Přidaná agenda pro nastavení limitů komisí. Změněn způsob hlídání limitů při zadávání nového požadavku- limit se bere z nové agendy.
closes #263 closes #264master
parent
cd6b8c01dc
commit
cbb81657c8
@ -0,0 +1,10 @@
|
|||||||
|
package info.bukova.isspst.dao;
|
||||||
|
|
||||||
|
import info.bukova.isspst.data.Limit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pepa Rokos
|
||||||
|
*/
|
||||||
|
public interface LimitDao extends BaseDao<Limit> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package info.bukova.isspst.dao.jpa;
|
||||||
|
|
||||||
|
import info.bukova.isspst.dao.LimitDao;
|
||||||
|
import info.bukova.isspst.data.Limit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pepa Rokos
|
||||||
|
*/
|
||||||
|
public class LimitDaoJPA extends BaseDaoJPA<Limit> implements LimitDao {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package info.bukova.isspst.data;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pepa Rokos
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "LIMITS")
|
||||||
|
public class Limit extends BaseData implements SeasonsAware {
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "WORKGROUP_ID")
|
||||||
|
private Workgroup workgroup;
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "SEASON_ID")
|
||||||
|
private Season season;
|
||||||
|
@Column(name = "REQ_LIMIT", precision = 15, scale = 4)
|
||||||
|
private BigDecimal limit;
|
||||||
|
|
||||||
|
public Workgroup getWorkgroup() {
|
||||||
|
return workgroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkgroup(Workgroup workgroup) {
|
||||||
|
this.workgroup = workgroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Season getSeason() {
|
||||||
|
return season;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeason(Season season) {
|
||||||
|
this.season = season;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getLimit() {
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLimit(BigDecimal limit) {
|
||||||
|
this.limit = limit;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package info.bukova.isspst.services.limits;
|
||||||
|
|
||||||
|
import info.bukova.isspst.services.IsspstException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pepa Rokos
|
||||||
|
*/
|
||||||
|
public class LimitException extends IsspstException {
|
||||||
|
|
||||||
|
public LimitException(String reason) {
|
||||||
|
setReason(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package info.bukova.isspst.services.limits;
|
||||||
|
|
||||||
|
import info.bukova.isspst.data.Limit;
|
||||||
|
import info.bukova.isspst.data.Season;
|
||||||
|
import info.bukova.isspst.data.Workgroup;
|
||||||
|
import info.bukova.isspst.services.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pepa Rokos
|
||||||
|
*/
|
||||||
|
public interface LimitService extends Service<Limit> {
|
||||||
|
List<Limit> getForSeason(Season season);
|
||||||
|
Limit getForWorkgroupAndSeason(Workgroup wg, Season season);
|
||||||
|
Limit getForWorkgroup(Workgroup wg);
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package info.bukova.isspst.services.limits;
|
||||||
|
|
||||||
|
import info.bukova.isspst.data.Limit;
|
||||||
|
import info.bukova.isspst.data.Season;
|
||||||
|
import info.bukova.isspst.data.Workgroup;
|
||||||
|
import info.bukova.isspst.services.AbstractOwnedService;
|
||||||
|
import info.bukova.isspst.services.settings.SeasonService;
|
||||||
|
import org.hibernate.Query;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pepa Rokos
|
||||||
|
*/
|
||||||
|
public class LimitServiceImpl extends AbstractOwnedService<Limit> implements LimitService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SeasonService seasonService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<Limit> getForSeason(Season season) {
|
||||||
|
Query q = dao.getQuery("from Limit where season = :season");
|
||||||
|
q.setParameter("season", season);
|
||||||
|
return q.list();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public Limit getForWorkgroupAndSeason(Workgroup wg, Season season) {
|
||||||
|
Query q = dao.getQuery("from Limit where workgroup = :wg and season = :season");
|
||||||
|
q.setParameter("wg", wg);
|
||||||
|
q.setParameter("season", season);
|
||||||
|
return (Limit) q.uniqueResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public Limit getForWorkgroup(Workgroup wg) {
|
||||||
|
return getForWorkgroupAndSeason(wg, seasonService.getActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
@PreAuthorize("hasPermission(this, 'PERM_ADD')")
|
||||||
|
public void add(Limit entity) {
|
||||||
|
if (getForWorkgroupAndSeason(entity.getWorkgroup(),entity.getSeason()) != null) {
|
||||||
|
throw new LimitException("LimitExists");
|
||||||
|
}
|
||||||
|
super.add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Limit createEntity() {
|
||||||
|
Limit limit = new Limit();
|
||||||
|
limit.setSeason(seasonService.getActive());
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package info.bukova.isspst.ui.limits;
|
||||||
|
|
||||||
|
import info.bukova.isspst.data.Limit;
|
||||||
|
import info.bukova.isspst.data.Workgroup;
|
||||||
|
import info.bukova.isspst.services.limits.LimitService;
|
||||||
|
import info.bukova.isspst.services.settings.SeasonService;
|
||||||
|
import info.bukova.isspst.services.workgroups.WorkgroupService;
|
||||||
|
import info.bukova.isspst.ui.FormViewModel;
|
||||||
|
import org.zkoss.bind.annotation.Init;
|
||||||
|
import org.zkoss.zk.ui.select.annotation.WireVariable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LimitsForm extends FormViewModel<Limit> {
|
||||||
|
|
||||||
|
List<Workgroup> workgroups;
|
||||||
|
@WireVariable
|
||||||
|
WorkgroupService workgroupService;
|
||||||
|
@WireVariable
|
||||||
|
LimitService limitService;
|
||||||
|
@WireVariable
|
||||||
|
SeasonService seasonService;
|
||||||
|
|
||||||
|
@Init(superclass = true)
|
||||||
|
public void init() {
|
||||||
|
workgroups = workgroupService.getWorkgroups();
|
||||||
|
if (getDataBean().getWorkgroup() == null) {
|
||||||
|
List<Limit> limits = limitService.getForSeason(seasonService.getActive());
|
||||||
|
|
||||||
|
for (Limit l : limits) {
|
||||||
|
workgroups.remove(l.getWorkgroup());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Workgroup> getWorkgroups() {
|
||||||
|
return workgroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNewRec() {
|
||||||
|
return newRec;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
package info.bukova.isspst.ui.limits;
|
||||||
|
|
||||||
|
import info.bukova.isspst.StringUtils;
|
||||||
|
import info.bukova.isspst.data.Limit;
|
||||||
|
import info.bukova.isspst.data.Workgroup;
|
||||||
|
import info.bukova.isspst.services.invoicing.InvoicingService;
|
||||||
|
import info.bukova.isspst.services.limits.LimitService;
|
||||||
|
import info.bukova.isspst.services.workgroups.WorkgroupService;
|
||||||
|
import info.bukova.isspst.ui.ListViewModel;
|
||||||
|
import org.jfree.chart.ChartFactory;
|
||||||
|
import org.jfree.chart.ChartUtilities;
|
||||||
|
import org.jfree.chart.JFreeChart;
|
||||||
|
import org.jfree.chart.plot.CategoryPlot;
|
||||||
|
import org.jfree.chart.plot.PlotOrientation;
|
||||||
|
import org.jfree.chart.renderer.category.BarRenderer3D;
|
||||||
|
import org.jfree.chart.title.LegendTitle;
|
||||||
|
import org.jfree.data.category.DefaultCategoryDataset;
|
||||||
|
import org.jfree.ui.RectangleEdge;
|
||||||
|
import org.zkoss.bind.annotation.GlobalCommand;
|
||||||
|
import org.zkoss.bind.annotation.Init;
|
||||||
|
import org.zkoss.bind.annotation.NotifyChange;
|
||||||
|
import org.zkoss.zk.ui.select.annotation.WireVariable;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.RenderedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LimitsList extends ListViewModel<Limit> {
|
||||||
|
|
||||||
|
@WireVariable
|
||||||
|
private LimitService limitService;
|
||||||
|
@WireVariable
|
||||||
|
private InvoicingService invoicingService;
|
||||||
|
@WireVariable
|
||||||
|
private WorkgroupService workgroupService;
|
||||||
|
private Map<Limit, BigDecimal> spent;
|
||||||
|
private RenderedImage chart;
|
||||||
|
|
||||||
|
@Init(superclass = true)
|
||||||
|
public void init() {
|
||||||
|
service = limitService;
|
||||||
|
dataClass = Limit.class;
|
||||||
|
formZul = "limitForm.zul";
|
||||||
|
//dataFilter = new MUnitFilter(getFilterTemplate());
|
||||||
|
genSpent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Limit, BigDecimal> getSpent() {
|
||||||
|
if (spent != null && !getDataList().isEmpty()) {
|
||||||
|
for (Limit l : spent.keySet()) {
|
||||||
|
if (!l.getSeason().equals(getDataList().get(0).getSeason())) {
|
||||||
|
spent = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spent != null && spent.keySet().size() < getDataList().size()) {
|
||||||
|
spent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spent != null) {
|
||||||
|
return spent;
|
||||||
|
}
|
||||||
|
|
||||||
|
spent = new HashMap<Limit, BigDecimal>();
|
||||||
|
for (Limit l : getDataList()) {
|
||||||
|
spent.put(l, invoicingService.totalInvoicedForWorkgroupAndSeason(l.getWorkgroup(), getSelSeason()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return spent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void genSpent() {
|
||||||
|
spent = new HashMap<Limit, BigDecimal>();
|
||||||
|
for (Limit l : getDataList()) {
|
||||||
|
spent.put(l, invoicingService.totalInvoicedForWorkgroupAndSeason(l.getWorkgroup(), getSelSeason()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void genCharts() {
|
||||||
|
DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
|
||||||
|
|
||||||
|
for (Workgroup wg : workgroupService.getWorkgroups()) {
|
||||||
|
Limit limit = null;
|
||||||
|
for (Limit l : getDataList()) {
|
||||||
|
if (l.getWorkgroup().equals(wg)) {
|
||||||
|
limit = l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSet.addValue(limit == null ? null : limit.getLimit(), StringUtils.localize("LimitsLimit"), wg.getFullName());
|
||||||
|
dataSet.addValue(invoicingService.totalInvoicedForWorkgroupAndSeason(wg, getSelSeason()), StringUtils.localize("LimitsSpent"), wg.getFullName());
|
||||||
|
}
|
||||||
|
|
||||||
|
JFreeChart jfChart = ChartFactory.createBarChart3D(StringUtils.localize("LimitsChartTitle"), StringUtils.localize("LimitsWorkgroup"),
|
||||||
|
StringUtils.localize("LimitsAmount"), dataSet, PlotOrientation.HORIZONTAL, true, false, false);
|
||||||
|
CategoryPlot plot = (CategoryPlot) jfChart.getPlot();
|
||||||
|
BarRenderer3D renderer = (BarRenderer3D) plot.getRenderer();
|
||||||
|
renderer.setSeriesPaint(0, Color.GREEN);
|
||||||
|
renderer.setSeriesPaint(1, Color.RED);
|
||||||
|
|
||||||
|
LegendTitle legend = jfChart.getLegend();
|
||||||
|
legend.setPosition(RectangleEdge.RIGHT);
|
||||||
|
|
||||||
|
try {
|
||||||
|
chart = ImageIO.read(new ByteArrayInputStream(ChartUtilities.encodeAsPNG(jfChart.createBufferedImage(1000, 400))));
|
||||||
|
} catch (IOException e) {
|
||||||
|
chart = null;
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RenderedImage getChart() {
|
||||||
|
genCharts();
|
||||||
|
return chart;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@GlobalCommand
|
||||||
|
@NotifyChange({ "dataList", "dataBean", "ableToDelete", "chart", "spent" })
|
||||||
|
public void refresh() {
|
||||||
|
genSpent();
|
||||||
|
super.refresh();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
<?page title="${labels.LimitsAgName}" contentType="text/html;charset=UTF-8"?>
|
||||||
|
|
||||||
|
<zk xmlns="http://www.zkoss.org/2005/zul"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">
|
||||||
|
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
|
||||||
|
|
||||||
|
<zscript>
|
||||||
|
String gridZul = "limits.zul";
|
||||||
|
</zscript>
|
||||||
|
|
||||||
|
<include src="../../app/template.zhtml"/>
|
||||||
|
|
||||||
|
</zk>
|
@ -0,0 +1,46 @@
|
|||||||
|
<?page title="${labels.TravelOrdersFormTitle}" contentType="text/html;charset=UTF-8"?>
|
||||||
|
|
||||||
|
<zk xmlns="http://www.zkoss.org/2005/zul"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">
|
||||||
|
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
|
||||||
|
<window
|
||||||
|
id="editWin"
|
||||||
|
closable="true"
|
||||||
|
border="normal"
|
||||||
|
width="600px"
|
||||||
|
position="center"
|
||||||
|
apply="org.zkoss.bind.BindComposer"
|
||||||
|
viewModel="@id('vm') @init('info.bukova.isspst.ui.limits.LimitsForm')">
|
||||||
|
<caption
|
||||||
|
image="/img/invoicing-032.png"
|
||||||
|
zclass="form-caption"
|
||||||
|
label="${labels.LimitsLimit}" />
|
||||||
|
<grid>
|
||||||
|
<columns>
|
||||||
|
<column/>
|
||||||
|
<column/>
|
||||||
|
</columns>
|
||||||
|
<rows>
|
||||||
|
<row>
|
||||||
|
<label value="${labels.LimitsWorkgroup}"/>
|
||||||
|
<combobox
|
||||||
|
disabled="@load(not vm.newRec)"
|
||||||
|
width="150px"
|
||||||
|
model="@load(vm.workgroups)"
|
||||||
|
readonly="true"
|
||||||
|
selectedItem="@bind(vm.dataBean.workgroup)">
|
||||||
|
<template name="model">
|
||||||
|
<comboitem label="@load(each)" />
|
||||||
|
</template>
|
||||||
|
</combobox>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<label value="${labels.LimitsLimit}"/>
|
||||||
|
<textbox value="@bind(vm.dataBean.limit) @converter(vm.standardBigDecimalConverter)"/>
|
||||||
|
</row>
|
||||||
|
</rows>
|
||||||
|
</grid>
|
||||||
|
<include src="/app/formButtons.zul"/>
|
||||||
|
</window>
|
||||||
|
</zk>
|
@ -0,0 +1,53 @@
|
|||||||
|
<?page title="${labels.LimitsAgName}" contentType="text/html;charset=UTF-8"?>
|
||||||
|
|
||||||
|
<zk xmlns="http://www.zkoss.org/2005/zul"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">
|
||||||
|
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
|
||||||
|
|
||||||
|
<window
|
||||||
|
vflex="1"
|
||||||
|
border="normal"
|
||||||
|
apply="org.zkoss.bind.BindComposer"
|
||||||
|
viewModel="@id('vm') @init('info.bukova.isspst.ui.limits.LimitsList')">
|
||||||
|
<caption
|
||||||
|
src="/img/invoicing-032.png"
|
||||||
|
zclass="form-caption"
|
||||||
|
label="${labels.LimitsAgName}" />
|
||||||
|
|
||||||
|
<include src="/app/toolbar.zul" />
|
||||||
|
<listbox
|
||||||
|
vflex="1"
|
||||||
|
model="@load(vm.dataList)"
|
||||||
|
selectedItem="@bind(vm.dataBean)">
|
||||||
|
<listhead menupopup="auto">
|
||||||
|
<listheader
|
||||||
|
label="${labels.LimitsWorkgroup}"
|
||||||
|
sort="czech(name)"
|
||||||
|
width="30%" />
|
||||||
|
<listheader
|
||||||
|
label="${labels.LimitsLimit}"
|
||||||
|
sort="czech(description)"
|
||||||
|
align="right"
|
||||||
|
width="70%" />
|
||||||
|
<listheader
|
||||||
|
label="${labels.LimitsSpent}"
|
||||||
|
sort="czech(description)"
|
||||||
|
align="right"
|
||||||
|
width="70%" />
|
||||||
|
</listhead>
|
||||||
|
<template name="model">
|
||||||
|
<listitem>
|
||||||
|
<listcell label="@load(each.workgroup)" />
|
||||||
|
<listcell label="@load(each.limit) @converter(vm.standardBigDecimalConverter)" />
|
||||||
|
<listcell label="@load(vm.spent[each]) @converter(vm.standardBigDecimalConverter)"/>
|
||||||
|
</listitem>
|
||||||
|
</template>
|
||||||
|
</listbox>
|
||||||
|
<div align="center" vflex="1">
|
||||||
|
<image height="100%" content="@load(vm.chart)"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</window>
|
||||||
|
|
||||||
|
</zk>
|
Loading…
Reference in New Issue