in applications/manufacturing/src/main/java/org/apache/ofbiz/manufacturing/mrp/MrpServices.java [62:508]
public static Map<String, Object> initMrpEvents(DispatchContext ctx, Map<String, ? extends Object> context) {
Delegator delegator = ctx.getDelegator();
LocalDispatcher dispatcher = ctx.getDispatcher();
Timestamp now = UtilDateTime.nowTimestamp();
Locale locale = (Locale) context.get("locale");
String facilityId = (String) context.get("facilityId");
Integer defaultYearsOffset = (Integer) context.get("defaultYearsOffset");
String mrpId = (String) context.get("mrpId");
//Erases the old table for the moment and initializes it with the new orders,
//Does not modify the old one now.
List<GenericValue> listResult = null;
try {
listResult = EntityQuery.use(delegator).from("MrpEvent").queryList();
} catch (GenericEntityException e) {
Debug.logError(e, "Error : findList(\"MrpEvent\", null, null, null, null, false)", MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventFindError", locale));
}
if (listResult != null) {
try {
delegator.removeAll(listResult);
} catch (GenericEntityException e) {
Debug.logError(e, "Error : removeAll(listResult), listResult =" + listResult, MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventRemoveError", locale));
}
}
// Proposed requirements are deleted
List<GenericValue> listResultRoles = new LinkedList<>();
try {
listResult = EntityQuery.use(delegator).from("Requirement")
.where("requirementTypeId", "PRODUCT_REQUIREMENT", "facilityId", facilityId,
"statusId", "REQ_PROPOSED")
.queryList();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventFindError", locale));
}
List<GenericValue> requirementStatus = new ArrayList<>();
if (listResult != null) {
try {
for (GenericValue tmpRequirement : listResult) {
listResultRoles.addAll(tmpRequirement.getRelated("RequirementRole", null, null, false));
requirementStatus.addAll(tmpRequirement.getRelated("RequirementStatus", null, null, false));
}
delegator.removeAll(listResultRoles);
delegator.removeAll(requirementStatus);
delegator.removeAll(listResult);
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventRemoveError", locale));
}
}
try {
listResult = EntityQuery.use(delegator).from("Requirement")
.where("requirementTypeId", "INTERNAL_REQUIREMENT", "facilityId", facilityId,
"statusId", "REQ_PROPOSED")
.queryList();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventFindError", locale));
}
if (listResult != null) {
try {
for (GenericValue tempRequirement : listResult) {
requirementStatus.addAll(tempRequirement.getRelated("RequirementStatus", null, null, false));
}
delegator.removeAll(requirementStatus);
delegator.removeAll(listResult);
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventRemoveError", locale));
}
}
Map<String, Object> parameters = null;
List<GenericValue> resultList = null;
// ----------------------------------------
// Loads all the approved sales order items and purchase order items
// ----------------------------------------
// This is the default required date for orders without dates specified:
// by convention it is a date far in the future of 100 years.
Timestamp notAssignedDate = null;
if (UtilValidate.isEmpty(defaultYearsOffset)) {
notAssignedDate = now;
} else {
Calendar calendar = UtilDateTime.toCalendar(now);
calendar.add(Calendar.YEAR, defaultYearsOffset);
notAssignedDate = new Timestamp(calendar.getTimeInMillis());
}
try {
resultList = EntityQuery.use(delegator).from("OrderHeaderItemAndShipGroup")
.where("orderTypeId", "SALES_ORDER",
"oiStatusId", "ITEM_APPROVED",
"facilityId", facilityId)
.orderBy("orderId").queryList();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventFindError", locale));
}
for (GenericValue genericResult : resultList) {
String productId = genericResult.getString("productId");
BigDecimal reservedQuantity = genericResult.getBigDecimal("reservedQuantity");
BigDecimal shipGroupQuantity = genericResult.getBigDecimal("quantity");
BigDecimal cancelledQuantity = genericResult.getBigDecimal("cancelQuantity");
BigDecimal eventQuantityTmp = BigDecimal.ZERO;
if (UtilValidate.isNotEmpty(reservedQuantity)) {
eventQuantityTmp = reservedQuantity.negate();
} else {
if (UtilValidate.isNotEmpty(cancelledQuantity)) {
shipGroupQuantity = shipGroupQuantity.subtract(cancelledQuantity);
}
eventQuantityTmp = shipGroupQuantity.negate();
}
if (eventQuantityTmp.compareTo(BigDecimal.ZERO) == 0) {
continue;
}
// This is the order in which order dates are considered:
// OrderItemShipGroup.shipByDate
// OrderItemShipGroup.shipAfterDate
// OrderItem.shipBeforeDate
// OrderItem.shipAfterDate
// OrderItem.estimatedDeliveryDate
Timestamp requiredByDate = genericResult.getTimestamp("shipByDate");
if (UtilValidate.isEmpty(requiredByDate)) {
requiredByDate = genericResult.getTimestamp("shipAfterDate");
if (UtilValidate.isEmpty(requiredByDate)) {
requiredByDate = genericResult.getTimestamp("oiShipBeforeDate");
if (UtilValidate.isEmpty(requiredByDate)) {
requiredByDate = genericResult.getTimestamp("oiShipAfterDate");
if (UtilValidate.isEmpty(requiredByDate)) {
requiredByDate = genericResult.getTimestamp("oiEstimatedDeliveryDate");
if (requiredByDate == null) {
requiredByDate = notAssignedDate;
}
}
}
}
}
parameters = UtilMisc.toMap("mrpId", mrpId, "productId", productId, "eventDate", requiredByDate, "mrpEventTypeId", "SALES_ORDER_SHIP");
try {
InventoryEventPlannedServices.createOrUpdateMrpEvent(parameters, eventQuantityTmp, null,
genericResult.getString("orderId") + "-" + genericResult.getString("orderItemSeqId"), false, delegator);
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventProblemInitializing", UtilMisc.toMap(
"mrpEventTypeId", "SALES_ORDER_SHIP"), locale));
}
}
// ----------------------------------------
// Loads all the approved product requirements (po requirements)
// ----------------------------------------
try {
resultList = EntityQuery.use(delegator).from("Requirement")
.where("requirementTypeId", "PRODUCT_REQUIREMENT",
"statusId", "REQ_APPROVED",
"facilityId", facilityId)
.queryList();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventFindError", locale));
}
for (GenericValue genericResult : resultList) {
String productId = genericResult.getString("productId");
BigDecimal eventQuantityTmp = genericResult.getBigDecimal("quantity");
if (productId == null || eventQuantityTmp == null) {
continue;
}
Timestamp estimatedShipDate = genericResult.getTimestamp("requiredByDate");
if (estimatedShipDate == null) {
estimatedShipDate = now;
}
parameters = UtilMisc.toMap("mrpId", mrpId, "productId", productId, "eventDate", estimatedShipDate, "mrpEventTypeId", "PROD_REQ_RECP");
try {
InventoryEventPlannedServices.createOrUpdateMrpEvent(parameters, eventQuantityTmp, null, genericResult.getString("requirementId"),
false, delegator);
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventProblemInitializing", UtilMisc.toMap(
"mrpEventTypeId", "PROD_REQ_RECP"), locale));
}
}
// ----------------------------------------
// Loads all the approved purchase order items
// ----------------------------------------
String orderId = null;
GenericValue orderDeliverySchedule = null;
try {
List<GenericValue> facilityContactMechs = EntityQuery.use(delegator).from("FacilityContactMech")
.where("facilityId", facilityId)
.filterByDate().queryList();
List<String> facilityContactMechIds = EntityUtil.getFieldListFromEntityList(facilityContactMechs, "contactMechId", true);
resultList = EntityQuery.use(delegator)
.select("orderId", "orderItemSeqId", "productId", "quantity", "cancelQuantity", "oiEstimatedDeliveryDate")
.from("OrderHeaderItemAndShipGroup")
.where(EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "PURCHASE_ORDER"),
EntityCondition.makeCondition("oiStatusId", EntityOperator.EQUALS, "ITEM_APPROVED"),
EntityCondition.makeCondition("contactMechId", EntityOperator.IN, facilityContactMechIds))
.orderBy("orderDate")
.queryList();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventFindError", locale));
}
for (GenericValue genericResult : resultList) {
try {
String newOrderId = genericResult.getString("orderId");
if (!newOrderId.equals(orderId)) {
orderDeliverySchedule = null;
orderId = newOrderId;
orderDeliverySchedule = EntityQuery.use(delegator).from("OrderDeliverySchedule").where("orderId", orderId, "orderItemSeqId",
"_NA_").queryOne();
}
String productId = genericResult.getString("productId");
BigDecimal shipGroupQuantity = genericResult.getBigDecimal("quantity");
BigDecimal cancelledQuantity = genericResult.getBigDecimal("cancelQuantity");
if (UtilValidate.isEmpty(shipGroupQuantity)) {
shipGroupQuantity = BigDecimal.ZERO;
}
if (UtilValidate.isNotEmpty(cancelledQuantity)) {
shipGroupQuantity = shipGroupQuantity.subtract(cancelledQuantity);
}
try {
List<GenericValue> shipmentReceipts = EntityQuery.use(delegator).select("quantityAccepted", "quantityRejected").from(
"ShipmentReceipt").where("orderId", genericResult.getString("orderId"), "orderItemSeqId", genericResult.getString(
"orderItemSeqId")).queryList();
for (GenericValue shipmentReceipt : shipmentReceipts) {
shipGroupQuantity = shipGroupQuantity.subtract(shipmentReceipt.getBigDecimal("quantityAccepted"));
shipGroupQuantity = shipGroupQuantity.subtract(shipmentReceipt.getBigDecimal("quantityRejected"));
}
} catch (GenericEntityException e) {
Debug.logWarning(e, MODULE);
}
GenericValue orderItemDeliverySchedule = null;
orderItemDeliverySchedule = EntityQuery.use(delegator).from("OrderDeliverySchedule").where("orderId", orderId, "orderItemSeqId",
genericResult.getString("orderItemSeqId")).queryOne();
Timestamp estimatedShipDate = null;
if (orderItemDeliverySchedule != null && orderItemDeliverySchedule.get("estimatedReadyDate") != null) {
estimatedShipDate = orderItemDeliverySchedule.getTimestamp("estimatedReadyDate");
} else if (orderDeliverySchedule != null && orderDeliverySchedule.get("estimatedReadyDate") != null) {
estimatedShipDate = orderDeliverySchedule.getTimestamp("estimatedReadyDate");
} else {
estimatedShipDate = genericResult.getTimestamp("oiEstimatedDeliveryDate");
}
if (estimatedShipDate == null) {
estimatedShipDate = now;
}
parameters = UtilMisc.toMap("mrpId", mrpId, "productId", productId, "eventDate", estimatedShipDate, "mrpEventTypeId",
"PUR_ORDER_RECP");
InventoryEventPlannedServices.createOrUpdateMrpEvent(parameters, shipGroupQuantity, null,
genericResult.getString("orderId") + "-" + genericResult.getString("orderItemSeqId"), false, delegator);
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventProblemInitializing", UtilMisc.toMap(
"mrpEventTypeId", "PUR_ORDER_RECP"), locale));
}
}
// ----------------------------------------
// PRODUCTION Run: components
// ----------------------------------------
try {
resultList = EntityQuery.use(delegator).from("WorkEffortAndGoods")
.where("workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED",
"statusId", "WEGS_CREATED",
"facilityId", facilityId)
.queryList();
for (GenericValue genericResult : resultList) {
if ("PRUN_CLOSED".equals(genericResult.getString("currentStatusId"))
|| "PRUN_COMPLETED".equals(genericResult.getString("currentStatusId"))
|| "PRUN_CANCELLED".equals(genericResult.getString("currentStatusId"))) {
continue;
}
String productId = genericResult.getString("productId");
// get the inventory already consumed
BigDecimal consumedInventoryTotal = BigDecimal.ZERO;
List<GenericValue> consumedInventoryItems = EntityQuery.use(delegator).from("WorkEffortAndInventoryAssign")
.where("workEffortId", genericResult.get("workEffortId"), "productId", productId)
.queryList();
for (GenericValue consumedInventoryItem : consumedInventoryItems) {
consumedInventoryTotal = consumedInventoryTotal.add(consumedInventoryItem.getBigDecimal("quantity"));
}
BigDecimal eventQuantityTmp = consumedInventoryTotal.subtract(genericResult.getBigDecimal("estimatedQuantity"));
Timestamp estimatedShipDate = genericResult.getTimestamp("estimatedStartDate");
if (estimatedShipDate == null) {
estimatedShipDate = now;
}
parameters = UtilMisc.toMap("mrpId", mrpId, "productId", productId, "eventDate", estimatedShipDate, "mrpEventTypeId",
"MANUF_ORDER_REQ");
String eventName = (UtilValidate.isEmpty(genericResult.getString("workEffortParentId")) ? genericResult.getString("workEffortId")
: genericResult.getString("workEffortParentId") + "-" + genericResult.getString("workEffortId"));
InventoryEventPlannedServices.createOrUpdateMrpEvent(parameters, eventQuantityTmp, null, eventName, false, delegator);
}
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventProblemInitializing", UtilMisc.toMap(
"mrpEventTypeId", "MANUF_ORDER_REQ"), locale) + " " + e.getMessage());
}
// ----------------------------------------
// PRODUCTION Run: product produced
// ----------------------------------------
try {
resultList = EntityQuery.use(delegator).from("WorkEffortAndGoods")
.where("workEffortGoodStdTypeId", "PRUN_PROD_DELIV",
"statusId", "WEGS_CREATED",
"workEffortTypeId", "PROD_ORDER_HEADER",
"facilityId", facilityId)
.queryList();
for (GenericValue genericResult : resultList) {
if ("PRUN_CLOSED".equals(genericResult.getString("currentStatusId"))
|| "PRUN_COMPLETED".equals(genericResult.getString("currentStatusId"))
|| "PRUN_CANCELLED".equals(genericResult.getString("currentStatusId"))) {
continue;
}
BigDecimal qtyToProduce = genericResult.getBigDecimal("quantityToProduce");
if (qtyToProduce == null) {
qtyToProduce = BigDecimal.ZERO;
}
BigDecimal qtyProduced = genericResult.getBigDecimal("quantityProduced");
if (qtyProduced == null) {
qtyProduced = BigDecimal.ZERO;
}
if (qtyProduced.compareTo(qtyToProduce) >= 0) {
continue;
}
BigDecimal qtyDiff = qtyToProduce.subtract(qtyProduced);
String productId = genericResult.getString("productId");
BigDecimal eventQuantityTmp = qtyDiff;
Timestamp estimatedShipDate = genericResult.getTimestamp("estimatedCompletionDate");
if (estimatedShipDate == null) {
estimatedShipDate = now;
}
parameters = UtilMisc.toMap("mrpId", mrpId, "productId", productId, "eventDate", estimatedShipDate, "mrpEventTypeId",
"MANUF_ORDER_RECP");
InventoryEventPlannedServices.createOrUpdateMrpEvent(parameters, eventQuantityTmp, null, genericResult.getString("workEffortId"),
false, delegator);
}
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventProblemInitializing", UtilMisc.toMap(
"mrpEventTypeId", "MANUF_ORDER_RECP"), locale) + " " + e.getMessage());
}
// ----------------------------------------
// Products without upcoming events but that are already under minimum quantity in warehouse
// ----------------------------------------
try {
resultList = EntityQuery.use(delegator).from("ProductFacility")
.where("facilityId", facilityId)
.queryList();
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to retrieve ProductFacility records.", MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpCannotFindProductFacility", locale));
}
for (GenericValue genericResult : resultList) {
String productId = genericResult.getString("productId");
BigDecimal minimumStock = genericResult.getBigDecimal("minimumStock");
if (minimumStock == null) {
minimumStock = BigDecimal.ZERO;
}
try {
long numOfEvents = EntityQuery.use(delegator).from("MrpEvent")
.where("mrpId", mrpId, "productId", productId)
.queryCount();
if (numOfEvents > 0) {
continue;
}
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to count MrpEvent records.", MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpCannotCountRecords", locale));
}
BigDecimal qoh = findProductMrpQoh(mrpId, productId, facilityId, dispatcher, delegator);
if (qoh.compareTo(minimumStock) >= 0) {
continue;
}
parameters = UtilMisc.toMap("mrpId", mrpId, "productId", productId, "eventDate", now, "mrpEventTypeId", "REQUIRED_MRP");
try {
InventoryEventPlannedServices.createOrUpdateMrpEvent(parameters, BigDecimal.ZERO, null, null, false, delegator);
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventProblemInitializing", UtilMisc.toMap(
"mrpEventTypeId", "REQUIRED_MRP"), locale));
}
}
// ----------------------------------------
// SALES FORECASTS
// ----------------------------------------
GenericValue facility = null;
try {
facility = EntityQuery.use(delegator).from("Facility").where("facilityId", facilityId).queryOne();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventFindError", locale));
}
String partyId = (String) facility.get("ownerPartyId");
try {
resultList = EntityQuery.use(delegator).from("SalesForecast")
.where("organizationPartyId", partyId)
.queryList();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpCannotFindSalesForecasts", locale));
}
for (GenericValue genericResult : resultList) {
String customTimePeriodId = genericResult.getString("customTimePeriodId");
GenericValue customTimePeriod = null;
try {
customTimePeriod = EntityQuery.use(delegator).from("CustomTimePeriod").where("customTimePeriodId", customTimePeriodId).queryOne();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpCannotFindCustomTimePeriod", locale));
}
if (customTimePeriod != null) {
if (UtilValidate.isNotEmpty(customTimePeriod.getTimestamp("thruDate"))
&& customTimePeriod.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp())) {
continue;
} else {
List<GenericValue> salesForecastDetails = null;
try {
salesForecastDetails = EntityQuery.use(delegator).from("SalesForecastDetail")
.where("salesForecastId", genericResult.get("salesForecastId"))
.queryList();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpCannotFindSalesForecastDetails", locale));
}
for (GenericValue sfd : salesForecastDetails) {
String productId = sfd.getString("productId");
BigDecimal eventQuantityTmp = sfd.getBigDecimal("quantity");
if (productId == null || eventQuantityTmp == null) {
continue;
}
eventQuantityTmp = eventQuantityTmp.negate();
parameters = UtilMisc.toMap("mrpId", mrpId, "productId", productId, "eventDate", customTimePeriod.getTimestamp("fromDate"),
"mrpEventTypeId", "SALES_FORECAST");
try {
InventoryEventPlannedServices.createOrUpdateMrpEvent(parameters, eventQuantityTmp, null, sfd.getString(
"salesForecastDetailId"), false, delegator);
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingMrpEventProblemInitializing",
UtilMisc.toMap("mrpEventTypeId", "SALES_FORECAST"), locale));
}
}
}
}
}
Map<String, Object> result = new HashMap<>();
result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
Debug.logInfo("return from initMrpEvent", MODULE);
return result;
}