in applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java [190:1162]
public static Map<String, Object> createOrder(DispatchContext ctx, Map<String, ? extends Object> context) {
Delegator delegator = ctx.getDelegator();
LocalDispatcher dispatcher = ctx.getDispatcher();
Security security = ctx.getSecurity();
List<GenericValue> toBeStored = new LinkedList<>();
Locale locale = (Locale) context.get("locale");
Map<String, Object> successResult = ServiceUtil.returnSuccess();
GenericValue userLogin = (GenericValue) context.get("userLogin");
// get the order type
String orderTypeId = (String) context.get("orderTypeId");
String partyId = (String) context.get("partyId");
String billFromVendorPartyId = (String) context.get("billFromVendorPartyId");
// check security permissions for order:
// SALES ORDERS - if userLogin has ORDERMGR_SALES_CREATE or ORDERMGR_CREATE permission, or if it is same party as the partyId, or
// if it is an AGENT (sales rep) creating an order for his customer
// PURCHASE ORDERS - if there is a PURCHASE_ORDER permission
Map<String, Object> resultSecurity = new HashMap<>();
boolean hasPermission = OrderServices.hasPermission(orderTypeId, partyId, userLogin, "CREATE", security);
// final check - will pass if userLogin's partyId = partyId for order or if userLogin has ORDERMGR_CREATE permission
// jacopoc: what is the meaning of this code block? FIXME
if (!hasPermission) {
partyId = ServiceUtil.getPartyIdCheckSecurity(userLogin, security, context, resultSecurity, "ORDERMGR", "_CREATE");
if (!resultSecurity.isEmpty()) {
return resultSecurity;
}
}
// get the product store for the order, but it is required only for sales orders
String productStoreId = (String) context.get("productStoreId");
GenericValue productStore = null;
if (("SALES_ORDER".equals(orderTypeId)) && (UtilValidate.isNotEmpty(productStoreId))) {
try {
productStore = EntityQuery.use(delegator).from("ProductStore").where("productStoreId", productStoreId).cache().queryOne();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderErrorCouldNotFindProductStoreWithID", UtilMisc.toMap("productStoreId", productStoreId), locale) + e.toString());
}
}
// figure out if the order is immediately fulfilled based on product store settings
boolean isImmediatelyFulfilled = false;
if (productStore != null) {
isImmediatelyFulfilled = "Y".equals(productStore.getString("isImmediatelyFulfilled"));
}
successResult.put("orderTypeId", orderTypeId);
// lookup the order type entity
GenericValue orderType = null;
try {
orderType = EntityQuery.use(delegator).from("OrderType").where("orderTypeId", orderTypeId).cache().queryOne();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderErrorOrderTypeLookupFailed", locale) + e.toString());
}
// make sure we have a valid order type
if (orderType == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderErrorInvalidOrderTypeWithID", UtilMisc.toMap("orderTypeId", orderTypeId), locale));
}
// check to make sure we have something to order
List<GenericValue> orderItems = UtilGenerics.cast(context.get("orderItems"));
if (orderItems.size() < 1) {
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR, "items.none", locale));
}
// all this marketing pkg auto stuff is deprecated in favor of MARKETING_PKG_AUTO productTypeId and a BOM of MANUF_COMPONENT assocs
// these need to be retrieved now because they might be needed for exploding MARKETING_PKG_AUTO
List<GenericValue> orderAdjustments = UtilGenerics.cast(context.get("orderAdjustments"));
List<GenericValue> orderItemShipGroupInfo = UtilGenerics.cast(context.get("orderItemShipGroupInfo"));
List<GenericValue> orderItemPriceInfo = UtilGenerics.cast(context.get("orderItemPriceInfos"));
// check inventory and other things for each item
List<String> errorMessages = new LinkedList<>();
Map<String, BigDecimal> normalizedItemQuantities = new HashMap<>();
Map<String, String> normalizedItemNames = new HashMap<>();
Map<String, GenericValue> itemValuesBySeqId = new HashMap<>();
Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
// need to run through the items combining any cases where multiple lines refer to the
// same product so the inventory check will work correctly
// also count quantities ordered while going through the loop
for (GenericValue orderItem : orderItems) {
// start by putting it in the itemValuesById Map
itemValuesBySeqId.put(orderItem.getString("orderItemSeqId"), orderItem);
String currentProductId = orderItem.getString("productId");
if (currentProductId != null) {
// only normalize items with a product associated (ignore non-product items)
if (normalizedItemQuantities.get(currentProductId) == null) {
normalizedItemQuantities.put(currentProductId, orderItem.getBigDecimal("quantity"));
normalizedItemNames.put(currentProductId, orderItem.getString("itemDescription"));
} else {
BigDecimal currentQuantity = normalizedItemQuantities.get(currentProductId);
normalizedItemQuantities.put(currentProductId, currentQuantity.add(orderItem.getBigDecimal("quantity")));
}
try {
// count product ordered quantities
// run this synchronously so it will run in the same transaction
Map<String, Object> result = dispatcher.runSync("countProductQuantityOrdered", UtilMisc.<String, Object>toMap("productId",
currentProductId, "quantity", orderItem.getBigDecimal("quantity"), "userLogin", userLogin));
if (ServiceUtil.isError(result)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
}
} catch (GenericServiceException e1) {
Debug.logError(e1, "Error calling countProductQuantityOrdered service", MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderErrorCallingCountProductQuantityOrderedService", locale) + e1.toString());
}
}
}
if (!"PURCHASE_ORDER".equals(orderTypeId) && productStoreId == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderErrorTheProductStoreIdCanOnlyBeNullForPurchaseOrders", locale));
}
Timestamp orderDate = (Timestamp) context.get("orderDate");
for (String currentProductId : normalizedItemQuantities.keySet()) {
// lookup the product entity for each normalized item; error on products not found
BigDecimal currentQuantity = normalizedItemQuantities.get(currentProductId);
String itemName = normalizedItemNames.get(currentProductId);
GenericValue product = null;
try {
product = EntityQuery.use(delegator).from("Product").where("productId", currentProductId).cache().queryOne();
} catch (GenericEntityException e) {
String errMsg = UtilProperties.getMessage(RES_ERROR, "product.not_found", new Object[]{currentProductId}, locale);
Debug.logError(e, errMsg, MODULE);
errorMessages.add(errMsg);
continue;
}
if (product == null) {
String errMsg = UtilProperties.getMessage(RES_ERROR, "product.not_found", new Object[]{currentProductId}, locale);
Debug.logError(errMsg, MODULE);
errorMessages.add(errMsg);
continue;
}
if ("SALES_ORDER".equals(orderTypeId)) {
// check to see if introductionDate hasn't passed yet
if (product.get("introductionDate") != null && nowTimestamp.before(product.getTimestamp("introductionDate"))) {
String excMsg = UtilProperties.getMessage(RES_ERROR, "product.not_yet_for_sale",
new Object[]{getProductName(product, itemName), product.getString("productId")}, locale);
Debug.logWarning(excMsg, MODULE);
errorMessages.add(excMsg);
continue;
}
}
if ("SALES_ORDER".equals(orderTypeId)) {
boolean salesDiscontinuationFlag = false;
// When past orders are imported, they should be imported even if sales discontinuation date is in the past but if the order date
// was before it
if (orderDate != null && product.get("salesDiscontinuationDate") != null) {
salesDiscontinuationFlag =
orderDate.after(product.getTimestamp("salesDiscontinuationDate")) && nowTimestamp.after(product.getTimestamp(
"salesDiscontinuationDate"));
} else if (product.get("salesDiscontinuationDate") != null) {
salesDiscontinuationFlag = nowTimestamp.after(product.getTimestamp("salesDiscontinuationDate"));
}
// check to see if salesDiscontinuationDate has passed
if (salesDiscontinuationFlag) {
String excMsg = UtilProperties.getMessage(RES_ERROR, "product.no_longer_for_sale",
new Object[]{getProductName(product, itemName), product.getString("productId")}, locale);
Debug.logWarning(excMsg, MODULE);
errorMessages.add(excMsg);
continue;
}
}
if ("SALES_ORDER".equals(orderTypeId)) {
// check to see if we have inventory available
try {
Map<String, Object> invReqResult = dispatcher.runSync("isStoreInventoryAvailableOrNotRequired", UtilMisc.toMap("productStoreId",
productStoreId, "productId", product.get("productId"), "product", product, "quantity", currentQuantity));
if (ServiceUtil.isError(invReqResult)) {
errorMessages.add(ServiceUtil.getErrorMessage(invReqResult));
List<String> errMsgList = UtilGenerics.cast(invReqResult.get(ModelService.ERROR_MESSAGE_LIST));
errorMessages.addAll(errMsgList);
} else if (!"Y".equals(invReqResult.get("availableOrNotRequired"))) {
String invErrMsg = UtilProperties.getMessage(RES_ERROR, "product.out_of_stock",
new Object[]{getProductName(product, itemName), currentProductId}, locale);
Debug.logWarning(invErrMsg, MODULE);
errorMessages.add(invErrMsg);
continue;
}
} catch (GenericServiceException e) {
String errMsg = "Fatal error calling inventory checking services: " + e.toString();
Debug.logError(e, errMsg, MODULE);
errorMessages.add(errMsg);
}
}
}
// add the fixedAsset id to the workefforts map by obtaining the fixed Asset number from the FixedAssetProduct table
List<GenericValue> workEfforts = UtilGenerics.cast(context.get("workEfforts")); // is an optional parameter from this service but mandatory
// for rental items
for (GenericValue orderItem : orderItems) {
if ("RENTAL_ORDER_ITEM".equals(orderItem.getString("orderItemTypeId"))) {
// check to see if workefforts are available for this order type.
if (UtilValidate.isEmpty(workEfforts)) {
String errMsg = "Work Efforts missing for ordertype RENTAL_ORDER_ITEM " + "Product: " + orderItem.getString("productId");
Debug.logError(errMsg, MODULE);
errorMessages.add(errMsg);
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderRentalOrderItems", locale));
}
for (GenericValue workEffort : workEfforts) {
// find the related workEffortItem (workEffortId = orderSeqId)
// create the entity maps required.
if (workEffort.getString("workEffortId").equals(orderItem.getString("orderItemSeqId"))) {
List<GenericValue> selFixedAssetProduct = null;
try {
selFixedAssetProduct = EntityQuery.use(delegator).from("FixedAssetProduct").where("productId", orderItem.getString(
"productId"), "fixedAssetProductTypeId", "FAPT_USE").filterByDate(nowTimestamp, "fromDate",
"thruDate").queryList();
} catch (GenericEntityException e) {
String excMsg = "Could not find related Fixed Asset for the product: " + orderItem.getString("productId");
Debug.logError(excMsg, MODULE);
errorMessages.add(excMsg);
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderCouldNotFindRelatedFixedAssetForTheProduct", UtilMisc.toMap("productId",
orderItem.getString("productId")), locale));
}
if (UtilValidate.isNotEmpty(selFixedAssetProduct)) {
Iterator<GenericValue> firstOne = selFixedAssetProduct.iterator();
if (firstOne.hasNext()) {
GenericValue fixedAssetProduct = delegator.makeValue("FixedAssetProduct");
fixedAssetProduct = firstOne.next();
workEffort.set("fixedAssetId", fixedAssetProduct.get("fixedAssetId"));
workEffort.set("quantityToProduce", orderItem.get("quantity")); // have quantity easy available later...
workEffort.set("createdByUserLogin", userLogin.get("userLoginId"));
}
}
break; // item found, so go to next orderitem.
}
}
}
}
if (!errorMessages.isEmpty()) {
return ServiceUtil.returnError(errorMessages);
}
// the inital status for ALL order types
String initialStatus = "ORDER_CREATED";
successResult.put("statusId", initialStatus);
// create the order object
String orderId = (String) context.get("orderId");
String orgPartyId = null;
if (productStore != null) {
orgPartyId = productStore.getString("payToPartyId");
} else if (billFromVendorPartyId != null) {
orgPartyId = billFromVendorPartyId;
}
if (UtilValidate.isNotEmpty(orgPartyId)) {
Map<String, Object> getNextOrderIdContext = new HashMap<>();
getNextOrderIdContext.putAll(context);
getNextOrderIdContext.put("partyId", orgPartyId);
getNextOrderIdContext.put("userLogin", userLogin);
if (("SALES_ORDER".equals(orderTypeId)) || (productStoreId != null)) {
getNextOrderIdContext.put("productStoreId", productStoreId);
}
if (UtilValidate.isEmpty(orderId)) {
try {
getNextOrderIdContext = ctx.makeValidContext("getNextOrderId", ModelService.IN_PARAM, getNextOrderIdContext);
Map<String, Object> getNextOrderIdResult = dispatcher.runSync("getNextOrderId", getNextOrderIdContext);
if (ServiceUtil.isError(getNextOrderIdResult)) {
String errMsg = UtilProperties.getMessage(RES_ERROR,
"OrderErrorGettingNextOrderIdWhileCreatingOrder", locale);
return ServiceUtil.returnError(errMsg);
}
orderId = (String) getNextOrderIdResult.get("orderId");
} catch (GenericServiceException e) {
String errMsg = UtilProperties.getMessage(RES_ERROR,
"OrderCaughtGenericServiceExceptionWhileGettingOrderId", locale);
Debug.logError(e, errMsg, MODULE);
return ServiceUtil.returnError(errMsg);
}
}
}
if (UtilValidate.isEmpty(orderId)) {
// for purchase orders or when other orderId generation fails, a product store id should not be required to make an order
orderId = delegator.getNextSeqId("OrderHeader");
}
String billingAccountId = (String) context.get("billingAccountId");
if (orderDate == null) {
orderDate = nowTimestamp;
}
Map<String, Object> orderHeaderMap = UtilMisc.<String, Object>toMap("orderId", orderId, "orderTypeId", orderTypeId,
"orderDate", orderDate, "entryDate", nowTimestamp,
"statusId", initialStatus, "billingAccountId", billingAccountId);
orderHeaderMap.put("orderName", context.get("orderName"));
orderHeaderMap.put("agreementId", context.get("agreementId"));
if (isImmediatelyFulfilled) {
// also flag this order as needing inventory issuance so that when it is set to complete it will be issued immediately
// (needsInventoryIssuance = Y)
orderHeaderMap.put("needsInventoryIssuance", "Y");
}
GenericValue orderHeader = delegator.makeValue("OrderHeader", orderHeaderMap);
// determine the sales channel
String salesChannelEnumId = (String) context.get("salesChannelEnumId");
if ((salesChannelEnumId == null) || "UNKNWN_SALES_CHANNEL".equals(salesChannelEnumId)) {
// try the default store sales channel
if ("SALES_ORDER".equals(orderTypeId) && (productStore != null)) {
salesChannelEnumId = productStore.getString("defaultSalesChannelEnumId");
}
// if there's still no channel, set to unknown channel
if (salesChannelEnumId == null) {
salesChannelEnumId = "UNKNWN_SALES_CHANNEL";
}
}
orderHeader.set("salesChannelEnumId", salesChannelEnumId);
if (context.get("currencyUom") != null) {
orderHeader.set("currencyUom", context.get("currencyUom"));
}
if (context.get("firstAttemptOrderId") != null) {
orderHeader.set("firstAttemptOrderId", context.get("firstAttemptOrderId"));
}
if (context.get("grandTotal") != null) {
orderHeader.set("grandTotal", context.get("grandTotal"));
}
if (UtilValidate.isNotEmpty(context.get("visitId"))) {
orderHeader.set("visitId", context.get("visitId"));
}
if (UtilValidate.isNotEmpty(context.get("internalCode"))) {
orderHeader.set("internalCode", context.get("internalCode"));
}
if (UtilValidate.isNotEmpty(context.get("externalId"))) {
orderHeader.set("externalId", context.get("externalId"));
}
if (UtilValidate.isNotEmpty(context.get("originFacilityId"))) {
orderHeader.set("originFacilityId", context.get("originFacilityId"));
}
if (UtilValidate.isNotEmpty(context.get("productStoreId"))) {
orderHeader.set("productStoreId", context.get("productStoreId"));
}
if (UtilValidate.isNotEmpty(context.get("transactionId"))) {
orderHeader.set("transactionId", context.get("transactionId"));
}
if (UtilValidate.isNotEmpty(context.get("terminalId"))) {
orderHeader.set("terminalId", context.get("terminalId"));
}
if (UtilValidate.isNotEmpty(context.get("autoOrderShoppingListId"))) {
orderHeader.set("autoOrderShoppingListId", context.get("autoOrderShoppingListId"));
}
if (UtilValidate.isNotEmpty(context.get("webSiteId"))) {
orderHeader.set("webSiteId", context.get("webSiteId"));
}
if (userLogin != null && userLogin.get("userLoginId") != null) {
orderHeader.set("createdBy", userLogin.getString("userLoginId"));
}
if (UtilValidate.isNotEmpty(context.get("isRushOrder"))) {
orderHeader.set("isRushOrder", context.get("isRushOrder"));
}
if (UtilValidate.isNotEmpty(context.get("priority"))) {
orderHeader.set("priority", context.get("priority"));
}
String invoicePerShipment = EntityUtilProperties.getPropertyValue("accounting", "create.invoice.per.shipment", delegator);
if (UtilValidate.isNotEmpty(invoicePerShipment)) {
orderHeader.set("invoicePerShipment", invoicePerShipment);
}
// first try to create the OrderHeader; if this does not fail, continue.
try {
delegator.create(orderHeader);
} catch (GenericEntityException e) {
Debug.logError(e, "Cannot create OrderHeader entity; problems with insert", MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderOrderCreationFailedPleaseNotifyCustomerService", locale));
}
// create the order status record
String orderStatusSeqId = delegator.getNextSeqId("OrderStatus");
GenericValue orderStatus = delegator.makeValue("OrderStatus", UtilMisc.toMap("orderStatusId", orderStatusSeqId));
orderStatus.set("orderId", orderId);
orderStatus.set("statusId", orderHeader.getString("statusId"));
orderStatus.set("statusDatetime", nowTimestamp);
orderStatus.set("statusUserLogin", userLogin.getString("userLoginId"));
toBeStored.add(orderStatus);
// before processing orderItems process orderItemGroups so that they'll be in place for the foreign keys and what not
List<GenericValue> orderItemGroups = UtilGenerics.cast(context.get("orderItemGroups"));
if (UtilValidate.isNotEmpty(orderItemGroups)) {
for (GenericValue orderItemGroup : orderItemGroups) {
orderItemGroup.set("orderId", orderId);
toBeStored.add(orderItemGroup);
}
}
// set the order items
for (GenericValue orderItem : orderItems) {
orderItem.set("orderId", orderId);
toBeStored.add(orderItem);
// create the item status record
String itemStatusId = delegator.getNextSeqId("OrderStatus");
GenericValue itemStatus = delegator.makeValue("OrderStatus", UtilMisc.toMap("orderStatusId", itemStatusId));
itemStatus.put("statusId", orderItem.get("statusId"));
itemStatus.put("orderId", orderId);
itemStatus.put("orderItemSeqId", orderItem.get("orderItemSeqId"));
itemStatus.put("statusDatetime", nowTimestamp);
itemStatus.set("statusUserLogin", userLogin.getString("userLoginId"));
toBeStored.add(itemStatus);
}
// set the order attributes
List<GenericValue> orderAttributes = UtilGenerics.cast(context.get("orderAttributes"));
if (UtilValidate.isNotEmpty(orderAttributes)) {
for (GenericValue oatt : orderAttributes) {
oatt.set("orderId", orderId);
toBeStored.add(oatt);
}
}
// set the order item attributes
List<GenericValue> orderItemAttributes = UtilGenerics.cast(context.get("orderItemAttributes"));
if (UtilValidate.isNotEmpty(orderItemAttributes)) {
for (GenericValue oiatt : orderItemAttributes) {
oiatt.set("orderId", orderId);
toBeStored.add(oiatt);
}
}
// create the order internal notes
List<String> orderInternalNotes = UtilGenerics.cast(context.get("orderInternalNotes"));
if (UtilValidate.isNotEmpty(orderInternalNotes)) {
for (String orderInternalNote : orderInternalNotes) {
try {
Map<String, Object> noteOutputMap = dispatcher.runSync("createOrderNote", UtilMisc.<String, Object>toMap("orderId", orderId,
"internalNote", "Y",
"note", orderInternalNote,
"userLogin", userLogin));
if (ServiceUtil.isError(noteOutputMap)) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE,
"OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", ""), locale),
null, null, noteOutputMap);
}
} catch (GenericServiceException e) {
Debug.logError(e, "Error creating internal notes while creating order: " + e.toString(), MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE,
"OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", e.toString()), locale));
}
}
}
// create the order public notes
List<String> orderNotes = UtilGenerics.cast(context.get("orderNotes"));
if (UtilValidate.isNotEmpty(orderNotes)) {
for (String orderNote : orderNotes) {
try {
Map<String, Object> noteOutputMap = dispatcher.runSync("createOrderNote", UtilMisc.<String, Object>toMap("orderId", orderId,
"internalNote", "N",
"note", orderNote,
"userLogin", userLogin));
if (ServiceUtil.isError(noteOutputMap)) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE,
"OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", ""), locale),
null, null, noteOutputMap);
}
} catch (GenericServiceException e) {
Debug.logError(e, "Error creating notes while creating order: " + e.toString(), MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE,
"OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", e.toString()), locale));
}
}
}
// create the workeffort records
// and connect them with the orderitem over the WorkOrderItemFulfillment
// create also the techData calendars to keep track of availability of the fixed asset.
if (UtilValidate.isNotEmpty(workEfforts)) {
List<GenericValue> tempList = new LinkedList<>();
for (GenericValue workEffort : workEfforts) {
// create the entity maps required.
GenericValue workOrderItemFulfillment = delegator.makeValue("WorkOrderItemFulfillment");
// find fixed asset supplied on the workeffort map
GenericValue fixedAsset = null;
Debug.logInfo("find the fixedAsset", MODULE);
try {
fixedAsset = EntityQuery.use(delegator).from("FixedAsset").where("fixedAssetId", workEffort.get("fixedAssetId")).queryOne();
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderFixedAssetNotFoundFixedAssetId",
UtilMisc.toMap("fixedAssetId", workEffort.get("fixedAssetId")), locale));
}
if (fixedAsset == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderFixedAssetNotFoundFixedAssetId",
UtilMisc.toMap("fixedAssetId", workEffort.get("fixedAssetId")), locale));
}
// see if this fixed asset has a calendar, when no create one and attach to fixed asset
Debug.logInfo("find the techdatacalendar", MODULE);
GenericValue techDataCalendar = null;
try {
techDataCalendar = fixedAsset.getRelatedOne("TechDataCalendar", false);
} catch (GenericEntityException e) {
Debug.logInfo("TechData calendar does not exist yet so create for fixedAsset: " + fixedAsset.get("fixedAssetId"), MODULE);
}
if (techDataCalendar == null) {
for (GenericValue currentValue : tempList) {
if ("FixedAsset".equals(currentValue.getEntityName()) && currentValue.getString("fixedAssetId")
.equals(workEffort.getString("fixedAssetId"))) {
fixedAsset = currentValue;
break;
}
}
for (GenericValue currentValue : tempList) {
if ("TechDataCalendar".equals(currentValue.getEntityName()) && currentValue.getString("calendarId")
.equals(fixedAsset.getString("calendarId"))) {
techDataCalendar = currentValue;
break;
}
}
}
if (techDataCalendar == null) {
techDataCalendar = delegator.makeValue("TechDataCalendar");
Debug.logInfo("create techdata calendar because it does not exist", MODULE);
String calendarId = delegator.getNextSeqId("TechDataCalendar");
techDataCalendar.set("calendarId", calendarId);
tempList.add(techDataCalendar);
Debug.logInfo("update fixed Asset", MODULE);
fixedAsset.set("calendarId", calendarId);
tempList.add(fixedAsset);
}
// then create the workEffort and the workOrderItemFulfillment to connect to the order and orderItem
workOrderItemFulfillment.set("orderItemSeqId", workEffort.get("workEffortId").toString()); // orderItemSeqNo is stored here so save
// first
// workeffort
String workEffortId = delegator.getNextSeqId("WorkEffort"); // find next available workEffortId
workEffort.set("workEffortId", workEffortId);
workEffort.set("workEffortTypeId", "ASSET_USAGE");
workEffort.set("currentStatusId", "_NA_"); // a lot of workefforts selection services expect a value here....
toBeStored.add(workEffort); // store workeffort before workOrderItemFulfillment because of workEffortId key constraint
// workOrderItemFulfillment
workOrderItemFulfillment.set("workEffortId", workEffortId);
workOrderItemFulfillment.set("orderId", orderId);
toBeStored.add(workOrderItemFulfillment);
// now create the TechDataExcDay, when they do not exist, create otherwise update the capacity values
// please note that calendarId is the same for (TechData)Calendar, CalendarExcDay and CalendarExWeek
Timestamp estimatedStartDate = workEffort.getTimestamp("estimatedStartDate");
Timestamp estimatedCompletionDate = workEffort.getTimestamp("estimatedCompletionDate");
long dayCount = (estimatedCompletionDate.getTime() - estimatedStartDate.getTime()) / 86400000;
while (--dayCount >= 0) {
GenericValue techDataCalendarExcDay = null;
// find an existing Day exception record
Timestamp exceptionDateStartTime = UtilDateTime.getDayStart(new Timestamp(estimatedStartDate.getTime()), (int) dayCount);
try {
techDataCalendarExcDay = EntityQuery.use(delegator).from("TechDataCalendarExcDay").where("calendarId", fixedAsset.get(
"calendarId"), "exceptionDateStartTime", exceptionDateStartTime).queryOne();
} catch (GenericEntityException e) {
Debug.logInfo(" techData excday record not found so creating........", MODULE);
}
if (techDataCalendarExcDay == null) {
for (GenericValue currentValue : tempList) {
if ("TechDataCalendarExcDay".equals(currentValue.getEntityName())
&& currentValue.getString("calendarId").equals(fixedAsset.getString("calendarId"))
&& currentValue.getTimestamp("exceptionDateStartTime").equals(exceptionDateStartTime)) {
techDataCalendarExcDay = currentValue;
break;
}
}
}
if (techDataCalendarExcDay == null) {
techDataCalendarExcDay = delegator.makeValue("TechDataCalendarExcDay");
techDataCalendarExcDay.set("calendarId", fixedAsset.get("calendarId"));
techDataCalendarExcDay.set("exceptionDateStartTime", exceptionDateStartTime);
techDataCalendarExcDay.set("usedCapacity", BigDecimal.ZERO); // initialise to zero
techDataCalendarExcDay.set("exceptionCapacity", fixedAsset.getBigDecimal("productionCapacity"));
}
// add the quantity to the quantity on the date record
BigDecimal newUsedCapacity = techDataCalendarExcDay.getBigDecimal("usedCapacity").add(workEffort.getBigDecimal(
"quantityToProduce"));
// check to see if the requested quantity is available on the requested day but only when the maximum capacity is set on the
// fixed asset
if (fixedAsset.get("productionCapacity") != null) {
if (newUsedCapacity.compareTo(techDataCalendarExcDay.getBigDecimal("exceptionCapacity")) > 0) {
String errMsg = UtilProperties.getMessage(RES_ERROR, "OrderFixedAssetSoldOut", UtilMisc.toMap("fixedAssetId",
workEffort.get("fixedAssetId"), "exceptionDateStartTime",
techDataCalendarExcDay.getString("exceptionDateStartTime")), locale);
Debug.logError(errMsg, MODULE);
errorMessages.add(errMsg);
continue;
}
}
techDataCalendarExcDay.set("usedCapacity", newUsedCapacity);
tempList.add(techDataCalendarExcDay);
}
}
if (!tempList.isEmpty()) {
toBeStored.addAll(tempList);
}
}
if (!errorMessages.isEmpty()) {
return ServiceUtil.returnError(errorMessages);
}
// set the orderId on all adjustments; this list will include order and
// item adjustments...
if (UtilValidate.isNotEmpty(orderAdjustments)) {
for (GenericValue orderAdjustment : orderAdjustments) {
try {
orderAdjustment.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment"));
} catch (IllegalArgumentException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderErrorCouldNotGetNextSequenceIdForOrderAdjustmentCannotCreateOrder", locale));
}
orderAdjustment.set("orderId", orderId);
orderAdjustment.set("createdDate", UtilDateTime.nowTimestamp());
orderAdjustment.set("createdByUserLogin", userLogin.getString("userLoginId"));
if (UtilValidate.isEmpty(orderAdjustment.get("orderItemSeqId"))) {
orderAdjustment.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA);
}
if (UtilValidate.isEmpty(orderAdjustment.get("shipGroupSeqId"))) {
orderAdjustment.set("shipGroupSeqId", DataModelConstants.SEQ_ID_NA);
}
toBeStored.add(orderAdjustment);
}
}
// set the order contact mechs
List<GenericValue> orderContactMechs = UtilGenerics.cast(context.get("orderContactMechs"));
if (UtilValidate.isNotEmpty(orderContactMechs)) {
for (GenericValue ocm : orderContactMechs) {
ocm.set("orderId", orderId);
toBeStored.add(ocm);
}
}
// set the order item contact mechs
List<GenericValue> orderItemContactMechs = UtilGenerics.cast(context.get("orderItemContactMechs"));
if (UtilValidate.isNotEmpty(orderItemContactMechs)) {
for (GenericValue oicm : orderItemContactMechs) {
oicm.set("orderId", orderId);
toBeStored.add(oicm);
}
}
// set the order item ship groups
List<String> dropShipGroupIds = new LinkedList<>(); // this list will contain the ids of all the ship groups for drop shipments (no
// reservations)
if (UtilValidate.isNotEmpty(orderItemShipGroupInfo)) {
for (GenericValue valueObj : orderItemShipGroupInfo) {
valueObj.set("orderId", orderId);
if ("OrderItemShipGroup".equals(valueObj.getEntityName())) {
// ship group
if (valueObj.get("carrierRoleTypeId") == null) {
valueObj.set("carrierRoleTypeId", "CARRIER");
}
if (UtilValidate.isNotEmpty(valueObj.getString("supplierPartyId"))) {
dropShipGroupIds.add(valueObj.getString("shipGroupSeqId"));
}
} else if ("OrderAdjustment".equals(valueObj.getEntityName())) {
// shipping / tax adjustment(s)
if (UtilValidate.isEmpty(valueObj.get("orderItemSeqId"))) {
valueObj.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA);
}
valueObj.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment"));
valueObj.set("createdDate", UtilDateTime.nowTimestamp());
valueObj.set("createdByUserLogin", userLogin.getString("userLoginId"));
}
toBeStored.add(valueObj);
}
}
// set the additional party roles
Map<String, List<String>> additionalPartyRole = UtilGenerics.cast(context.get("orderAdditionalPartyRoleMap"));
if (additionalPartyRole != null) {
for (Map.Entry<String, List<String>> entry : additionalPartyRole.entrySet()) {
String additionalRoleTypeId = entry.getKey();
List<String> parties = entry.getValue();
if (parties != null) {
for (String additionalPartyId : parties) {
toBeStored.add(delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", additionalPartyId, "roleTypeId",
additionalRoleTypeId)));
toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", additionalPartyId,
"roleTypeId", additionalRoleTypeId)));
}
}
}
}
// set the item survey responses
List<GenericValue> surveyResponses = UtilGenerics.cast(context.get("orderItemSurveyResponses"));
if (UtilValidate.isNotEmpty(surveyResponses)) {
for (GenericValue surveyResponse : surveyResponses) {
surveyResponse.set("orderId", orderId);
toBeStored.add(surveyResponse);
}
}
// set the item price info; NOTE: this must be after the orderItems are stored for referential integrity
if (UtilValidate.isNotEmpty(orderItemPriceInfo)) {
for (GenericValue oipi : orderItemPriceInfo) {
try {
oipi.set("orderItemPriceInfoId", delegator.getNextSeqId("OrderItemPriceInfo"));
} catch (IllegalArgumentException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderErrorCouldNotGetNextSequenceIdForOrderItemPriceInfoCannotCreateOrder", locale));
}
oipi.set("orderId", orderId);
toBeStored.add(oipi);
}
}
// set the item associations
List<GenericValue> orderItemAssociations = UtilGenerics.cast(context.get("orderItemAssociations"));
if (UtilValidate.isNotEmpty(orderItemAssociations)) {
for (GenericValue orderItemAssociation : orderItemAssociations) {
if (orderItemAssociation.get("toOrderId") == null) {
orderItemAssociation.set("toOrderId", orderId);
} else if (orderItemAssociation.get("orderId") == null) {
orderItemAssociation.set("orderId", orderId);
}
toBeStored.add(orderItemAssociation);
}
}
// store the orderProductPromoUseInfos
List<GenericValue> orderProductPromoUses = UtilGenerics.cast(context.get("orderProductPromoUses"));
if (UtilValidate.isNotEmpty(orderProductPromoUses)) {
for (GenericValue productPromoUse : orderProductPromoUses) {
productPromoUse.set("orderId", orderId);
toBeStored.add(productPromoUse);
}
}
// store the orderProductPromoCodes
Set<String> orderProductPromoCodes = UtilGenerics.cast(context.get("orderProductPromoCodes"));
if (UtilValidate.isNotEmpty(orderProductPromoCodes)) {
for (String productPromoCodeId : orderProductPromoCodes) {
GenericValue orderProductPromoCode = delegator.makeValue("OrderProductPromoCode");
orderProductPromoCode.set("orderId", orderId);
orderProductPromoCode.set("productPromoCodeId", productPromoCodeId);
toBeStored.add(orderProductPromoCode);
}
}
// see the attributeRoleMap definition near the top of this file for attribute-role mappings
Map<String, String> attributeRoleMap = SALES_ROLE_MAP;
if ("PURCHASE_ORDER".equals(orderTypeId)) {
attributeRoleMap = PURCHASE_ROLE_MAP;
}
for (Map.Entry<String, String> attributeRoleEntry : attributeRoleMap.entrySet()) {
if (UtilValidate.isNotEmpty(context.get(attributeRoleEntry.getKey()))) {
// make sure the party is in the role before adding
toBeStored.add(delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", context.get(attributeRoleEntry.getKey()), "roleTypeId",
attributeRoleEntry.getValue())));
toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId",
context.get(attributeRoleEntry.getKey()), "roleTypeId", attributeRoleEntry.getValue())));
}
}
// set the affiliate -- This is going to be removed...
String affiliateId = (String) context.get("affiliateId");
if (UtilValidate.isNotEmpty(affiliateId)) {
toBeStored.add(delegator.makeValue("OrderRole",
UtilMisc.toMap("orderId", orderId, "partyId", affiliateId, "roleTypeId", "AFFILIATE")));
}
// set the distributor
String distributorId = (String) context.get("distributorId");
if (UtilValidate.isNotEmpty(distributorId)) {
toBeStored.add(delegator.makeValue("OrderRole",
UtilMisc.toMap("orderId", orderId, "partyId", distributorId, "roleTypeId", "DISTRIBUTOR")));
}
// find all parties in role VENDOR associated with WebSite OR ProductStore (where WebSite overrides, if specified), associated first valid
// with the Order
if (UtilValidate.isNotEmpty(context.get("productStoreId"))) {
try {
GenericValue productStoreRole = EntityQuery.use(delegator).from("ProductStoreRole")
.where("roleTypeId", "VENDOR", "productStoreId", context.get("productStoreId"))
.orderBy("-fromDate")
.filterByDate()
.queryFirst();
if (productStoreRole != null) {
toBeStored.add(delegator.makeValue("OrderRole",
UtilMisc.toMap("orderId", orderId, "partyId", productStoreRole.get("partyId"), "roleTypeId", "VENDOR")));
}
} catch (GenericEntityException e) {
Debug.logError(e, "Error looking up Vendor for the current Product Store", MODULE);
}
}
if (UtilValidate.isNotEmpty(context.get("webSiteId"))) {
try {
GenericValue webSiteRole = EntityQuery.use(delegator).from("WebSiteRole").where("roleTypeId", "VENDOR", "webSiteId", context.get(
"webSiteId")).orderBy("-fromDate").filterByDate().queryFirst();
if (webSiteRole != null) {
toBeStored.add(delegator.makeValue("OrderRole",
UtilMisc.toMap("orderId", orderId, "partyId", webSiteRole.get("partyId"), "roleTypeId", "VENDOR")));
}
} catch (GenericEntityException e) {
Debug.logError(e, "Error looking up Vendor for the current Web Site", MODULE);
}
}
// set the order payment info
List<GenericValue> orderPaymentInfos = UtilGenerics.cast(context.get("orderPaymentInfo"));
if (UtilValidate.isNotEmpty(orderPaymentInfos)) {
for (GenericValue valueObj : orderPaymentInfos) {
valueObj.set("orderId", orderId);
if ("OrderPaymentPreference".equals(valueObj.getEntityName())) {
if (valueObj.get("orderPaymentPreferenceId") == null) {
valueObj.set("orderPaymentPreferenceId", delegator.getNextSeqId("OrderPaymentPreference"));
valueObj.set("createdDate", UtilDateTime.nowTimestamp());
valueObj.set("createdByUserLogin", userLogin.getString("userLoginId"));
}
if (valueObj.get("statusId") == null) {
valueObj.set("statusId", "PAYMENT_NOT_RECEIVED");
}
}
toBeStored.add(valueObj);
}
}
// store the trackingCodeOrder entities
List<GenericValue> trackingCodeOrders = UtilGenerics.cast(context.get("trackingCodeOrders"));
if (UtilValidate.isNotEmpty(trackingCodeOrders)) {
for (GenericValue trackingCodeOrder : trackingCodeOrders) {
trackingCodeOrder.set("orderId", orderId);
toBeStored.add(trackingCodeOrder);
}
}
// store the OrderTerm entities
List<GenericValue> orderTerms = UtilGenerics.cast(context.get("orderTerms"));
if (UtilValidate.isNotEmpty(orderTerms)) {
for (GenericValue orderTerm : orderTerms) {
orderTerm.set("orderId", orderId);
if (orderTerm.get("orderItemSeqId") == null) {
orderTerm.set("orderItemSeqId", "_NA_");
}
toBeStored.add(orderTerm);
}
}
// if a workEffortId is passed, then prepare a OrderHeaderWorkEffort value
String workEffortId = (String) context.get("workEffortId");
if (UtilValidate.isNotEmpty(workEffortId)) {
GenericValue orderHeaderWorkEffort = delegator.makeValue("OrderHeaderWorkEffort");
orderHeaderWorkEffort.set("orderId", orderId);
orderHeaderWorkEffort.set("workEffortId", workEffortId);
toBeStored.add(orderHeaderWorkEffort);
}
try {
// store line items, etc so that they will be there for the foreign key checks
delegator.storeAll(toBeStored);
List<String> resErrorMessages = new LinkedList<>();
GenericValue permUserLogin = EntityQuery.use(delegator).from("UserLogin").where("userLoginId", "system").cache().queryOne();
// add a product service to inventory
if (UtilValidate.isNotEmpty(orderItems)) {
for (GenericValue orderItem : orderItems) {
String productId = (String) orderItem.get("productId");
GenericValue product = delegator.getRelatedOne("Product", orderItem, false);
if (product != null && ("SERVICE_PRODUCT".equals(product.get("productTypeId")) || "AGGREGATEDSERV_CONF".equals(product.get(
"productTypeId")))) {
String inventoryFacilityId = null;
if ("Y".equals(productStore.getString("oneInventoryFacility"))) {
inventoryFacilityId = productStore.getString("inventoryFacilityId");
if (UtilValidate.isEmpty(inventoryFacilityId)) {
Debug.logWarning("ProductStore with id " + productStoreId + " has Y for oneInventoryFacility but "
+ "inventoryFacilityId is empty, returning false for inventory check", MODULE);
}
} else {
List<GenericValue> productFacilities = null;
GenericValue productFacility = null;
try {
productFacilities = product.getRelated("ProductFacility", null, null, true);
} catch (GenericEntityException e) {
Debug.logWarning(e, "Error invoking getRelated in isCatalogInventoryAvailable", MODULE);
}
if (UtilValidate.isNotEmpty(productFacilities)) {
productFacility = EntityUtil.getFirst(productFacilities);
inventoryFacilityId = (String) productFacility.get("facilityId");
}
}
Map<String, Object> ripCtx = new HashMap<>();
if (UtilValidate.isNotEmpty(inventoryFacilityId) && UtilValidate.isNotEmpty(productId) && orderItem.getBigDecimal("quantity")
.compareTo(BigDecimal.ZERO) > 0) {
ripCtx.put("productId", productId);
ripCtx.put("facilityId", inventoryFacilityId);
ripCtx.put("inventoryItemTypeId", "SERIALIZED_INV_ITEM");
ripCtx.put("statusId", "INV_AVAILABLE");
ripCtx.put("quantityAccepted", orderItem.getBigDecimal("quantity"));
ripCtx.put("quantityRejected", 0.0);
// do something tricky here: run as the "system" user
ripCtx.put("userLogin", permUserLogin);
try {
Map<String, Object> ripResult = dispatcher.runSync("receiveInventoryProduct", ripCtx);
if (ServiceUtil.isError(ripResult)) {
String errMsg = ServiceUtil.getErrorMessage(ripResult);
@SuppressWarnings("unchecked")
Collection<? extends String> map = (Collection<? extends String>) UtilMisc.<String, String>toMap("reasonCode",
"ReceiveInventoryServiceError", "description", errMsg);
resErrorMessages.addAll(map);
}
} catch (GenericServiceException e) {
Debug.logWarning(e, "Error invoking receiveInventoryProduct service in createOrder", MODULE);
}
}
}
}
}
// START inventory reservation
try {
reserveInventory(delegator, dispatcher, permUserLogin, locale, orderItemShipGroupInfo, dropShipGroupIds, itemValuesBySeqId,
orderTypeId, productStoreId, resErrorMessages);
} catch (GeneralException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (!resErrorMessages.isEmpty()) {
return ServiceUtil.returnError(resErrorMessages);
}
// END inventory reservation
successResult.put("orderId", orderId);
} catch (GenericEntityException e) {
Debug.logError(e, "Problem with order storage or reservations", MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
"OrderErrorCouldNotCreateOrderWriteError", locale) + e.getMessage() + ").");
}
return successResult;
}