Java tutorial
/** * *************************************************************************** * Copyright (c) 2010 Qcadoo Limited * Project: Qcadoo MES * Version: 1.3 * * This file is part of Qcadoo. * * Qcadoo is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************** */ package com.qcadoo.mes.avgLaborCostCalcForOrder; import static com.qcadoo.mes.assignmentToShift.constants.AssignmentToShiftFields.SHIFT; import static com.qcadoo.mes.assignmentToShift.constants.AssignmentToShiftFields.START_DATE; import static com.qcadoo.mes.assignmentToShift.constants.StaffAssignmentToShiftFields.WORKER; import static com.qcadoo.mes.avgLaborCostCalcForOrder.constants.AvgLaborCostCalcForOrderFields.AVERAGE_LABOR_HOURLY_COST; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.Period; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.google.common.collect.Lists; import com.qcadoo.mes.assignmentToShift.constants.AssignmentToShiftConstants; import com.qcadoo.mes.assignmentToShift.constants.AssignmentToShiftFields; import com.qcadoo.mes.assignmentToShift.constants.StaffAssignmentToShiftFields; import com.qcadoo.mes.assignmentToShift.constants.StaffAssignmentToShiftState; import com.qcadoo.mes.assignmentToShift.states.constants.AssignmentToShiftState; import com.qcadoo.mes.avgLaborCostCalcForOrder.constants.AssignmentWorkerToShiftFields; import com.qcadoo.mes.avgLaborCostCalcForOrder.constants.AvgLaborCostCalcForOrderConstants; import com.qcadoo.mes.avgLaborCostCalcForOrder.constants.AvgLaborCostCalcForOrderFields; import com.qcadoo.mes.basic.ShiftsService; import com.qcadoo.mes.basic.ShiftsServiceImpl.ShiftHour; import com.qcadoo.mes.basic.constants.BasicConstants; import com.qcadoo.model.api.DataDefinitionService; import com.qcadoo.model.api.Entity; import com.qcadoo.model.api.NumberService; import com.qcadoo.model.api.search.SearchCriteriaBuilder; import com.qcadoo.model.api.search.SearchOrders; import com.qcadoo.model.api.search.SearchRestrictions; @Service public class AverageCostService { @Autowired private DataDefinitionService dataDefinitionService; @Autowired private NumberService numberService; @Autowired private ShiftsService shiftsService; public Entity generateAssignmentWorkerToShiftAndAverageCost(final Entity entity, final Date start, final Date finish, final Entity productionLine) { Entity avgLaborCostCalcForOrder = entity.getDataDefinition().get(entity.getId()); List<DateTime> days = getDaysBetweenGivenDates(start, finish); List<Entity> shifts = getAllShifts(); Map<Entity, BigDecimal> workersWithHoursWorked = generateMapWorkersWithHoursWorked(days, shifts, productionLine); BigDecimal averageCost = countAverageCost(workersWithHoursWorked); if (averageCost == null) { avgLaborCostCalcForOrder.addError(entity.getDataDefinition().getField(AVERAGE_LABOR_HOURLY_COST), "avgLaborCostCalcForOrder.avgLaborCostCalcForOrder.averageLaborHourlyCost.isZero"); avgLaborCostCalcForOrder.addError( entity.getDataDefinition().getField(AvgLaborCostCalcForOrderFields.START_DATE), "avgLaborCostCalcForOrder.avgLaborCostCalcForOrder.averageLaborHourlyCost.isZero"); avgLaborCostCalcForOrder.addError( entity.getDataDefinition().getField(AvgLaborCostCalcForOrderFields.FINISH_DATE), "avgLaborCostCalcForOrder.avgLaborCostCalcForOrder.averageLaborHourlyCost.isZero"); } else { avgLaborCostCalcForOrder.setField(AVERAGE_LABOR_HOURLY_COST, averageCost); avgLaborCostCalcForOrder.setField(AvgLaborCostCalcForOrderFields.ASSIGNMENT_WORKER_TO_SHIFTS, createAssignmentWorkerToShift(workersWithHoursWorked)); } return avgLaborCostCalcForOrder; } private Map<Entity, BigDecimal> generateMapWorkersWithHoursWorked(final List<DateTime> days, final List<Entity> shifts, final Entity productionLine) { Map<Entity, BigDecimal> workersWithHours = new HashMap<Entity, BigDecimal>(); for (DateTime day : days) { for (Entity shift : shifts) { Entity assignmentToShift = getAssignmentToShift(shift, day.toDate()); if (assignmentToShift == null) { continue; } List<Entity> staffs = getStaffAssignmentToShiftDependOnAssignmentToShiftState(assignmentToShift, productionLine); for (Entity staff : staffs) { if (workersWithHours.containsKey(staff)) { BigDecimal countHours = workersWithHours.get(staff).add(getWorkedHoursOfWorker(shift, day)); workersWithHours.put(staff, countHours); } else { workersWithHours.put(staff, getWorkedHoursOfWorker(shift, day)); } } } } return workersWithHours; } private BigDecimal countAverageCost(final Map<Entity, BigDecimal> workersWithHoursWorked) { BigDecimal averageCost = BigDecimal.ZERO; BigDecimal countHours = BigDecimal.ZERO; for (Entry<Entity, BigDecimal> workerWithHours : workersWithHoursWorked.entrySet()) { BigDecimal quantityOfHours = workerWithHours.getValue(); BigDecimal costOfWorkerHours = workerWithHours.getKey() .getBelongsToField(StaffAssignmentToShiftFields.WORKER).getDecimalField("laborHourlyCost") .multiply(quantityOfHours); averageCost = averageCost.add(costOfWorkerHours); countHours = countHours.add(quantityOfHours); } if (countHours.equals(BigDecimal.ZERO)) { return null; } return numberService.setScale(averageCost.divide(countHours, numberService.getMathContext())); } private BigDecimal getWorkedHoursOfWorker(final Entity shift, final DateTime dateOfDay) { BigDecimal hours = BigDecimal.ZERO; List<ShiftHour> workedHours = shiftsService.getHoursForShift(shift, dateOfDay.toDate(), dateOfDay.plusDays(1).toDate()); for (ShiftHour shiftHour : workedHours) { DateTime dateFrom = new DateTime(shiftHour.getDateFrom()); DateTime dateTo = new DateTime(shiftHour.getDateTo()); Period p = new Period(dateFrom, dateTo); hours = hours.add(new BigDecimal(p.getHours())); } return hours; } private Entity getAssignmentToShift(final Entity shift, final Date date) { boolean shiftWorks = shiftsService.checkIfShiftWorkAtDate(date, shift); if (shiftWorks) { return dataDefinitionService .get(AssignmentToShiftConstants.PLUGIN_IDENTIFIER, AssignmentToShiftConstants.MODEL_ASSIGNMENT_TO_SHIFT) .find().add(SearchRestrictions.belongsTo(SHIFT, shift)) .add(SearchRestrictions.le(START_DATE, date)).addOrder(SearchOrders.desc(START_DATE)) .setMaxResults(1).uniqueResult(); } else { return null; } } private List<Entity> getStaffAssignmentToShiftDependOnAssignmentToShiftState(final Entity assignmentToShift, final Entity productionLine) { List<Entity> staffAssignmentToShifts = new ArrayList<Entity>(); String state = assignmentToShift.getStringField(AssignmentToShiftFields.STATE); SearchCriteriaBuilder searchCriteriaBuilder = assignmentToShift.getHasManyField("staffAssignmentToShifts") .find().add(SearchRestrictions.eq("occupationTypeEnum", "01workOnLine")) .add(SearchRestrictions.belongsTo(StaffAssignmentToShiftFields.PRODUCTION_LINE, productionLine)); if (state.equals(AssignmentToShiftState.CORRECTED.getStringValue())) { staffAssignmentToShifts = searchCriteriaBuilder .add(SearchRestrictions.eq("state", StaffAssignmentToShiftState.CORRECTED.getStringValue())) .list().getEntities(); } else if (state.equals(AssignmentToShiftState.ACCEPTED.getStringValue()) || state.equals(AssignmentToShiftState.DURING_CORRECTION.getStringValue())) { staffAssignmentToShifts = searchCriteriaBuilder .add(SearchRestrictions.eq("state", StaffAssignmentToShiftState.ACCEPTED.getStringValue())) .list().getEntities(); } return staffAssignmentToShifts; } private List<Entity> createAssignmentWorkerToShift(final Map<Entity, BigDecimal> workersWithHoursWorked) { Map<Long, Entity> workers = new HashMap<Long, Entity>(); for (Entry<Entity, BigDecimal> workerWithHours : workersWithHoursWorked.entrySet()) { Entity worker = workerWithHours.getKey().getBelongsToField(WORKER); Long workerId = worker.getId(); Entity assignmentWorkerToShift = dataDefinitionService .get(AvgLaborCostCalcForOrderConstants.PLUGIN_IDENTIFIER, AvgLaborCostCalcForOrderConstants.MODEL_ASSIGNMENT_WORKER_TO_SHIFT) .create(); if (workers.containsKey(workerId)) { assignmentWorkerToShift = workers.get(workerId); BigDecimal countHours = assignmentWorkerToShift .getDecimalField(AssignmentWorkerToShiftFields.WORKED_HOURS) .add(workerWithHours.getValue()); assignmentWorkerToShift.setField(AssignmentWorkerToShiftFields.WORKED_HOURS, countHours); } else { assignmentWorkerToShift.setField(AssignmentWorkerToShiftFields.ASSIGNMENT_TO_SHIFT, workerWithHours.getKey().getBelongsToField("assignmentToShift")); assignmentWorkerToShift.setField(AssignmentWorkerToShiftFields.WORKER, worker); assignmentWorkerToShift.setField(AssignmentWorkerToShiftFields.WORKED_HOURS, workerWithHours.getValue()); } workers.put(worker.getId(), assignmentWorkerToShift); } return Lists.newArrayList(workers.values()); } private List<DateTime> getDaysBetweenGivenDates(final Date start, final Date finish) { List<DateTime> days = new LinkedList<DateTime>(); DateTime startDate = new DateTime(start); DateTime finishDate = new DateTime(finish); DateTime nextDay = startDate; int numberOfDays = Days.daysBetween(startDate.toDateMidnight(), finishDate.toDateMidnight()).getDays(); days.add(nextDay); int oneDay = 1; while (numberOfDays != 0) { nextDay = nextDay.plusDays(oneDay).toDateTime(); days.add(nextDay); numberOfDays--; } return days; } private List<Entity> getAllShifts() { return dataDefinitionService.get(BasicConstants.PLUGIN_IDENTIFIER, BasicConstants.MODEL_SHIFT).find().list() .getEntities(); } }