diff --git a/src/main/java/info/bukova/isspst/data/TripBill.java b/src/main/java/info/bukova/isspst/data/TripBill.java index a8bdee81..7029654f 100644 --- a/src/main/java/info/bukova/isspst/data/TripBill.java +++ b/src/main/java/info/bukova/isspst/data/TripBill.java @@ -1,6 +1,7 @@ package info.bukova.isspst.data; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -43,6 +44,10 @@ public class TripBill extends BaseData { private BigDecimal downPayment; @Column(name = "TOTAL", precision = 15, scale = 4) private BigDecimal total; + + public TripBill() { + billItems = new ArrayList(); + } public TripRequirement getRequirement() { return requirement; diff --git a/src/main/java/info/bukova/isspst/data/TripBillItem.java b/src/main/java/info/bukova/isspst/data/TripBillItem.java index 4f1ff517..153e54ac 100644 --- a/src/main/java/info/bukova/isspst/data/TripBillItem.java +++ b/src/main/java/info/bukova/isspst/data/TripBillItem.java @@ -3,6 +3,8 @@ package info.bukova.isspst.data; import java.math.BigDecimal; import java.util.Date; +import javax.persistence.AttributeOverride; +import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; @@ -19,11 +21,21 @@ public class TripBillItem extends BaseData { @Column(name = "BACK") private String back; @Column(name = "DEPARTURE") - private Date departure; + private Date toDeparture; @Column(name = "ARRIVAL") - private Date arrival; + private Date toArrival; + @Column(name = "BACK_DEPARTURE") + private Date backDeparture; + @Column(name = "BACK_ARRIVAL") + private Date backArrival; @Embedded - private Vehicle vehicle; + private Vehicle toVehicle; + @Embedded + @AttributeOverrides({ + @AttributeOverride(name = "code", column = @Column(name = "BACK_VEHICLE_CODE")), + @AttributeOverride(name = "description", column = @Column(name = "BACK_VEHICLE_DESCRIPTION")) + }) + private Vehicle backVehicle; @Column(name = "BEGIN_WORK") private Date beginWork; @Column(name = "END_WORK") @@ -34,6 +46,10 @@ public class TripBillItem extends BaseData { private BigDecimal distance; @Column(name = "FUEL_CONSUMPTION", precision = 15, scale = 4) private BigDecimal fuelConsumption; + @Column(name = "DISTANCE_AMOUNT", precision = 15, scale = 4) + private BigDecimal distanceAmount; + @Column(name = "FUEL_AMOUNT", precision = 15, scale = 4) + private BigDecimal fuelAmount; @Column(name = "CAREFARE", precision = 15, scale = 4) private BigDecimal carefare; @Column(name = "HOUSING", precision = 15, scale = 4) @@ -71,30 +87,6 @@ public class TripBillItem extends BaseData { this.back = back; } - public Date getDeparture() { - return departure; - } - - public void setDeparture(Date departure) { - this.departure = departure; - } - - public Date getArrival() { - return arrival; - } - - public void setArrival(Date arrival) { - this.arrival = arrival; - } - - public Vehicle getVehicle() { - return vehicle; - } - - public void setVehicle(Vehicle vehicle) { - this.vehicle = vehicle; - } - public Date getBeginWork() { return beginWork; } @@ -183,4 +175,68 @@ public class TripBillItem extends BaseData { this.adjustedTotal = adjustedTotal; } + public Date getToDeparture() { + return toDeparture; + } + + public void setToDeparture(Date toDeparture) { + this.toDeparture = toDeparture; + } + + public Date getToArrival() { + return toArrival; + } + + public void setToArrival(Date toArrival) { + this.toArrival = toArrival; + } + + public Date getBackDeparture() { + return backDeparture; + } + + public void setBackDeparture(Date backDeparture) { + this.backDeparture = backDeparture; + } + + public Date getBackArrival() { + return backArrival; + } + + public void setBackArrival(Date backArrival) { + this.backArrival = backArrival; + } + + public Vehicle getToVehicle() { + return toVehicle; + } + + public void setToVehicle(Vehicle toVhicle) { + this.toVehicle = toVhicle; + } + + public Vehicle getBackVehicle() { + return backVehicle; + } + + public void setBackVehicle(Vehicle backVehicle) { + this.backVehicle = backVehicle; + } + + public BigDecimal getDistanceAmount() { + return distanceAmount; + } + + public void setDistanceAmount(BigDecimal distanceAmount) { + this.distanceAmount = distanceAmount; + } + + public BigDecimal getFuelAmount() { + return fuelAmount; + } + + public void setFuelAmount(BigDecimal fuelAmount) { + this.fuelAmount = fuelAmount; + } + } diff --git a/src/main/java/info/bukova/isspst/services/requirement/TripRequirementServiceImpl.java b/src/main/java/info/bukova/isspst/services/requirement/TripRequirementServiceImpl.java index 2f001ca3..b274a0f7 100644 --- a/src/main/java/info/bukova/isspst/services/requirement/TripRequirementServiceImpl.java +++ b/src/main/java/info/bukova/isspst/services/requirement/TripRequirementServiceImpl.java @@ -2,8 +2,10 @@ package info.bukova.isspst.services.requirement; import info.bukova.isspst.Constants; import info.bukova.isspst.data.RequirementState; +import info.bukova.isspst.data.TripBill; import info.bukova.isspst.data.TripRequirement; import info.bukova.isspst.services.LazyLoader; +import info.bukova.isspst.services.tripbill.TripBillService; import info.bukova.isspst.services.workgroups.WorkgroupService; import java.util.Date; @@ -20,6 +22,8 @@ public class TripRequirementServiceImpl extends RequirementBaseServiceImpl { + + public TripBill createTripBill(TripRequirement requirement); + public void loadItems(TripBill bill); + public void calculate(TripBill bill); + public List getMy(); } diff --git a/src/main/java/info/bukova/isspst/services/tripbill/TripBillServiceImpl.java b/src/main/java/info/bukova/isspst/services/tripbill/TripBillServiceImpl.java index d5d0192f..0bfa6c59 100644 --- a/src/main/java/info/bukova/isspst/services/tripbill/TripBillServiceImpl.java +++ b/src/main/java/info/bukova/isspst/services/tripbill/TripBillServiceImpl.java @@ -1,9 +1,177 @@ package info.bukova.isspst.services.tripbill; +import info.bukova.isspst.data.SettingsData; import info.bukova.isspst.data.TripBill; +import info.bukova.isspst.data.TripBillItem; +import info.bukova.isspst.data.TripRequirement; import info.bukova.isspst.services.AbstractOwnedService; +import info.bukova.isspst.services.LazyLoader; +import info.bukova.isspst.services.settings.GlobalSettingsService; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.hibernate.LazyInitializationException; +import org.hibernate.Query; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; public class TripBillServiceImpl extends AbstractOwnedService implements TripBillService { + @Autowired + private GlobalSettingsService globalSettings; + + @Override + public TripBill createTripBill(TripRequirement requirement) { + TripBill bill = new TripBill(); + + bill.setRequirement(requirement); + long daysCount = TimeUnit.DAYS.convert(requirement.getEndDate().getTime() - requirement.getTripDate().getTime(), TimeUnit.MILLISECONDS) + 1; + + for (int i = 0 ; i < daysCount ; i++) { + TripBillItem item = new TripBillItem(); + if (i == 0) { + item.setTo(requirement.getFrom() + " - " + requirement.getTo()); + item.setToVehicle(requirement.getVehicle()); + } + if (i == daysCount - 1) { + item.setBack(requirement.getTo() + " - " + requirement.getFrom()); + item.setBackVehicle(requirement.getVehicle()); + } + + Calendar calTripDate = Calendar.getInstance(); + calTripDate.setTime(requirement.getTripDate()); + calTripDate.add(Calendar.DATE, i); + item.setDate(calTripDate.getTime()); + + bill.getBillItems().add(item); + } + + this.calculate(bill); + + return bill; + } + + @Override + @Transactional + @LazyLoader("form") + public void loadItems(TripBill entity) { + try { + if (entity.getBillItems() == null) { + throw new LazyInitializationException(""); + } + + entity.getBillItems().size(); + } catch (LazyInitializationException ex) { + TripBill e = dao.getById(entity.getId()); + e.getBillItems().size(); + entity.setBillItems(e.getBillItems()); + } + } + + @Override + public void calculate(TripBill bill) { + bill.setTotal(BigDecimal.ZERO); + + for (TripBillItem item : bill.getBillItems()) { + if (!bill.isFreeMeals()) { + item.setFreeMealsCount(0); + } + + calculateItem(item); + bill.setTotal(bill.getTotal().add(item.getTotal())); + } + } + + private void calculateItem(TripBillItem item) { + Calendar cal = Calendar.getInstance(); + Date to = item.getToArrival(); + + if (to == null) { + to = new Date(); + cal.setTime(to); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + } else { + cal.setTime(to); + } + + cal.set(Calendar.DAY_OF_MONTH, 1); + cal.set(Calendar.MONTH, 1); + cal.set(Calendar.YEAR, 2000); + + to.setTime(cal.getTimeInMillis()); + + Date back = item.getBackDeparture(); + + if (back == null) { + back = new Date(to.getTime()); + } + + cal.setTime(back); + + if (back.equals(to)) { + cal.set(Calendar.HOUR, 23); + cal.set(Calendar.MINUTE, 59); + } + + cal.set(Calendar.DAY_OF_MONTH, 1); + cal.set(Calendar.MONTH, 1); + cal.set(Calendar.YEAR, 2000); + back.setTime(cal.getTimeInMillis()); + + if (to.getTime() > back.getTime()) { + item.setTotal(BigDecimal.ZERO); + return; + } + + SettingsData settings = globalSettings.getSettings(); + long hours = TimeUnit.HOURS.convert(back.getTime() - to.getTime(), TimeUnit.MILLISECONDS); + int refundHour = 0; + List refundHours = new ArrayList(settings.getRefunds().keySet()); + Collections.sort(refundHours); + + for (int key : refundHours) { + if (refundHour <= hours && key > hours) { + break; + } + + refundHour = key; + } + + item.setMeals(settings.getRefunds().get(refundHour)[item.getFreeMealsCount()]); + + BigDecimal carefare = item.getCarefare() == null ? BigDecimal.ZERO : item.getCarefare(); + BigDecimal housing = item.getHousing() == null ? BigDecimal.ZERO : item.getHousing(); + BigDecimal otherExp = item.getOtherExpenses() == null ? BigDecimal.ZERO : item.getOtherExpenses(); + BigDecimal distanceAmount = item.getDistanceAmount() == null ? BigDecimal.ZERO : item.getDistanceAmount(); + BigDecimal fuelAmount = item.getFuelAmount() == null ? BigDecimal.ZERO : item.getFuelAmount(); + + item.setTotal(carefare.add(housing).add(item.getMeals()).add(otherExp).add(distanceAmount).add(fuelAmount)); + } + + @SuppressWarnings("unchecked") + @Override + @Transactional + @PreAuthorize("hasPermission(this, 'PERM_READ')") + public List getMy() { + Query q = dao.getQuery("from TripBill where ownedBy = :owner"); + q.setParameter("owner", getLoggedInUser()); + return q.list(); + } + + @Override + @Transactional + @PreAuthorize("hasPermission(this, 'PERM_SHOW_ALL_BILL')") + public List getAll() { + return this.execQuery("from TripBill as tb join fetch tb.ownedBy"); + } + } diff --git a/src/main/java/info/bukova/isspst/services/workgroups/WorkgroupServiceImpl.java b/src/main/java/info/bukova/isspst/services/workgroups/WorkgroupServiceImpl.java index 7687ed94..faf8c8ee 100644 --- a/src/main/java/info/bukova/isspst/services/workgroups/WorkgroupServiceImpl.java +++ b/src/main/java/info/bukova/isspst/services/workgroups/WorkgroupServiceImpl.java @@ -70,6 +70,8 @@ public class WorkgroupServiceImpl extends AbstractOwnedService implem @Override @Transactional public boolean isMember(Workgroup workgroup, Member member) { + loadParents(member); + if (member.equals(getLoggedInUser()) && sessionData.getCurrentUser() != null) { return member.getParents().contains(workgroup); } diff --git a/src/main/java/info/bukova/isspst/ui/tripbill/TripBillForm.java b/src/main/java/info/bukova/isspst/ui/tripbill/TripBillForm.java index 4f31634e..98fbcc7e 100644 --- a/src/main/java/info/bukova/isspst/ui/tripbill/TripBillForm.java +++ b/src/main/java/info/bukova/isspst/ui/tripbill/TripBillForm.java @@ -1,14 +1,48 @@ package info.bukova.isspst.ui.tripbill; +import java.util.ArrayList; +import java.util.List; + import info.bukova.isspst.data.TripBill; +import info.bukova.isspst.data.Vehicle; +import info.bukova.isspst.services.settings.GlobalSettingsService; +import info.bukova.isspst.services.tripbill.TripBillService; +import info.bukova.isspst.ui.BigDecimalConverter; import info.bukova.isspst.ui.FormViewModel; +import org.zkoss.bind.annotation.Command; import org.zkoss.bind.annotation.Init; +import org.zkoss.bind.annotation.NotifyChange; +import org.zkoss.zk.ui.select.annotation.WireVariable; public class TripBillForm extends FormViewModel { + + private BigDecimalConverter bigDecimalConverter; + @WireVariable + private TripBillService tripBillService; + private List vehicles; + @WireVariable + private GlobalSettingsService settingsService; @Init(superclass = true) public void init() { + bigDecimalConverter = new BigDecimalConverter(); + vehicles = new ArrayList(); + vehicles.add(null); + vehicles.addAll(settingsService.getSettings().getVehicles()); + } + + public BigDecimalConverter getBigDecimalConverter() { + return bigDecimalConverter; + } + + @Command + @NotifyChange("dataBean") + public void calculate() { + tripBillService.calculate(getDataBean()); + } + public List getVehicles() { + return vehicles; } } diff --git a/src/main/java/info/bukova/isspst/ui/tripbill/TripBillList.java b/src/main/java/info/bukova/isspst/ui/tripbill/TripBillList.java index c7c3c477..46906468 100644 --- a/src/main/java/info/bukova/isspst/ui/tripbill/TripBillList.java +++ b/src/main/java/info/bukova/isspst/ui/tripbill/TripBillList.java @@ -1,7 +1,10 @@ package info.bukova.isspst.ui.tripbill; +import java.util.List; + import info.bukova.isspst.data.TripBill; import info.bukova.isspst.services.tripbill.TripBillService; +import info.bukova.isspst.ui.BigDecimalConverter; import info.bukova.isspst.ui.ListViewModel; import org.zkoss.bind.annotation.Init; @@ -11,6 +14,7 @@ public class TripBillList extends ListViewModel { @WireVariable private TripBillService tripBillService; + private BigDecimalConverter converter; @Init public void init() { @@ -18,5 +22,15 @@ public class TripBillList extends ListViewModel { dataClass = TripBill.class; formZul = "tripBillForm.zul"; //dataFilter = new MUnitFilter(getFilterTemplate()); + converter = new BigDecimalConverter(); + } + + @Override + protected List getListFromService() { + return tripBillService.getMy(); + } + + public BigDecimalConverter getConverter() { + return converter; } } diff --git a/src/main/webapp/WEB-INF/locales/zk-label.properties b/src/main/webapp/WEB-INF/locales/zk-label.properties index f2d83d55..68da1854 100644 --- a/src/main/webapp/WEB-INF/locales/zk-label.properties +++ b/src/main/webapp/WEB-INF/locales/zk-label.properties @@ -168,6 +168,42 @@ TravelOrdersGridFrom=Z TravelOrdersGridTo=Do TravelOrdersGridTotal=Celkem +TripBillTravelBegin=Počátek cesty +TripBillDate=Datum +TripBillTravelTarget=Místo jednání +TripBillPurpose=Účel cesty +TripBillTravelEnd=Konec cesty +TripBillResultMessage=Zpráva o výsledku pracovní cesty byla podána dne: +TripBillFreeMeals=Stravování bezplatně +TripBillFreeHousing=Ubytování bezplatně +TripBillFreeCarfare=Volná jízdenka +TripBillDepartureArrival=Odjezd - příjezd +TripBillUsed=Použitý dopravní +TripBillVehicle=prostředek +TripBillBeginEnd=Počátek a konec +TripBillWork=pracovního výkonu +TripBillTraveled=Ujeté +TripBillKm=Km +TripBillConsumption=Spotřeba +TripBillPHM=PHM +TripBillCarfare=Jízdné a +TripBillLocal=místní +TripBillTransportation=přeprava +TripBillHousing=Nocležné +TripBillNumber=Počet +TripBillMeals=jídel +TripBillFree=zdarma +TripBillMealExpenses=Stravné +TripBillNecessary=Nutné +TripBillOther=vedlejší +TripBillExpenses=výdaje +TripBillAdjusted=Upraveno +TripBillHourMin=hod:min +TripBillInKc=v Kč +TripBillTo=Tam +TripBillBack=Zpět +TripBillTotal=Celkem + CentresForRequirements=Střediska, pro která lze vkládat požadavky WorkgroupMembership=Členství v komisích LogedInUser=Přihlášený uživatel: diff --git a/src/main/webapp/css/form.css b/src/main/webapp/css/form.css index cda41364..4c67e242 100644 --- a/src/main/webapp/css/form.css +++ b/src/main/webapp/css/form.css @@ -52,4 +52,19 @@ background: #ebebeb; .bold { font-weight: bold; +} + +.vertikaal { + -webkit-transform: rotate(-90deg); + -moz-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); + -o-transform: rotate(-90deg); + transform: rotate(-90deg); + + + -webkit-transform-origin: 50% 50%; + -moz-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + -o-transform-origin: 50% 50%; + transform-origin: 50% 50%; } \ No newline at end of file diff --git a/src/main/webapp/trips/bill/tripBillForm.zul b/src/main/webapp/trips/bill/tripBillForm.zul index 86b7cf16..0404fe56 100644 --- a/src/main/webapp/trips/bill/tripBillForm.zul +++ b/src/main/webapp/trips/bill/tripBillForm.zul @@ -1,4 +1,5 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + +
+ + +
+ +
+ +
+ + +
+
+ + + ${labels.TripBillKm} ]]> + + + + + ${labels.TripBillPHM} ]]> + + + + + ${labels.TripBillLocal}
${labels.TripBillTransportation} ]]> + +
+ + + + + ${labels.TripBillMeals}
${labels.TripBillFree} ]]> + +
+ + + + + ${labels.TripBillOther}
${labels.TripBillExpenses} ]]> + +
+ + + + +
+ + + + + + + + + + + + + + ${labels.TripBillTraveled}
${labels.TripBillKm}
${labels.TripBillInKc} ]]> + +
+ + + ${labels.TripBillPHM}
${labels.TripBillInKc}]]> + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+
+
diff --git a/src/main/webapp/trips/bill/tripBillGrid.zul b/src/main/webapp/trips/bill/tripBillGrid.zul index a4b23a3c..92f30b57 100644 --- a/src/main/webapp/trips/bill/tripBillGrid.zul +++ b/src/main/webapp/trips/bill/tripBillGrid.zul @@ -10,7 +10,7 @@ src="/img/pickup-032.png" zclass="form-caption" label="${labels.TravelOrders}" /> - + - + - +