Vložena agenda se schválenými položkami požadavků

closes #139
multitenant
František Přibyl 10 years ago
parent 2a11599cb3
commit 9ff188caf0

@ -0,0 +1,24 @@
package info.bukova.isspst;
import java.math.BigDecimal;
public class BigDecimalUtils
{
public static boolean isEqualByDecimalForFilter(BigDecimal value, BigDecimal search)
{
if (search == null)
{
return true;
}
else if (value != null)
{
String valueS = value.toPlainString();
String searchS = search.toPlainString();
return valueS.startsWith(searchS);
// return (value.compareTo(search) == 0);
}
return false;
}
}

@ -7,6 +7,7 @@ import info.bukova.isspst.data.Role;
import info.bukova.isspst.reporting.Report;
import info.bukova.isspst.reporting.ReportMapping;
import info.bukova.isspst.services.addressbook.AdbService;
import info.bukova.isspst.services.approved.ApprovedService;
import info.bukova.isspst.services.buildings.BuildingService;
import info.bukova.isspst.services.munits.MUnitService;
import info.bukova.isspst.services.reqsubjects.MaterialService;
@ -67,6 +68,7 @@ public class Constants {
public final static String MOD_TRIPREQUIREMENTS = "TRIPREQUIREMENTS";
public final static String MOD_WORKFLOW = "WORKFLOW";
public final static String MOD_TRIPBILL = "TRIPBILL";
public final static String MOD_APPROVED = "APPROVED";
public final static Module MODULES[] = {
new Module(MOD_USERS, "Uživatelé", UserService.class),
new Module(MOD_PERMISSIONS, "Práva", RoleService.class),
@ -77,10 +79,10 @@ public class Constants {
new Module(MOD_SERVICES, "Služby", ServiceItemService.class),
new Module(MOD_WORKGROUPS, "Pracovní skupiny", WorkgroupService.class),
new Module(MOD_REQUIREMENTS, "Požadavky na nákupy", RequirementService.class),
new Module(MOD_TRIPREQUIREMENTS, "Pžadavky na služební cesty", TripRequirementService.class),
new Module(MOD_TRIPREQUIREMENTS, "Požadavky na služební cesty", TripRequirementService.class),
new Module(MOD_WORKFLOW, "Procesy schválení", RequirementTypeService.class),
new Module(MOD_TRIPBILL, "Cestovní příkazy", TripBillService.class)
};
new Module(MOD_TRIPBILL, "Cestovní příkazy", TripBillService.class),
new Module(MOD_APPROVED, "Schválené položky příkazů", ApprovedService.class) };
public final static String PERM_APPROVE = "PERM_APPROVE";
public final static String PERM_SHOW_WORKGROUP_REQ = "PERM_SHOW_WORKGROUP_REQ";

@ -1,34 +1,201 @@
package info.bukova.isspst.data;
public class JoinedItem implements FilterableRequirement {
import java.math.BigDecimal;
import java.util.Date;
private RequirementItem item;
private Workgroup workgroup;
private Workgroup centre;
private User ownedBy;
/**
* Položka schválených požadavků na materiál nebo službu
*/
public class JoinedItem implements DataModel, FilterableRequirement
{
// Konstruktoři
public JoinedItem(RequirementItem item, Workgroup workgroup,
Workgroup centre, User owner) {
super();
protected void CopyItem(RequirementItem item)
{
this.item = item;
this.id = item.getId();
this.reqSubject = item.getReqSubject();
this.requirement = item.getRequirement();
this.code = item.getCode();
this.name = item.getName();
this.textItem = item.getTextItem();
this.quantity = item.getQuantity();
this.munit = item.getMunit();
this.unitPrice = item.getUnitPrice();
this.total = item.getTotal();
this.description = item.getDescription();
}
// Default konstruktor kvůli volání newInstance()
public JoinedItem()
{
super();
}
public JoinedItem(RequirementItem item)
{
super();
this.CopyItem(item);
}
public JoinedItem(RequirementItem item, Workgroup workgroup, Workgroup centre, User owner)
{
super();
this.CopyItem(item);
this.workgroup = workgroup;
this.centre = centre;
this.ownedBy = owner;
}
public JoinedItem(RequirementItem item) {
super();
this.item = item;
}
// Kdyby se přistupovalo k datům přes další strukturu, byl by to problém pro
// tisk, řazení a Bůh ví co ještě
private RequirementItem item;
public RequirementItem getItem() {
public RequirementItem getItem()
{
return item;
}
public void setItem(RequirementItem item) {
public void setItem(RequirementItem item)
{
this.item = item;
}
// Členové RequirementItem
private int id;
private RequirementSubject reqSubject;
private Requirement requirement;
private String code;
private String name;
private String textItem;
private BigDecimal quantity;
private MUnitEmb munit;
private BigDecimal unitPrice;
private BigDecimal total;
private String description;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public RequirementSubject getReqSubject()
{
return reqSubject;
}
public void setReqSubject(RequirementSubject reqSubject)
{
this.reqSubject = reqSubject;
}
public Requirement getRequirement()
{
return requirement;
}
public void setRequirement(Requirement requirement)
{
this.requirement = requirement;
}
public String getCode()
{
return code;
}
public void setCode(String code)
{
this.code = code;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getTextItem()
{
return textItem;
}
public void setTextItem(String textItem)
{
this.textItem = textItem;
}
public BigDecimal getQuantity()
{
return quantity;
}
public void setQuantity(BigDecimal quantity)
{
this.quantity = quantity;
}
public MUnitEmb getMunit()
{
return munit;
}
public void setMunit(MUnitEmb munit)
{
this.munit = munit;
}
public BigDecimal getUnitPrice()
{
return unitPrice;
}
public void setUnitPrice(BigDecimal unitPrice)
{
this.unitPrice = unitPrice;
}
public BigDecimal getTotal()
{
return total;
}
public void setTotal(BigDecimal total)
{
this.total = total;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
// Hodnoty z Requirement
private Workgroup workgroup;
private Workgroup centre;
private User ownedBy;
public Workgroup getWorkgroup() {
return workgroup;
}
@ -53,4 +220,61 @@ public class JoinedItem implements FilterableRequirement {
this.ownedBy = owner;
}
@Override
public boolean equals(Object obj)
{
if (obj != null)
{
if (obj instanceof JoinedItem)
{
JoinedItem item = (JoinedItem) obj;
return (this.getId() == item.getId());
}
}
return false;
}
// Zbytenčné metody nutné kvůli přetížení z předka DataModel - chybka v
// návrhu no...
@Override
public void setCreated(Date created)
{
// TODO Auto-generated method stub
}
@Override
public Date getCreated()
{
// TODO Auto-generated method stub
return null;
}
@Override
public void setModified(Date modified)
{
// TODO Auto-generated method stub
}
@Override
public Date getModified()
{
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isValid()
{
// TODO Auto-generated method stub
return false;
}
@Override
public void setValid(boolean valid)
{
// TODO Auto-generated method stub
}
}

@ -58,6 +58,20 @@ public class MUnitEmb
this.description = StringUtils.encodeSpecialChars(description);
}
public static boolean isEqualMUnitEmbForFilter(MUnitEmb value, MUnitEmb search)
{
if (search == null)
{
return true;
}
else if (value != null)
{
return StringUtils.isEqualForFilter(value.getName(), search.getName());
}
return false;
}
public boolean eqWith(MUnit munit)
{
if (munit == null)

@ -0,0 +1,69 @@
package info.bukova.isspst.filters;
import info.bukova.isspst.BigDecimalUtils;
import info.bukova.isspst.StringUtils;
import info.bukova.isspst.data.JoinedItem;
import info.bukova.isspst.data.MUnitEmb;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public class JoinedItemFilter implements Filter<JoinedItem>
{
private JoinedItem condition;
public JoinedItemFilter(JoinedItem cond)
{
this.condition = cond;
}
private static class JoinedItemMatcher extends TypeSafeMatcher<JoinedItem>
{
private JoinedItem condition;
public JoinedItemMatcher(JoinedItem cond)
{
this.condition = cond;
}
@Override
public void describeTo(Description desc)
{
desc.appendText("JoinedItem matches");
}
@Override
public boolean matchesSafely(JoinedItem item)
{
boolean foundCode = StringUtils.isEqualForFilter(item.getCode(), condition.getCode());
boolean foundName = StringUtils.isEqualForFilter(item.getName(), condition.getName());
boolean foundTextItem = StringUtils.isEqualForFilter(item.getTextItem(), condition.getTextItem());
boolean foundQuantity = BigDecimalUtils.isEqualByDecimalForFilter(item.getQuantity(), condition.getQuantity());
boolean foundUnitPrice = BigDecimalUtils.isEqualByDecimalForFilter(item.getUnitPrice(), condition.getUnitPrice());
boolean foundMUnit = MUnitEmb.isEqualMUnitEmbForFilter(item.getMunit(), condition.getMunit());
boolean foundTotal = BigDecimalUtils.isEqualByDecimalForFilter(item.getTotal(), condition.getTotal());
boolean foundDescription = StringUtils.isEqualForFilter(item.getDescription(), condition.getDescription());
return (foundCode && foundName && foundTextItem && foundDescription && foundQuantity && foundUnitPrice && foundMUnit && foundTotal && foundDescription);
}
@Factory
public static Matcher<JoinedItem> matchBuilding(JoinedItem item)
{
return new JoinedItemMatcher(item);
}
}
@Override
public JoinedItemMatcher matcher()
{
return new JoinedItemMatcher(condition);
}
@Override
public String queryString()
{
return "";
}
}

@ -0,0 +1,8 @@
package info.bukova.isspst.services.approved;
import info.bukova.isspst.data.JoinedItem;
import info.bukova.isspst.services.Service;
public interface ApprovedService extends Service<JoinedItem>
{
}

@ -0,0 +1,63 @@
package info.bukova.isspst.services.approved;
import info.bukova.isspst.dao.BaseDao;
import info.bukova.isspst.data.JoinedItem;
import info.bukova.isspst.data.RequirementItem;
import info.bukova.isspst.data.RequirementState;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.AbstractService;
import info.bukova.isspst.services.users.UserService;
import info.bukova.isspst.services.workgroups.WorkgroupService;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
public class ApprovedServiceImpl extends AbstractService<JoinedItem> implements ApprovedService
{
@Autowired
WorkgroupService workgroupService;
@Autowired
UserService userService;
// V bázi je BaseDao<T>, což nelze použít, protože třída JoinedItem nemá
// ekvivalent v databázi
// Bylo by dobré tuto funčnost vložit do báze...
BaseDao<?> dao4Query;
public BaseDao<?> getDao4Query()
{
return dao4Query;
}
public void setDao4Query(BaseDao<?> dao4Query)
{
this.dao4Query = dao4Query;
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_SHOW_CENTRE_REQ')")
@PostFilter("hasPermission(filterObject, 'PERM_SHOW_CENTRE_REQ')")
public List<JoinedItem> getAll()
{
List<Workgroup> wgList = workgroupService.getUserCentres(userService.getCurrent());
Query q = dao4Query.getQuery("select item from RequirementItem item left join item.requirement rq join rq.centre c where rq.kind is not null and rq.state = :state and c in (:wgList)");
q.setParameterList("wgList", wgList);
q.setParameter("state", RequirementState.APPROVED);
List<JoinedItem> items = new ArrayList<JoinedItem>();
for (RequirementItem it : (List<RequirementItem>)q.list()) {
items.add(new JoinedItem(it, it.getRequirement().getWorkgroup(), it.getRequirement().getCentre(), it.getRequirement().getOwnedBy()));
}
return items;
}
}

@ -1,12 +1,8 @@
package info.bukova.isspst.services.requirement;
import java.util.List;
import info.bukova.isspst.data.JoinedItem;
import info.bukova.isspst.data.Requirement;
public interface RequirementService extends RequirementBaseService<Requirement>
{
public void loadGroups(Requirement req);
public List<JoinedItem> getItemsForOrder();
}

@ -1,24 +1,18 @@
package info.bukova.isspst.services.requirement;
import info.bukova.isspst.Constants;
import info.bukova.isspst.data.JoinedItem;
import info.bukova.isspst.data.Requirement;
import info.bukova.isspst.data.RequirementItem;
import info.bukova.isspst.data.RequirementState;
import info.bukova.isspst.data.RequirementSubject;
import info.bukova.isspst.data.User;
import info.bukova.isspst.data.Workflow;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.LazyLoader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
public class RequirementServiceImpl extends
@ -56,25 +50,6 @@ public class RequirementServiceImpl extends
return false;
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_SHOW_CENTRE_REQ')")
@PostFilter("hasPermission(filterObject, 'PERM_SHOW_CENTRE_REQ')")
public List<JoinedItem> getItemsForOrder() {
List<Workgroup> wgList = workgroupService.getUserCentres(getLoggedInUser());
Query q = dao.getQuery("select item from RequirementItem item left join item.requirement rq join rq.centre c where rq.kind is not null and rq.state = :state and c in (:wgList)");
q.setParameterList("wgList", wgList);
q.setParameter("state", RequirementState.APPROVED);
List<JoinedItem> items = new ArrayList<JoinedItem>();
for (RequirementItem it : (List<RequirementItem>)q.list()) {
items.add(new JoinedItem(it, it.getRequirement().getWorkgroup(), it.getRequirement().getCentre(), it.getRequirement().getOwnedBy()));
}
return items;
}
/*
* Lazy load pro načtení seznamu skupin materiálu nebo služeb do comba.
* Ošetřuje se zde případné neexistující vazby na ID smazaných skupin

@ -0,0 +1,40 @@
package info.bukova.isspst.ui.main.approved;
import info.bukova.isspst.data.JoinedItem;
import info.bukova.isspst.filters.JoinedItemFilter;
import info.bukova.isspst.services.approved.ApprovedService;
import info.bukova.isspst.ui.BigDecimalConverter;
import info.bukova.isspst.ui.ListViewModel;
import java.util.List;
import org.zkoss.bind.annotation.Init;
import org.zkoss.zk.ui.select.annotation.WireVariable;
public class ApprovedList extends ListViewModel<JoinedItem>
{
@WireVariable
protected ApprovedService approvedService;
private BigDecimalConverter bigDecimalConverter;
@Init
public void initApprovedList()
{
service = approvedService;
dataClass = JoinedItem.class;
// formZul = "form.zul";
dataFilter = new JoinedItemFilter(getFilterTemplate());
bigDecimalConverter = new BigDecimalConverter();
}
public BigDecimalConverter getBigDecimalConverter()
{
return bigDecimalConverter;
}
public List<JoinedItem> getItems()
{
return approvedService.getAll();
}
}

@ -265,6 +265,7 @@ MaterialRequirement=Požadavek na materiál
MaterialRequirements=Požadavky na materiál
ServiceRequirement=Požadavek na servis
ServiceRequirements=Požadavky na servis
ApprovedRequirementItems=Schválené položky požadavků
CurrentRequirements=Aktuální požadavky
ApprovedOrders=Schválené objednávky

@ -302,6 +302,10 @@
<property name="xmlContext" ref="xmlCtxAres" />
</bean>
<bean id="approvedService" class="info.bukova.isspst.services.approved.ApprovedServiceImpl">
<property name="dao4Query" ref="permissionDao"/>
</bean>
<bean id="permissionService" class="info.bukova.isspst.services.users.PermissionServiceImpl">
<property name="dao" ref="permissionDao"/>
</bean>

@ -22,6 +22,11 @@
label="${labels.ServiceRequirements}"
href="/main/orders/services/" />
<menuseparator />
<menuitem
image="/img/hammer-016.png"
label="${labels.ApprovedRequirementItems}"
href="/main/orders/approved/" />
<menuseparator />
<menuitem
label="${labels.ApprovedOrders}"
href="" />

@ -19,6 +19,12 @@
text-align: right;
}
.find-grid-img-left {
display: table-cell;
width: 20px;
text-align: left;
}
.find-grid-divtextbox {
display: table-cell;
}
@ -27,6 +33,11 @@
width: 100%;
}
.find-grid-textbox-right {
width: 100%;
text-align: right;
}
.grid-textbox-max {
width: 100%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -0,0 +1,198 @@
<?page title="${labels.ApprovedRequirementItems}" contentType="text/html;charset=UTF-8"?>
<zk>
<?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.main.approved.ApprovedList')">
<caption
image="/img/hammer-032.png"
zclass="form-caption"
label="${labels.ApprovedRequirementItems}" />
<toolbar>
<toolbarbutton
image="/img/funnel.png"
tooltiptext="${labels.ToolbarRecFilter}"
id="btnFilter"
onClick="@command('filter')" />
<toolbarbutton
image="/img/print.png"
tooltiptext="${labels.ToolbarPrint}"
id="btnPrint"
onClick="@command('onPrint')" />
</toolbar>
<listbox
multiple="true"
checkmark="true"
vflex="1"
model="@load(vm.dataList)">
<listhead menupopup="auto">
<listheader width="27" />
<listheader
hflex="7"
sort="czech(code)"
label="${labels.RequirementItemCode}" />
<listheader
hflex="15"
sort="czech(name)"
label="${labels.RequirementItemName}" />
<listheader
hflex="20"
sort="czech(textItem)"
label="${labels.RequirementItemText}" />
<listheader
hflex="5"
sort="auto(quantity)"
align="right"
label="${labels.RequirementItemQuantity}" />
<listheader
hflex="5"
sort="auto(munit.name)"
label="${labels.RequirementItemMUnit}" />
<listheader
hflex="7"
align="right"
sort="auto(unitPrice)"
label="${labels.RequirementItemUnitPrice}" />
<listheader
hflex="7"
align="right"
sort="auto(total)"
label="${labels.RequirementItemTotal}" />
<listheader
hflex="20"
sort="czech(description)"
label="${labels.RequirementItemDescription}" />
</listhead>
<auxhead visible="@load(vm.filter)">
<auxheader />
<auxheader>
<div sclass="find-grid-cell">
<div sclass="find-grid-divtextbox">
<textbox
value="@bind(vm.filterTemplate.code)"
instant="true"
onChange="@command('doFilter')"
sclass="find-grid-textbox" />
</div>
<div sclass="find-grid-img">
<image src="/img/funnel.png" />
</div>
</div>
</auxheader>
<auxheader>
<div sclass="find-grid-cell">
<div sclass="find-grid-divtextbox">
<textbox
value="@bind(vm.filterTemplate.name)"
instant="true"
onChange="@command('doFilter')"
sclass="find-grid-textbox" />
</div>
<div sclass="find-grid-img">
<image src="/img/funnel.png" />
</div>
</div>
</auxheader>
<auxheader>
<div sclass="find-grid-cell">
<div sclass="find-grid-divtextbox">
<textbox
value="@bind(vm.filterTemplate.textItem)"
instant="true"
onChange="@command('doFilter')"
sclass="find-grid-textbox" />
</div>
<div sclass="find-grid-img">
<image src="/img/funnel.png" />
</div>
</div>
</auxheader>
<auxheader>
<!-- div sclass="find-grid-cell">
<div sclass="find-grid-img-left">
<image src="/img/funnel.png" />
</div>
<div sclass="find-grid-divtextbox">
<textbox
value="@bind(vm.filterTemplate.quantity)"
instant="true"
onChange="@command('doFilter')"
sclass="find-grid-textbox-right" />
</div>
</div-->
</auxheader>
<auxheader>
<!-- div sclass="find-grid-cell">
<div sclass="find-grid-divtextbox">
<textbox
value="@bind(vm.filterTemplate.munit.name)"
instant="true"
onChange="@command('doFilter')"
sclass="find-grid-textbox" />
</div>
<div sclass="find-grid-img">
<image src="/img/funnel.png" />
</div>
</div-->
</auxheader>
<auxheader>
<!-- div sclass="find-grid-cell">
<div sclass="find-grid-img-left">
<image src="/img/funnel.png" />
</div>
<div sclass="find-grid-divtextbox">
<textbox
value="@bind(vm.filterTemplate.unitPrice)"
instant="true"
onChange="@command('doFilter')"
sclass="find-grid-textbox-right" />
</div>
</div-->
</auxheader>
<auxheader>
<!-- div sclass="find-grid-cell">
<div sclass="find-grid-img-left">
<image src="/img/funnel.png" />
</div>
<div sclass="find-grid-divtextbox">
<textbox
value="@bind(vm.filterTemplate.total)"
instant="true"
onChange="@command('doFilter')"
sclass="find-grid-textbox-right" />
</div>
</div-->
</auxheader>
<auxheader>
<div sclass="find-grid-cell">
<div sclass="find-grid-divtextbox">
<textbox
value="@bind(vm.filterTemplate.description)"
instant="true"
onChange="@command('doFilter')"
sclass="find-grid-textbox" />
</div>
<div sclass="find-grid-img">
<image src="/img/funnel.png" />
</div>
</div>
</auxheader>
</auxhead>
<template name="model">
<listitem>
<listcell />
<listcell label="@load(each.code)" />
<listcell label="@load(each.name)" />
<listcell label="@load(each.textItem)" />
<listcell label="@load(each.quantity) @converter(vm.bigDecimalConverter)" />
<listcell label="@load(each.munit.name)" />
<listcell label="@load(each.unitPrice) @converter(vm.bigDecimalConverter)" />
<listcell label="@load(each.total) @converter(vm.bigDecimalConverter)" />
<listcell label="@load(each.description)" />
</listitem>
</template>
</listbox>
</window>
</zk>

@ -0,0 +1,10 @@
<?page title="${labels.ApprovedRequirementItems}" contentType="text/html;charset=UTF-8"?>
<zk>
<zscript>
String gridZul = "grid.zul";
</zscript>
<include src="/app/template.zhtml"/>
</zk>
Loading…
Cancel
Save