001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.hhfacility;
019:
020: import java.util.HashMap;
021: import java.util.Map;
022: import java.util.List;
023: import java.util.ArrayList;
024: import java.util.Iterator;
025:
026: import org.ofbiz.base.util.UtilValidate;
027: import org.ofbiz.base.util.GeneralRuntimeException;
028: import org.ofbiz.base.util.Debug;
029: import org.ofbiz.base.util.UtilMisc;
030: import org.ofbiz.entity.GenericDelegator;
031: import org.ofbiz.entity.GenericEntityException;
032: import org.ofbiz.entity.GenericValue;
033: import org.ofbiz.service.DispatchContext;
034: import org.ofbiz.service.GenericServiceException;
035: import org.ofbiz.service.LocalDispatcher;
036: import org.ofbiz.service.ServiceUtil;
037:
038: public class FacilityServices {
039:
040: public static final String module = FacilityServices.class
041: .getName();
042:
043: public static Map findProductsById(DispatchContext dctx, Map context) {
044: GenericDelegator delegator = dctx.getDelegator();
045: String facilityId = (String) context.get("facilityId");
046: String idValue = (String) context.get("idValue");
047: GenericValue product = null;
048: List productsFound = null;
049:
050: GenericValue productItem = null;
051: if (UtilValidate.isNotEmpty(idValue)) {
052: // First lets find the productId from the Sku(s)
053: try {
054: productsFound = delegator.findByAnd(
055: "GoodIdentificationAndProduct", UtilMisc.toMap(
056: "idValue", idValue), UtilMisc
057: .toList("productId"));
058: } catch (GenericEntityException e) {
059: Debug.logError(e, module);
060: throw new GeneralRuntimeException(e.getMessage());
061: }
062: }
063:
064: // Now do a direct lookup..
065: productItem = null;
066: try {
067: productItem = delegator.findByPrimaryKey("Product",
068: UtilMisc.toMap("productId", idValue));
069: } catch (GenericEntityException e) {
070: Debug.logError(e, module);
071: throw new GeneralRuntimeException(e.getMessage());
072: }
073: if (productItem != null) {
074: if (productsFound == null) {
075: productsFound = new ArrayList();
076: }
077: productsFound.add(productItem);
078: }
079:
080: // Send back the results
081: Map result = ServiceUtil.returnSuccess();
082: if (productsFound != null && productsFound.size() > 0) {
083: result.put("productList", productsFound);
084: }
085: return result;
086: }
087:
088: public static Map fixProductNegativeQOH(DispatchContext dctx,
089: Map context) {
090: GenericDelegator delegator = dctx.getDelegator();
091: LocalDispatcher dispatcher = dctx.getDispatcher();
092:
093: String facilityId = (String) context.get("facilityId");
094: String productId = (String) context.get("productId");
095: GenericValue userLogin = (GenericValue) context
096: .get("userLogin");
097:
098: // Now we build a list of inventory items against the facility and product.
099: // todo: change this to a select from inv_items where productId and facilityId matches distinct (locationSeqId).
100: List invItemList = null;
101: try {
102: invItemList = delegator.findByAnd("InventoryItem", UtilMisc
103: .toMap("productId", productId, "facilityId",
104: facilityId));
105: } catch (GenericEntityException e) {
106: Debug.logError(e, module);
107: throw new GeneralRuntimeException(e.getMessage());
108: }
109:
110: Map locations = new HashMap();
111: Iterator invItemListIter = invItemList.iterator();
112: while (invItemListIter.hasNext()) {
113: GenericValue invItem = (GenericValue) invItemListIter
114: .next();
115: if (invItem != null) {
116: int qoh = ((Double) invItem.get("quantityOnHandTotal"))
117: .intValue();
118:
119: if (qoh < 0) {
120: // Got a negative qoh so lets balance if off to zero.
121: Map contextInput = UtilMisc.toMap("userLogin",
122: userLogin, "inventoryItemId", invItem
123: .get("inventoryItemId"),
124: "varianceReasonId", "VAR_LOST",
125: "availableToPromiseVar", new Double(qoh
126: * -1), "quantityOnHandVar",
127: new Double(qoh * -1), "comments",
128: "QOH < 0 stocktake correction");
129: try {
130: dispatcher.runSync(
131: "createPhysicalInventoryAndVariance",
132: contextInput);
133: } catch (GenericServiceException e) {
134: Debug
135: .logError(
136: e,
137: "fixProductNegativeQOH failed on createPhysicalInventoryAndVariance invItemId"
138: + invItem
139: .get("inventoryItemId"),
140: module);
141: return ServiceUtil
142: .returnError("fixProductNegativeQOH failed on createPhysicalInventoryAndVariance invItemId"
143: + invItem
144: .get("inventoryItemId"));
145: }
146: }
147: }
148: }
149: Map result = ServiceUtil.returnSuccess();
150: return result;
151: }
152:
153: public static Map updateProductStocktake(DispatchContext dctx,
154: Map context) {
155: GenericDelegator delegator = dctx.getDelegator();
156: LocalDispatcher dispatcher = dctx.getDispatcher();
157:
158: String facilityId = (String) context.get("facilityId");
159: String productId = (String) context.get("productId");
160: String locationSeqId = (String) context.get("locationSeqId");
161: String locationSeqIdNew = (String) context
162: .get("locationSeqIdNew");
163: Double quantity = (Double) context.get("quantity");
164: if (UtilValidate.isEmpty(productId)
165: || UtilValidate.isEmpty(facilityId)) {
166: return ServiceUtil
167: .returnError("productId or facilityId not found");
168: }
169:
170: // First identify the location and get a list of inventoryItemIds for that location.
171: if (UtilValidate.isEmpty(locationSeqId)) {
172: // Assume this is the null field version
173: locationSeqId = "nullField";
174: }
175:
176: // Get the current atp/qoh values for the location(s).
177: Map contextInput = UtilMisc.toMap("productId", productId,
178: "facilityId", facilityId, "locationSeqId",
179: locationSeqId);
180: Map invAvailability = null;
181: try {
182: invAvailability = dispatcher.runSync(
183: "getInventoryAvailableByLocationSeq", contextInput);
184: } catch (GenericServiceException e) {
185: Debug
186: .logError(
187: e,
188: "updateProductStocktake failed getting inventory counts",
189: module);
190: return ServiceUtil
191: .returnError("updateProductStocktake failed getting inventory counts");
192: }
193: int atp = ((Double) invAvailability
194: .get("availableToPromiseTotal")).intValue();
195: int qoh = ((Double) invAvailability.get("quantityOnHandTotal"))
196: .intValue();
197: if (quantity.intValue() == qoh) {
198: // No change required.
199: Debug
200: .logInfo(
201: "updateProductStocktake No change required quantity("
202: + quantity + ") = qoh(" + qoh + ")",
203: module);
204: return ServiceUtil.returnSuccess();
205: }
206:
207: // Now get the inventory items that are found for that location, facility and product
208: List invItemList = null;
209: try {
210: invItemList = delegator
211: .findByAnd("InventoryItem", UtilMisc.toMap(
212: "productId", productId, "facilityId",
213: facilityId, "locationSeqId", locationSeqId));
214: } catch (GenericEntityException e) {
215: Debug
216: .logError(
217: e,
218: "updateProductStocktake failed getting inventory items",
219: module);
220: return ServiceUtil
221: .returnError("updateProductStocktake failed getting inventory items");
222: }
223:
224: Iterator invItemListIter = invItemList.iterator();
225: while (invItemListIter.hasNext()) {
226: GenericValue invItem = (GenericValue) invItemListIter
227: .next();
228: String locationFound = invItem.getString("locationSeqId");
229: Debug.logInfo("updateProductStocktake: InvItemId("
230: + invItem.getString("inventoryItemId") + ")",
231: module);
232: if (locationFound == null) {
233: locationFound = "nullField";
234: }
235: }
236: // Check if there is a request to change the locationSeqId
237: GenericValue product = null;
238: try {
239: Map resultOutput = dispatcher.runSync(
240: "getInventoryAvailableByFacility", UtilMisc.toMap(
241: "productId", productId, "facilityId",
242: facilityId));
243: } catch (GenericServiceException e) {
244: Debug.logError(e, module);
245: return ServiceUtil
246: .returnError("Inventory atp/qoh lookup problem ["
247: + e.getMessage() + "]");
248: }
249:
250: /*
251: try {
252: inventoryTransfer = delegator.findByPrimaryKey("InventoryTransfer",
253: UtilMisc.toMap("inventoryTransferId", inventoryTransferId));
254: inventoryItem = inventoryTransfer.getRelatedOne("InventoryItem");
255: destinationFacility = inventoryTransfer.getRelatedOne("ToFacility");
256: } catch (GenericEntityException e) {
257: return ServiceUtil.returnError("Inventory Item/Transfer lookup problem [" + e.getMessage() + "]");
258: }
259:
260: if (inventoryTransfer == null || inventoryItem == null) {
261: return ServiceUtil.returnError("ERROR: Lookup of InventoryTransfer and/or InventoryItem failed!");
262: }
263:
264: String inventoryType = inventoryItem.getString("inventoryItemTypeId");
265:
266: // set the fields on the transfer record
267: if (inventoryTransfer.get("receiveDate") == null) {
268: inventoryTransfer.set("receiveDate", UtilDateTime.nowTimestamp());
269: }
270:
271: if (inventoryType.equals("NON_SERIAL_INV_ITEM")) {
272: // add an adjusting InventoryItemDetail so set ATP back to QOH: ATP = ATP + (QOH - ATP), diff = QOH - ATP
273: double atp = inventoryItem.get("availableToPromiseTotal") == null ? 0 : inventoryItem.getDouble("availableToPromiseTotal").doubleValue();
274: double qoh = inventoryItem.get("quantityOnHandTotal") == null ? 0 : inventoryItem.getDouble("quantityOnHandTotal").doubleValue();
275: Map createDetailMap = UtilMisc.toMap("availableToPromiseDiff", new Double(qoh - atp),
276: "inventoryItemId", inventoryItem.get("inventoryItemId"), "userLogin", userLogin);
277: try {
278: Map result = dctx.getDispatcher().runSync("createInventoryItemDetail", createDetailMap);
279: if (ServiceUtil.isError(result)) {
280: return ServiceUtil.returnError("Inventory Item Detail create problem in complete inventory transfer", null, null, result);
281: }
282: } catch (GenericServiceException e1) {
283: return ServiceUtil.returnError("Inventory Item Detail create problem in complete inventory transfer: [" + e1.getMessage() + "]");
284: }
285: try {
286: inventoryItem.refresh();
287: } catch (GenericEntityException e) {
288: return ServiceUtil.returnError("Inventory refresh problem [" + e.getMessage() + "]");
289: }
290: } else if (inventoryType.equals("SERIALIZED_INV_ITEM")) {
291: inventoryItem.set("statusId", "INV_AVAILABLE");
292: }
293:
294: // set the fields on the item
295: Map updateInventoryItemMap = UtilMisc.toMap("inventoryItemId", inventoryItem.getString("inventoryItemId"),
296: "facilityId", inventoryTransfer.get("facilityIdTo"),
297: "containerId", inventoryTransfer.get("containerIdTo"),
298: "locationSeqId", inventoryTransfer.get("locationSeqIdTo"),
299: "userLogin", userLogin);
300: // if the destination facility's owner is different
301: // from the inventory item's ownwer,
302: // the inventory item is assigned to the new owner.
303: if (destinationFacility != null && destinationFacility.get("ownerPartyId") != null) {
304: String fromPartyId = inventoryItem.getString("ownerPartyId");
305: String toPartyId = destinationFacility.getString("ownerPartyId");
306: if (fromPartyId == null || !fromPartyId.equals(toPartyId)) {
307: updateInventoryItemMap.put("ownerPartyId", toPartyId);
308: }
309: }
310: try {
311: Map result = dctx.getDispatcher().runSync("updateInventoryItem", updateInventoryItemMap);
312: if (ServiceUtil.isError(result)) {
313: return ServiceUtil.returnError("Inventory item store problem", null, null, result);
314: }
315: } catch (GenericServiceException exc) {
316: return ServiceUtil.returnError("Inventory item store problem [" + exc.getMessage() + "]");
317: }
318:
319: // set the inventory transfer record to complete
320: inventoryTransfer.set("statusId", "IXF_COMPLETE");
321:
322: // store the entities
323: try {
324: inventoryTransfer.store();
325: } catch (GenericEntityException e) {
326: return ServiceUtil.returnError("Inventory store problem [" + e.getMessage() + "]");
327: }
328: */
329: return ServiceUtil.returnSuccess();
330: }
331: }
|