| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.ofbiz.manufacturing.techdata; |
| |
| import java.sql.Time; |
| import java.sql.Timestamp; |
| import java.util.HashMap; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.UtilDateTime; |
| import org.apache.ofbiz.base.util.UtilMisc; |
| import org.apache.ofbiz.base.util.UtilProperties; |
| import org.apache.ofbiz.base.util.UtilValidate; |
| import org.apache.ofbiz.entity.Delegator; |
| import org.apache.ofbiz.entity.GenericEntityException; |
| import org.apache.ofbiz.entity.GenericValue; |
| import org.apache.ofbiz.entity.condition.EntityCondition; |
| import org.apache.ofbiz.entity.condition.EntityExpr; |
| import org.apache.ofbiz.entity.condition.EntityOperator; |
| import org.apache.ofbiz.entity.util.EntityQuery; |
| import org.apache.ofbiz.entity.util.EntityUtil; |
| import org.apache.ofbiz.service.DispatchContext; |
| import org.apache.ofbiz.service.ServiceUtil; |
| |
| import com.ibm.icu.util.Calendar; |
| |
| /** |
| * TechDataServices - TechData related Services |
| * |
| */ |
| public class TechDataServices { |
| |
| public static final String module = TechDataServices.class.getName(); |
| public static final String resource = "ManufacturingUiLabels"; |
| |
| /** |
| * |
| * Used to retrieve some RoutingTasks (WorkEffort) selected by Name or MachineGroup ordered by Name |
| * |
| * @param ctx the dispatch context |
| * @param context a map containing workEffortName (routingTaskName) and fixedAssetId (MachineGroup or ANY) |
| * @return result a map containing lookupResult (list of RoutingTask <=> workEffortId with currentStatusId = "ROU_ACTIVE" and workEffortTypeId = "ROU_TASK" |
| */ |
| public static Map<String, Object> lookupRoutingTask(DispatchContext ctx, Map<String, ? extends Object> context) { |
| Delegator delegator = ctx.getDelegator(); |
| Map<String, Object> result = new HashMap<String, Object>(); |
| Locale locale = (Locale) context.get("locale"); |
| String workEffortName = (String) context.get("workEffortName"); |
| String fixedAssetId = (String) context.get("fixedAssetId"); |
| |
| List<GenericValue> listRoutingTask = null; |
| List<EntityExpr> constraints = new LinkedList<EntityExpr>(); |
| |
| if (UtilValidate.isNotEmpty(workEffortName)) { |
| constraints.add(EntityCondition.makeCondition("workEffortName", EntityOperator.GREATER_THAN_EQUAL_TO, workEffortName)); |
| } |
| if (UtilValidate.isNotEmpty(fixedAssetId) && ! "ANY".equals(fixedAssetId)) { |
| constraints.add(EntityCondition.makeCondition("fixedAssetId", EntityOperator.EQUALS, fixedAssetId)); |
| } |
| constraints.add(EntityCondition.makeCondition("currentStatusId", EntityOperator.EQUALS, "ROU_ACTIVE")); |
| constraints.add(EntityCondition.makeCondition("workEffortTypeId", EntityOperator.EQUALS, "ROU_TASK")); |
| |
| try { |
| listRoutingTask = EntityQuery.use(delegator).from("WorkEffort") |
| .where(constraints) |
| .orderBy("workEffortName") |
| .queryList(); |
| } catch (GenericEntityException e) { |
| Debug.logWarning(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingTechDataWorkEffortNotExist", UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| if (listRoutingTask == null) { |
| listRoutingTask = new LinkedList<GenericValue>(); |
| } |
| if (listRoutingTask.size() == 0) { |
| //FIXME is it correct ? |
| // listRoutingTask.add(UtilMisc.toMap("label","no Match","value","NO_MATCH")); |
| } |
| result.put("lookupResult", listRoutingTask); |
| return result; |
| } |
| |
| /** |
| * |
| * Used to check if there is not two routing task with the same SeqId valid at the same period |
| * |
| * @param ctx The DispatchContext that this service is operating in. |
| * @param context a map containing workEffortIdFrom (routing) and SeqId, fromDate thruDate |
| * @return result a map containing sequenceNumNotOk which is equal to "Y" if it's not Ok |
| */ |
| public static Map<String, Object> checkRoutingTaskAssoc(DispatchContext ctx, Map<String, ? extends Object> context) { |
| Delegator delegator = ctx.getDelegator(); |
| Map<String, Object> result = new HashMap<String, Object>(); |
| String sequenceNumNotOk = "N"; |
| Locale locale = (Locale) context.get("locale"); |
| String workEffortIdFrom = (String) context.get("workEffortIdFrom"); |
| String workEffortIdTo = (String) context.get("workEffortIdTo"); |
| String workEffortAssocTypeId = (String) context.get("workEffortAssocTypeId"); |
| Long sequenceNum = (Long) context.get("sequenceNum"); |
| Timestamp fromDate = (Timestamp) context.get("fromDate"); |
| Timestamp thruDate = (Timestamp) context.get("thruDate"); |
| String create = (String) context.get("create"); |
| |
| boolean createProcess = (create !=null && create.equals("Y")) ? true : false; |
| List<GenericValue> listRoutingTaskAssoc = null; |
| |
| try { |
| listRoutingTaskAssoc = EntityQuery.use(delegator).from("WorkEffortAssoc") |
| .where("workEffortIdFrom", workEffortIdFrom,"sequenceNum",sequenceNum) |
| .orderBy("fromDate") |
| .queryList(); |
| } catch (GenericEntityException e) { |
| Debug.logWarning(e, module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingTechDataWorkEffortAssocNotExist", UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| |
| if (listRoutingTaskAssoc != null) { |
| for (GenericValue routingTaskAssoc : listRoutingTaskAssoc) { |
| if (! workEffortIdFrom.equals(routingTaskAssoc.getString("workEffortIdFrom")) || |
| ! workEffortIdTo.equals(routingTaskAssoc.getString("workEffortIdTo")) || |
| ! workEffortAssocTypeId.equals(routingTaskAssoc.getString("workEffortAssocTypeId")) || |
| ! sequenceNum.equals(routingTaskAssoc.getLong("sequenceNum")) |
| ) { |
| if (routingTaskAssoc.getTimestamp("thruDate") == null && routingTaskAssoc.getTimestamp("fromDate") == null) sequenceNumNotOk = "Y"; |
| else if (routingTaskAssoc.getTimestamp("thruDate") == null) { |
| if (thruDate == null) sequenceNumNotOk = "Y"; |
| else if (thruDate.after(routingTaskAssoc.getTimestamp("fromDate"))) sequenceNumNotOk = "Y"; |
| } |
| else if (routingTaskAssoc.getTimestamp("fromDate") == null) { |
| if (fromDate == null) sequenceNumNotOk = "Y"; |
| else if (fromDate.before(routingTaskAssoc.getTimestamp("thruDate"))) sequenceNumNotOk = "Y"; |
| } |
| else if (fromDate == null && thruDate == null) sequenceNumNotOk = "Y"; |
| else if (thruDate == null) { |
| if (fromDate.before(routingTaskAssoc.getTimestamp("thruDate"))) sequenceNumNotOk = "Y"; |
| } |
| else if (fromDate == null) { |
| if (thruDate.after(routingTaskAssoc.getTimestamp("fromDate"))) sequenceNumNotOk = "Y"; |
| } |
| else if (routingTaskAssoc.getTimestamp("fromDate").before(thruDate) && fromDate.before(routingTaskAssoc.getTimestamp("thruDate"))) sequenceNumNotOk = "Y"; |
| } else if (createProcess) sequenceNumNotOk = "Y"; |
| } |
| } |
| result.put("sequenceNumNotOk", sequenceNumNotOk); |
| return result; |
| } |
| |
| /** |
| * Used to get the techDataCalendar for a routingTask, if there is a entity exception |
| * or routingTask associated with no MachineGroup the DEFAULT TechDataCalendar is return. |
| * |
| * @param routingTask the routingTask for which we are looking for |
| * @return the techDataCalendar associated |
| */ |
| public static GenericValue getTechDataCalendar(GenericValue routingTask) { |
| GenericValue machineGroup = null, techDataCalendar = null; |
| try { |
| machineGroup = routingTask.getRelatedOne("FixedAsset", true); |
| } catch (GenericEntityException e) { |
| Debug.logError("Pb reading FixedAsset associated with routingTask"+e.getMessage(), module); |
| } |
| if (machineGroup != null) { |
| if (machineGroup.getString("calendarId") != null) { |
| try { |
| techDataCalendar = machineGroup.getRelatedOne("TechDataCalendar", true); |
| } catch (GenericEntityException e) { |
| Debug.logError("Pb reading TechDataCalendar associated with machineGroup"+e.getMessage(), module); |
| } |
| } else { |
| try { |
| List<GenericValue> machines = machineGroup.getRelated("ChildFixedAsset", null, null, true); |
| if (machines != null && machines.size()>0) { |
| GenericValue machine = EntityUtil.getFirst(machines); |
| techDataCalendar = machine.getRelatedOne("TechDataCalendar", true); |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError("Pb reading machine child from machineGroup"+e.getMessage(), module); |
| } |
| } |
| } |
| if (techDataCalendar == null) { |
| try { |
| Delegator delegator = routingTask.getDelegator(); |
| techDataCalendar = EntityQuery.use(delegator).from("TechDataCalendar").where("calendarId", "DEFAULT").queryOne(); |
| } catch (GenericEntityException e) { |
| Debug.logError("Pb reading TechDataCalendar DEFAULT"+e.getMessage(), module); |
| } |
| } |
| return techDataCalendar; |
| } |
| |
| /** Used to find the fisrt day in the TechDataCalendarWeek where capacity != 0, beginning at dayStart, dayStart included. |
| * |
| * @param techDataCalendarWeek The TechDataCalendarWeek cover |
| * @param dayStart |
| * @return a map with the capacity (Double) available and moveDay (int): the number of day it's necessary to move to have capacity available |
| */ |
| public static Map<String, Object> dayStartCapacityAvailable(GenericValue techDataCalendarWeek, int dayStart) { |
| Map<String, Object> result = new HashMap<String, Object>(); |
| int moveDay = 0; |
| Double capacity = null; |
| Time startTime = null; |
| while (capacity == null || capacity.doubleValue()==0) { |
| switch (dayStart) { |
| case Calendar.MONDAY: |
| capacity = techDataCalendarWeek.getDouble("mondayCapacity"); |
| startTime = techDataCalendarWeek.getTime("mondayStartTime"); |
| break; |
| case Calendar.TUESDAY: |
| capacity = techDataCalendarWeek.getDouble("tuesdayCapacity"); |
| startTime = techDataCalendarWeek.getTime("tuesdayStartTime"); |
| break; |
| case Calendar.WEDNESDAY: |
| capacity = techDataCalendarWeek.getDouble("wednesdayCapacity"); |
| startTime = techDataCalendarWeek.getTime("wednesdayStartTime"); |
| break; |
| case Calendar.THURSDAY: |
| capacity = techDataCalendarWeek.getDouble("thursdayCapacity"); |
| startTime = techDataCalendarWeek.getTime("thursdayStartTime"); |
| break; |
| case Calendar.FRIDAY: |
| capacity = techDataCalendarWeek.getDouble("fridayCapacity"); |
| startTime = techDataCalendarWeek.getTime("fridayStartTime"); |
| break; |
| case Calendar.SATURDAY: |
| capacity = techDataCalendarWeek.getDouble("saturdayCapacity"); |
| startTime = techDataCalendarWeek.getTime("saturdayStartTime"); |
| break; |
| case Calendar.SUNDAY: |
| capacity = techDataCalendarWeek.getDouble("sundayCapacity"); |
| startTime = techDataCalendarWeek.getTime("sundayStartTime"); |
| break; |
| } |
| if (capacity == null || capacity.doubleValue() == 0) { |
| moveDay +=1; |
| dayStart = (dayStart==7) ? 1 : dayStart +1; |
| } |
| } |
| result.put("capacity",capacity); |
| result.put("startTime",startTime); |
| result.put("moveDay",Integer.valueOf(moveDay)); |
| return result; |
| } |
| /** Used to to request the remain capacity available for dateFrom in a TechDataCalenda, |
| * If the dateFrom (param in) is not in an available TechDataCalendar period, the return value is zero. |
| * |
| * @param techDataCalendar The TechDataCalendar cover |
| * @param dateFrom the date |
| * @return long capacityRemaining |
| */ |
| public static long capacityRemaining(GenericValue techDataCalendar, Timestamp dateFrom) { |
| GenericValue techDataCalendarWeek = null; |
| // TODO read TechDataCalendarExcWeek to manage execption week (maybe it's needed to refactor the entity definition |
| try { |
| techDataCalendarWeek = techDataCalendar.getRelatedOne("TechDataCalendarWeek", true); |
| } catch (GenericEntityException e) { |
| Debug.logError("Pb reading Calendar Week associated with calendar"+e.getMessage(), module); |
| return 0; |
| } |
| // TODO read TechDataCalendarExcDay to manage execption day |
| Calendar cDateTrav = Calendar.getInstance(); |
| cDateTrav.setTime(dateFrom); |
| Map<String, Object> position = dayStartCapacityAvailable(techDataCalendarWeek, cDateTrav.get(Calendar.DAY_OF_WEEK)); |
| int moveDay = ((Integer) position.get("moveDay")).intValue(); |
| if (moveDay != 0) return 0; |
| Time startTime = (Time) position.get("startTime"); |
| Double capacity = (Double) position.get("capacity"); |
| Timestamp startAvailablePeriod = new Timestamp(UtilDateTime.getDayStart(dateFrom).getTime() + startTime.getTime() + cDateTrav.get(Calendar.ZONE_OFFSET) + cDateTrav.get(Calendar.DST_OFFSET)); |
| if (dateFrom.before(startAvailablePeriod)) return 0; |
| Timestamp endAvailablePeriod = new Timestamp(startAvailablePeriod.getTime()+capacity.longValue()); |
| if (dateFrom.after(endAvailablePeriod)) return 0; |
| return endAvailablePeriod.getTime() - dateFrom.getTime(); |
| } |
| /** Used to move in a TechDataCalenda, produce the Timestamp for the begining of the next day available and its associated capacity. |
| * If the dateFrom (param in) is not in an available TechDataCalendar period, the return value is the next day available |
| * |
| * @param techDataCalendar The TechDataCalendar cover |
| * @param dateFrom the date |
| * @return a map with Timestamp dateTo, Double nextCapacity |
| */ |
| public static Map<String, Object> startNextDay(GenericValue techDataCalendar, Timestamp dateFrom) { |
| Map<String, Object> result = new HashMap<String, Object>(); |
| Timestamp dateTo = null; |
| GenericValue techDataCalendarWeek = null; |
| // TODO read TechDataCalendarExcWeek to manage execption week (maybe it's needed to refactor the entity definition |
| try { |
| techDataCalendarWeek = techDataCalendar.getRelatedOne("TechDataCalendarWeek", true); |
| } catch (GenericEntityException e) { |
| Debug.logError("Pb reading Calendar Week associated with calendar"+e.getMessage(), module); |
| return ServiceUtil.returnError("Pb reading Calendar Week associated with calendar"); |
| } |
| // TODO read TechDataCalendarExcDay to manage execption day |
| Calendar cDateTrav = Calendar.getInstance(); |
| cDateTrav.setTime(dateFrom); |
| Map<String, Object> position = dayStartCapacityAvailable(techDataCalendarWeek, cDateTrav.get(Calendar.DAY_OF_WEEK)); |
| Time startTime = (Time) position.get("startTime"); |
| int moveDay = ((Integer) position.get("moveDay")).intValue(); |
| dateTo = (moveDay == 0) ? dateFrom : UtilDateTime.getDayStart(dateFrom,moveDay); |
| Timestamp startAvailablePeriod = new Timestamp(UtilDateTime.getDayStart(dateTo).getTime() + startTime.getTime() + cDateTrav.get(Calendar.ZONE_OFFSET) + cDateTrav.get(Calendar.DST_OFFSET)); |
| if (dateTo.before(startAvailablePeriod)) { |
| dateTo = startAvailablePeriod; |
| } |
| else { |
| dateTo = UtilDateTime.getNextDayStart(dateTo); |
| cDateTrav.setTime(dateTo); |
| position = dayStartCapacityAvailable(techDataCalendarWeek, cDateTrav.get(Calendar.DAY_OF_WEEK)); |
| startTime = (Time) position.get("startTime"); |
| moveDay = ((Integer) position.get("moveDay")).intValue(); |
| if (moveDay != 0) dateTo = UtilDateTime.getDayStart(dateTo,moveDay); |
| dateTo.setTime(dateTo.getTime() + startTime.getTime() + cDateTrav.get(Calendar.ZONE_OFFSET) + cDateTrav.get(Calendar.DST_OFFSET)); |
| } |
| result.put("dateTo",dateTo); |
| result.put("nextCapacity",position.get("capacity")); |
| return result; |
| } |
| /** Used to move forward in a TechDataCalenda, start from the dateFrom and move forward only on available period. |
| * If the dateFrom (param in) is not a available TechDataCalendar period, the startDate is the begining of the next day available |
| * |
| * @param techDataCalendar The TechDataCalendar cover |
| * @param dateFrom the start date |
| * @param amount the amount of millisecond to move forward |
| * @return the dateTo |
| */ |
| public static Timestamp addForward(GenericValue techDataCalendar, Timestamp dateFrom, long amount) { |
| Timestamp dateTo = (Timestamp) dateFrom.clone(); |
| long nextCapacity = capacityRemaining(techDataCalendar, dateFrom); |
| if (amount <= nextCapacity) { |
| dateTo.setTime(dateTo.getTime()+amount); |
| amount = 0; |
| } else amount -= nextCapacity; |
| |
| Map<String, Object> result = new HashMap<String, Object>(); |
| while (amount > 0) { |
| result = startNextDay(techDataCalendar, dateTo); |
| dateTo = (Timestamp) result.get("dateTo"); |
| nextCapacity = ((Double) result.get("nextCapacity")).longValue(); |
| if (amount <= nextCapacity) { |
| dateTo.setTime(dateTo.getTime()+amount); |
| amount = 0; |
| } else amount -= nextCapacity; |
| } |
| return dateTo; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| /** Used to find the last day in the TechDataCalendarWeek where capacity != 0, ending at dayEnd, dayEnd included. |
| * |
| * @param techDataCalendarWeek The TechDataCalendarWeek cover |
| * @param dayEnd |
| * @return a map with the capacity (Double) available, the startTime and moveDay (int): the number of day it's necessary to move to have capacity available |
| */ |
| public static Map<String, Object> dayEndCapacityAvailable(GenericValue techDataCalendarWeek, int dayEnd) { |
| Map<String, Object> result = new HashMap<String, Object>(); |
| int moveDay = 0; |
| Double capacity = null; |
| Time startTime = null; |
| while (capacity == null || capacity.doubleValue() == 0) { |
| switch (dayEnd) { |
| case Calendar.MONDAY: |
| capacity = techDataCalendarWeek.getDouble("mondayCapacity"); |
| startTime = techDataCalendarWeek.getTime("mondayStartTime"); |
| break; |
| case Calendar.TUESDAY: |
| capacity = techDataCalendarWeek.getDouble("tuesdayCapacity"); |
| startTime = techDataCalendarWeek.getTime("tuesdayStartTime"); |
| break; |
| case Calendar.WEDNESDAY: |
| capacity = techDataCalendarWeek.getDouble("wednesdayCapacity"); |
| startTime = techDataCalendarWeek.getTime("wednesdayStartTime"); |
| break; |
| case Calendar.THURSDAY: |
| capacity = techDataCalendarWeek.getDouble("thursdayCapacity"); |
| startTime = techDataCalendarWeek.getTime("thursdayStartTime"); |
| break; |
| case Calendar.FRIDAY: |
| capacity = techDataCalendarWeek.getDouble("fridayCapacity"); |
| startTime = techDataCalendarWeek.getTime("fridayStartTime"); |
| break; |
| case Calendar.SATURDAY: |
| capacity = techDataCalendarWeek.getDouble("saturdayCapacity"); |
| startTime = techDataCalendarWeek.getTime("saturdayStartTime"); |
| break; |
| case Calendar.SUNDAY: |
| capacity = techDataCalendarWeek.getDouble("sundayCapacity"); |
| startTime = techDataCalendarWeek.getTime("sundayStartTime"); |
| break; |
| } |
| if (capacity == null || capacity.doubleValue() == 0) { |
| moveDay -=1; |
| dayEnd = (dayEnd==1) ? 7 : dayEnd - 1; |
| } |
| } |
| result.put("capacity",capacity); |
| result.put("startTime",startTime); |
| result.put("moveDay",Integer.valueOf(moveDay)); |
| return result; |
| } |
| /** Used to request the remaining capacity available for dateFrom in a TechDataCalenda, |
| * If the dateFrom (param in) is not in an available TechDataCalendar period, the return value is zero. |
| * |
| * @param techDataCalendar The TechDataCalendar cover |
| * @param dateFrom the date |
| * @return long capacityRemaining |
| */ |
| public static long capacityRemainingBackward(GenericValue techDataCalendar, Timestamp dateFrom) { |
| GenericValue techDataCalendarWeek = null; |
| // TODO read TechDataCalendarExcWeek to manage exception week (maybe it's needed to refactor the entity definition |
| try { |
| techDataCalendarWeek = techDataCalendar.getRelatedOne("TechDataCalendarWeek", true); |
| } catch (GenericEntityException e) { |
| Debug.logError("Pb reading Calendar Week associated with calendar"+e.getMessage(), module); |
| return 0; |
| } |
| // TODO read TechDataCalendarExcDay to manage execption day |
| Calendar cDateTrav = Calendar.getInstance(); |
| cDateTrav.setTime(dateFrom); |
| Map<String, Object> position = dayEndCapacityAvailable(techDataCalendarWeek, cDateTrav.get(Calendar.DAY_OF_WEEK)); |
| int moveDay = ((Integer) position.get("moveDay")).intValue(); |
| if (moveDay != 0) return 0; |
| Time startTime = (Time) position.get("startTime"); |
| Double capacity = (Double) position.get("capacity"); |
| Timestamp startAvailablePeriod = new Timestamp(UtilDateTime.getDayStart(dateFrom).getTime() + startTime.getTime() + cDateTrav.get(Calendar.ZONE_OFFSET) + cDateTrav.get(Calendar.DST_OFFSET)); |
| if (dateFrom.before(startAvailablePeriod)) return 0; |
| Timestamp endAvailablePeriod = new Timestamp(startAvailablePeriod.getTime()+capacity.longValue()); |
| if (dateFrom.after(endAvailablePeriod)) return 0; |
| return dateFrom.getTime() - startAvailablePeriod.getTime(); |
| } |
| /** Used to move in a TechDataCalenda, produce the Timestamp for the end of the previous day available and its associated capacity. |
| * If the dateFrom (param in) is not in an available TechDataCalendar period, the return value is the previous day available |
| * |
| * @param techDataCalendar The TechDataCalendar cover |
| * @param dateFrom the date |
| * @return a map with Timestamp dateTo, Double previousCapacity |
| */ |
| public static Map<String, Object> endPreviousDay(GenericValue techDataCalendar, Timestamp dateFrom) { |
| Map<String, Object> result = new HashMap<String, Object>(); |
| Timestamp dateTo = null; |
| GenericValue techDataCalendarWeek = null; |
| // TODO read TechDataCalendarExcWeek to manage exception week (maybe it's needed to refactor the entity definition |
| try { |
| techDataCalendarWeek = techDataCalendar.getRelatedOne("TechDataCalendarWeek", true); |
| } catch (GenericEntityException e) { |
| Debug.logError("Pb reading Calendar Week associated with calendar"+e.getMessage(), module); |
| return ServiceUtil.returnError("Pb reading Calendar Week associated with calendar"); |
| } |
| // TODO read TechDataCalendarExcDay to manage execption day |
| Calendar cDateTrav = Calendar.getInstance(); |
| cDateTrav.setTime(dateFrom); |
| Map<String, Object> position = dayEndCapacityAvailable(techDataCalendarWeek, cDateTrav.get(Calendar.DAY_OF_WEEK)); |
| Time startTime = (Time) position.get("startTime"); |
| int moveDay = ((Integer) position.get("moveDay")).intValue(); |
| Double capacity = (Double) position.get("capacity"); |
| dateTo = (moveDay == 0) ? dateFrom : UtilDateTime.getDayEnd(dateFrom, Long.valueOf(moveDay)); |
| Timestamp endAvailablePeriod = new Timestamp(UtilDateTime.getDayStart(dateTo).getTime() + startTime.getTime() + capacity.longValue() + cDateTrav.get(Calendar.ZONE_OFFSET) + cDateTrav.get(Calendar.DST_OFFSET)); |
| if (dateTo.after(endAvailablePeriod)) { |
| dateTo = endAvailablePeriod; |
| } |
| else { |
| dateTo = UtilDateTime.getDayStart(dateTo, -1); |
| cDateTrav.setTime(dateTo); |
| position = dayEndCapacityAvailable(techDataCalendarWeek, cDateTrav.get(Calendar.DAY_OF_WEEK)); |
| startTime = (Time) position.get("startTime"); |
| moveDay = ((Integer) position.get("moveDay")).intValue(); |
| capacity = (Double) position.get("capacity"); |
| if (moveDay != 0) dateTo = UtilDateTime.getDayStart(dateTo,moveDay); |
| dateTo.setTime(dateTo.getTime() + startTime.getTime() + capacity.longValue() + cDateTrav.get(Calendar.ZONE_OFFSET) + cDateTrav.get(Calendar.DST_OFFSET)); |
| } |
| result.put("dateTo",dateTo); |
| result.put("previousCapacity",position.get("capacity")); |
| return result; |
| } |
| /** Used to move backward in a TechDataCalendar, start from the dateFrom and move backward only on available period. |
| * If the dateFrom (param in) is not a available TechDataCalendar period, the startDate is the end of the previous day available |
| * |
| * @param techDataCalendar The TechDataCalendar cover |
| * @param dateFrom the start date |
| * @param amount the amount of millisecond to move backward |
| * @return the dateTo |
| */ |
| public static Timestamp addBackward(GenericValue techDataCalendar, Timestamp dateFrom, long amount) { |
| Timestamp dateTo = (Timestamp) dateFrom.clone(); |
| long previousCapacity = capacityRemainingBackward(techDataCalendar, dateFrom); |
| if (amount <= previousCapacity) { |
| dateTo.setTime(dateTo.getTime()-amount); |
| amount = 0; |
| } else amount -= previousCapacity; |
| |
| Map<String, Object> result = new HashMap<String, Object>(); |
| while (amount > 0) { |
| result = endPreviousDay(techDataCalendar, dateTo); |
| dateTo = (Timestamp) result.get("dateTo"); |
| previousCapacity = ((Double) result.get("previousCapacity")).longValue(); |
| if (amount <= previousCapacity) { |
| dateTo.setTime(dateTo.getTime()-amount); |
| amount = 0; |
| } else amount -= previousCapacity; |
| } |
| return dateTo; |
| } |
| } |