use of org.eevolution.exceptions.CRPException in project adempiere by adempiere.
the class CRP method scheduleForward.
private Timestamp scheduleForward(final Timestamp start, final long nodeDurationMillis, MResource r) {
MResourceType t = r.getResourceType();
// statistical interation count
int iteration = 0;
Timestamp currentDate = start;
Timestamp end = null;
long remainingMillis = nodeDurationMillis;
do {
currentDate = reasoner.getAvailableDate(r, currentDate, false);
Timestamp dayStart = t.getDayStart(currentDate);
Timestamp dayEnd = t.getDayEnd(currentDate);
// resource's availability, switch start time to the given again
if (currentDate.after(dayStart) && currentDate.before(dayEnd)) {
dayStart = currentDate;
}
// The available time at this day in milliseconds
long availableDayDuration = getAvailableDurationMillis(dayStart, dayEnd, r);
// The work can be finish on this day.
if (availableDayDuration >= remainingMillis) {
end = new Timestamp(dayStart.getTime() + remainingMillis);
remainingMillis = 0;
break;
} else // Otherwise recall with next day and the remained node duration.
{
currentDate = TimeUtil.addDays(TimeUtil.getDayBorder(currentDate, null, false), 1);
remainingMillis -= availableDayDuration;
}
iteration++;
if (iteration > p_MaxIterationsNo) {
throw new CRPException("Maximum number of iterations exceeded (" + p_MaxIterationsNo + ")" + " - Date:" + currentDate + ", RemainingMillis:" + remainingMillis);
}
} while (remainingMillis > 0);
return end;
}
use of org.eevolution.exceptions.CRPException in project adempiere by adempiere.
the class CRP method getAvailableDurationMillis.
/**
* Calculate duration in millis
* @param dayStart
* @param dayEnd
* @param resource
* @return dayEnd - dayStart in millis
* @throws CRPException if dayStart > dayEnd
*/
private long getAvailableDurationMillis(Timestamp dayStart, Timestamp dayEnd, I_S_Resource resource) {
long availableDayDuration = dayEnd.getTime() - dayStart.getTime();
log.info("--> availableDayDuration " + availableDayDuration);
if (availableDayDuration < 0) {
throw new CRPException("@TimeSlotStart@ > @TimeSlotEnd@ (" + dayEnd + " > " + dayStart + ")").setS_Resource(resource);
}
return availableDayDuration;
}
use of org.eevolution.exceptions.CRPException in project adempiere by adempiere.
the class CRP method scheduleBackward.
/**
* Calculate start date having duration and resource
* @param end end date
* @param nodeDurationMillis duration [millis]
* @param r resource
* @return start date
*/
private Timestamp scheduleBackward(final Timestamp end, final long nodeDurationMillis, MResource r) {
MResourceType t = r.getResourceType();
log.info("--> ResourceType " + t);
Timestamp start = null;
Timestamp currentDate = end;
long remainingMillis = nodeDurationMillis;
// statistical iteration count
int iteration = 0;
do {
log.info("--> end=" + currentDate);
log.info("--> nodeDuration=" + remainingMillis);
currentDate = reasoner.getAvailableDate(r, currentDate, true);
log.info("--> end(available)=" + currentDate);
Timestamp dayEnd = t.getDayEnd(currentDate);
Timestamp dayStart = t.getDayStart(currentDate);
log.info("--> dayStart=" + dayStart + ", dayEnd=" + dayEnd);
// resource's availability, switch end time to the given again
if (currentDate.before(dayEnd) && currentDate.after(dayStart)) {
dayEnd = currentDate;
}
// The available time at this day in milliseconds
long availableDayDuration = getAvailableDurationMillis(dayStart, dayEnd, r);
// The work can be finish on this day.
if (availableDayDuration >= remainingMillis) {
log.info("--> availableDayDuration >= nodeDuration true " + availableDayDuration + "|" + remainingMillis);
start = new Timestamp(dayEnd.getTime() - remainingMillis);
remainingMillis = 0;
break;
} else // Otherwise recall with previous day and the remained node duration.
{
log.info("--> availableDayDuration >= nodeDuration false " + availableDayDuration + "|" + remainingMillis);
log.info("--> nodeDuration-availableDayDuration " + (remainingMillis - availableDayDuration));
currentDate = TimeUtil.addDays(TimeUtil.getDayBorder(currentDate, null, true), -1);
remainingMillis -= availableDayDuration;
}
//
iteration++;
if (iteration > p_MaxIterationsNo) {
throw new CRPException("Maximum number of iterations exceeded (" + p_MaxIterationsNo + ")" + " - Date:" + start + ", RemainingMillis:" + remainingMillis);
}
} while (remainingMillis > 0);
log.info(" --> start=" + start + " <---------------------------------------- ");
return start;
}
use of org.eevolution.exceptions.CRPException in project adempiere by adempiere.
the class CRP method runCRP.
public void runCRP(MPPOrder order) {
log.info("PP_Order DocumentNo:" + order.getDocumentNo());
MPPOrderWorkflow owf = order.getMPPOrderWorkflow();
if (owf == null) {
// TODO: generate notice
addLog("WARNING: No workflow found - " + order);
return;
}
log.info("PP_Order Workflow:" + owf.getName());
final ArrayList<Integer> visitedNodes = new ArrayList<Integer>();
// Schedule Fordward
if (p_ScheduleType.equals(FORWARD_SCHEDULING)) {
Timestamp date = order.getDateStartSchedule();
int nodeId = owf.getPP_Order_Node_ID();
MPPOrderNode node = null;
while (nodeId != 0) {
node = owf.getNode(nodeId);
if (visitedNodes.contains(nodeId)) {
throw new CRPException("Cyclic transition found").setPP_Order_Node(node);
}
visitedNodes.add(nodeId);
log.info("PP_Order Node:" + node.getName() != null ? node.getName() : "" + " Description:" + node.getDescription() != null ? node.getDescription() : "");
//
MResource resource = MResource.get(getCtx(), node.getS_Resource_ID());
// Skip this node if there is no resource
if (resource == null) {
nodeId = owf.getNext(nodeId, getAD_Client_ID());
continue;
}
if (!reasoner.isAvailable(resource)) {
throw new CRPException("@ResourceNotInSlotDay@").setS_Resource(resource);
}
long nodeMillis = calculateMillisFor(node, owf.getDurationBaseSec());
Timestamp dateFinish = scheduleForward(date, nodeMillis, resource);
node.setDateStartSchedule(date);
node.setDateFinishSchedule(dateFinish);
node.saveEx();
date = node.getDateFinishSchedule();
nodeId = owf.getNext(nodeId, getAD_Client_ID());
}
// Update order finish date
if (node != null && node.getDateFinishSchedule() != null) {
order.setDateFinishSchedule(node.getDateFinishSchedule());
}
} else // Schedule backward
if (p_ScheduleType.equals(BACKWARD_SCHEDULING)) {
Timestamp date = order.getDateFinishSchedule();
int nodeId = owf.getNodeLastID(getAD_Client_ID());
MPPOrderNode node = null;
while (nodeId != 0) {
node = owf.getNode(nodeId);
if (visitedNodes.contains(nodeId)) {
throw new CRPException("Cyclic transition found - ").setPP_Order_Node(node);
}
visitedNodes.add(nodeId);
log.info("PP_Order Node:" + node.getName() != null ? node.getName() : "" + " Description:" + node.getDescription() != null ? node.getDescription() : "");
//
MResource resource = MResource.get(getCtx(), node.getS_Resource_ID());
// Skip this node if there is no resource
if (resource == null) {
nodeId = owf.getPrevious(nodeId, getAD_Client_ID());
continue;
}
if (!reasoner.isAvailable(resource)) {
throw new CRPException("@ResourceNotInSlotDay@").setS_Resource(resource);
}
long nodeMillis = calculateMillisFor(node, owf.getDurationBaseSec());
Timestamp dateStart = scheduleBackward(date, nodeMillis, resource);
node.setDateStartSchedule(dateStart);
node.setDateFinishSchedule(date);
node.saveEx();
date = node.getDateStartSchedule();
nodeId = owf.getPrevious(nodeId, getAD_Client_ID());
}
// Update order start date
if (node != null && node.getDateStartSchedule() != null) {
order.setDateStartSchedule(node.getDateStartSchedule());
}
} else {
throw new CRPException("Unknown scheduling method - " + p_ScheduleType);
}
order.saveEx(get_TrxName());
}
Aggregations