Search in sources :

Example 21 with MStorage

use of org.compiere.model.MStorage in project adempiere by adempiere.

the class MovementGenerate method generate.

/**
	 * 	Generate Shipments
	 * 	@param distributionOrders Orders
	 *	@return info
	 */
private String generate(List<MDDOrder> distributionOrders) {
    distributionOrders.stream().filter(order -> order != null).forEach(order -> {
        getCurrentMovement().filter(movement -> movement != null || !isConsolidatetooneDocument()).filter(movement -> movement.getC_BPartner_Location_ID() != order.getC_BPartner_Location_ID() || movement.getM_Shipper_ID() != order.getM_Shipper_ID()).ifPresent(movement -> completeMovement());
        log.fine("check: " + order + " - DeliveryRule=" + order.getDeliveryRule());
        Timestamp minGuaranteeDate = getMovementDate();
        StringBuilder where = new StringBuilder(" 1=1 ");
        if (getWarehouseId() > 0)
            where.append(" AND ").append(getWarehouseId()).append(" IN (SELECT l.M_Warehouse_ID FROM M_Locator l WHERE l.M_Locator_ID=M_Locator_ID) ");
        if (getDatePromised() != null)
            where.append(" AND (TRUNC(DatePromised)<=").append(DB.TO_DATE(getDatePromised(), true)).append(" OR DatePromised IS NULL)");
        if (!MDDOrder.DELIVERYRULE_Force.equals(order.getDeliveryRule()))
            where.append(" AND (DD_OrderLine.M_Product_ID IS NULL").append(" OR EXISTS (SELECT * FROM M_Product p ").append("WHERE DD_OrderLine.M_Product_ID=p.M_Product_ID").append(" AND IsExcludeAutoDelivery='N'))");
        if (!isOrderswithunconfirmedShipments())
            where.append(" AND NOT EXISTS (SELECT * FROM M_MovementLine iol").append(" INNER JOIN M_Movement io ON (iol.M_Movement_ID=io.M_Movement_ID) ").append("WHERE iol.DD_OrderLine_ID=DD_OrderLine.DD_OrderLine_ID AND io.DocStatus IN ('IP','WC'))");
        List<MDDOrderLine> orderLines = order.getLines(where.toString(), "M_Product_ID");
        orderLines.stream().filter(orderLine -> orderLine.getM_Product_ID() > 0 || orderLine.getC_Charge_ID() > 0).filter(orderLine -> orderLine.getConfirmedQty().signum() != 0).forEach(orderLine -> {
            MLocator locator = new MLocator(getCtx(), orderLine.getM_Locator_ID(), get_TrxName());
            if (getWarehouseId() > 0 && locator.getM_Warehouse_ID() != getWarehouseId())
                return;
            log.fine("check: " + orderLine);
            BigDecimal onHand = Env.ZERO;
            BigDecimal toDeliver = orderLine.getConfirmedQty();
            MProduct product = orderLine.getProduct();
            BigDecimal unconfirmedShippedQty = Env.ZERO;
            if (isOrderswithunconfirmedShipments() && product != null && toDeliver.signum() != 0) {
                String whereLine = "EXISTS (SELECT * FROM M_Movement io WHERE io.M_Movement_ID=M_MovementLine.M_Movement_ID AND io.DocStatus IN ('IP','WC'))";
                MMovementLine[] movementLines = MMovementLine.getOfOrderLine(getCtx(), orderLine.getDD_OrderLine_ID(), whereLine, null);
                unconfirmedShippedQty = Arrays.asList(movementLines).stream().map(MMovementLine::getMovementQty).reduce(BigDecimal.ZERO, BigDecimal::add);
                String logInfo = "Unconfirmed Qty=" + unconfirmedShippedQty + " - ToDeliver=" + orderLine.getConfirmedQty() + "->";
                toDeliver = orderLine.getConfirmedQty().subtract(unconfirmedShippedQty);
                logInfo += toDeliver;
                if (toDeliver.signum() < 0) {
                    toDeliver = Env.ZERO;
                    logInfo += " (set to 0)";
                }
                onHand = onHand.subtract(unconfirmedShippedQty);
                log.fine(logInfo);
            }
            if ((product == null || !product.isStocked()) && (orderLine.getQtyOrdered().signum() == 0 || toDeliver.signum() != 0)) {
                if (!MDDOrder.DELIVERYRULE_CompleteOrder.equals(order.getDeliveryRule()))
                    createLine(order, orderLine, toDeliver, null, false);
                return;
            }
            String policyMaterialIssue = getPolicyIssue(product);
            MStorage[] storages = getStorages(locator.getM_Warehouse_ID(), orderLine.getM_Product_ID(), orderLine.getM_AttributeSetInstance_ID(), product.getM_AttributeSet_ID(), orderLine.getM_AttributeSetInstance_ID() == 0, minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(policyMaterialIssue));
            onHand = Arrays.asList(storages).stream().map(MStorage::getQtyOnHand).reduce(BigDecimal.ZERO, BigDecimal::add);
            boolean fullLine = onHand.compareTo(toDeliver) >= 0 || toDeliver.signum() < 0;
            boolean completeOrder = MDDOrder.DELIVERYRULE_CompleteOrder.equals(order.getDeliveryRule());
            if (completeOrder && !fullLine) {
                log.fine("Failed CompleteOrder - OnHand=" + onHand + " (Unconfirmed=" + unconfirmedShippedQty + "), ToDeliver=" + toDeliver + " - " + orderLine);
                return;
            } else if (fullLine && MDDOrder.DELIVERYRULE_CompleteLine.equals(order.getDeliveryRule())) {
                log.fine("CompleteLine - OnHand=" + onHand + " (Unconfirmed=" + unconfirmedShippedQty + ", ToDeliver=" + toDeliver + " - " + orderLine);
                createLine(order, orderLine, toDeliver, storages, false);
            } else if (MDDOrder.DELIVERYRULE_Availability.equals(order.getDeliveryRule()) && (onHand.signum() > 0 || orderLine.getConfirmedQty().signum() < 0)) {
                BigDecimal deliver = orderLine.getConfirmedQty();
                log.fine("Available - OnHand=" + onHand + " (Unconfirmed=" + unconfirmedShippedQty + "), ToDeliver=" + toDeliver + ", Delivering=" + deliver + " - " + orderLine);
                if (deliver.compareTo(onHand) > 0)
                    deliver = onHand;
                createLine(order, orderLine, deliver, storages, false);
            } else if (MDDOrder.DELIVERYRULE_Force.equals(order.getDeliveryRule())) {
                BigDecimal deliver = toDeliver;
                log.fine("Force - OnHand=" + onHand + " (Unconfirmed=" + unconfirmedShippedQty + "), ToDeliver=" + toDeliver + ", Delivering=" + deliver + " - " + orderLine);
                createLine(order, orderLine, deliver, storages, true);
            } else if (MDDOrder.DELIVERYRULE_Manual.equals(order.getDeliveryRule()))
                log.fine("Manual - OnHand=" + onHand + " (Unconfirmed=" + unconfirmedShippedQty + ") - " + orderLine);
            else
                log.fine("Failed: " + order.getDeliveryRule() + " - OnHand=" + onHand + " (Unconfirmed=" + unconfirmedShippedQty + "), ToDeliver=" + toDeliver + " - " + orderLine);
        });
        boolean completeOrder = MDDOrder.DELIVERYRULE_CompleteOrder.equals(order.getDeliveryRule());
        if (completeOrder && MDDOrder.DELIVERYRULE_CompleteOrder.equals(order.getDeliveryRule())) {
            for (MDDOrderLine orderLine : orderLines) {
                MLocator l = new MLocator(getCtx(), orderLine.getM_Locator_ID(), get_TrxName());
                if (getWarehouseId() > 0 && l.getM_Warehouse_ID() != getWarehouseId())
                    continue;
                MProduct product = orderLine.getProduct();
                BigDecimal toDeliver = orderLine.getQtyOrdered().subtract(orderLine.getQtyDelivered());
                MStorage[] storages = null;
                if (product != null && product.isStocked()) {
                    MProductCategory pc = MProductCategory.get(order.getCtx(), product.getM_Product_Category_ID());
                    String MMPolicy = pc.getMMPolicy();
                    if (MMPolicy == null || MMPolicy.length() == 0)
                        MMPolicy = getClient().getMMPolicy();
                    storages = getStorages(l.getM_Warehouse_ID(), orderLine.getM_Product_ID(), orderLine.getM_AttributeSetInstance_ID(), product.getM_AttributeSet_ID(), orderLine.getM_AttributeSetInstance_ID() == 0, minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy));
                }
                createLine(order, orderLine, toDeliver, storages, false);
            }
        }
        lineNo += 1000;
        completeMovement();
    });
    return "@Created@ = " + createdCount;
}
Also used : Arrays(java.util.Arrays) MDDOrder(org.eevolution.model.MDDOrder) Timestamp(java.sql.Timestamp) MClient(org.compiere.model.MClient) MDocType(org.compiere.model.MDocType) Env(org.compiere.util.Env) HashMap(java.util.HashMap) MDDOrderLine(org.eevolution.model.MDDOrderLine) MStorage(org.compiere.model.MStorage) ArrayList(java.util.ArrayList) MMovementLine(org.compiere.model.MMovementLine) BigDecimal(java.math.BigDecimal) List(java.util.List) MAttributeSet(org.compiere.model.MAttributeSet) Query(org.compiere.model.Query) DB(org.compiere.util.DB) AdempiereException(org.adempiere.exceptions.AdempiereException) MMovement(org.compiere.model.MMovement) Optional(java.util.Optional) MLocator(org.compiere.model.MLocator) MProduct(org.compiere.model.MProduct) MProductCategory(org.compiere.model.MProductCategory) MProduct(org.compiere.model.MProduct) Timestamp(java.sql.Timestamp) MStorage(org.compiere.model.MStorage) BigDecimal(java.math.BigDecimal) MDDOrderLine(org.eevolution.model.MDDOrderLine) MProductCategory(org.compiere.model.MProductCategory) MLocator(org.compiere.model.MLocator) MMovementLine(org.compiere.model.MMovementLine)

Example 22 with MStorage

use of org.compiere.model.MStorage in project adempiere by adempiere.

the class StorageReasoner method getAvailableQtyLocator.

public MStorage getAvailableQtyLocator(MProduct p, MAttributeSetInstance asi, BigDecimal qtyRequired) {
    int[] ids = getPOIDs(MLocator.Table_Name, null, null);
    MStorage storage = null;
    BigDecimal qtyAvailable = BigDecimal.ZERO;
    BigDecimal qtyOnHand = BigDecimal.ZERO;
    BigDecimal qtyReserved = BigDecimal.ZERO;
    for (int i = 0; i < ids.length; i++) {
        storage = MStorage.get(Env.getCtx(), ids[i], p.get_ID(), asi.get_ID(), null);
        if (storage != null) {
            qtyOnHand = (storage.getQtyOnHand() == null) ? BigDecimal.ZERO : storage.getQtyOnHand();
            qtyReserved = (storage.getQtyReserved() == null) ? BigDecimal.ZERO : storage.getQtyReserved();
            qtyAvailable = qtyOnHand.subtract(qtyReserved);
            if (qtyRequired.compareTo(qtyAvailable) <= 0 && qtyOnHand.compareTo(BigDecimal.ZERO) > 0) {
                break;
            } else {
                storage = null;
            }
        }
    }
    return storage;
}
Also used : MStorage(org.compiere.model.MStorage) BigDecimal(java.math.BigDecimal)

Example 23 with MStorage

use of org.compiere.model.MStorage in project adempiere by adempiere.

the class StorageReasoner method isQtyAvailable.

public boolean isQtyAvailable(MProduct p, MAttributeSetInstance asi) {
    int[] ids = getPOIDs(MLocator.Table_Name, null, null);
    MStorage storage = null;
    BigDecimal sumQtyOnHand = BigDecimal.ZERO;
    BigDecimal sumQtyReserved = BigDecimal.ZERO;
    int count = 0;
    for (int i = 0; i < ids.length; i++) {
        storage = MStorage.get(Env.getCtx(), ids[i], p.get_ID(), asi.get_ID(), null);
        if (storage == null) {
            continue;
        }
        count++;
        sumQtyOnHand = sumQtyOnHand.add(storage.getQtyOnHand());
        sumQtyReserved = sumQtyReserved.add(storage.getQtyReserved());
    }
    double available = sumQtyOnHand.subtract(sumQtyReserved).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    if (count == 0 || (available <= 0.00d)) {
        return false;
    }
    return true;
}
Also used : MStorage(org.compiere.model.MStorage) BigDecimal(java.math.BigDecimal)

Example 24 with MStorage

use of org.compiere.model.MStorage in project adempiere by adempiere.

the class MDDOrderLine method beforeSave.

//	setQtyOrdered
/**************************************************************************
	 * 	Before Save
	 *	@param newRecord
	 *	@return true if it can be sabed
	 */
protected boolean beforeSave(boolean newRecord) {
    if (newRecord && getParent().isComplete()) {
        log.saveError("ParentComplete", Msg.translate(getCtx(), "DD_OrderLine"));
        return false;
    }
    /*if (getC_BPartner_ID() == 0 || getC_BPartner_Location_ID() == 0
			|| getM_Warehouse_ID() == 0)
			setOrder (getParent());*/
    if (m_M_PriceList_ID == 0)
        setHeaderInfo(getParent());
    //	R/O Check - Product/Warehouse Change
    if (!newRecord && (is_ValueChanged("M_Product_ID") || is_ValueChanged("M_Locator_ID") || is_ValueChanged("M_LocatorTo_ID"))) {
        if (!canChangeWarehouse())
            return false;
    }
    //	Charge
    if (getC_Charge_ID() != 0 && getM_Product_ID() != 0)
        setM_Product_ID(0);
    //	No Product
    if (getM_Product_ID() == 0)
        setM_AttributeSetInstance_ID(0);
    //	UOM
    if (getC_UOM_ID() == 0 && (getM_Product_ID() != 0 || getC_Charge_ID() != 0)) {
        int C_UOM_ID = MUOM.getDefault_UOM_ID(getCtx());
        if (C_UOM_ID > 0)
            setC_UOM_ID(C_UOM_ID);
    }
    //	Qty Precision
    if (newRecord || is_ValueChanged("QtyEntered"))
        setQtyEntered(getQtyEntered());
    if (newRecord || is_ValueChanged("QtyOrdered"))
        setQtyOrdered(getQtyOrdered());
    //	Qty on instance ASI for SO
    if (m_IsSOTrx && getM_AttributeSetInstance_ID() != 0 && (newRecord || is_ValueChanged("M_Product_ID") || is_ValueChanged("M_AttributeSetInstance_ID") || is_ValueChanged("M_Warehouse_ID"))) {
        MProduct product = getProduct();
        if (product.isStocked()) {
            int M_AttributeSet_ID = product.getM_AttributeSet_ID();
            boolean isInstance = M_AttributeSet_ID != 0;
            if (isInstance) {
                MAttributeSet mas = MAttributeSet.get(getCtx(), M_AttributeSet_ID);
                isInstance = mas.isInstanceAttribute();
            }
            //	Max
            if (isInstance) {
                MLocator locator_from = MLocator.get(getCtx(), getM_Locator_ID());
                MStorage[] storages = MStorage.getWarehouse(getCtx(), locator_from.getM_Warehouse_ID(), getM_Product_ID(), getM_AttributeSetInstance_ID(), M_AttributeSet_ID, false, null, true, get_TrxName());
                BigDecimal qty = Env.ZERO;
                for (int i = 0; i < storages.length; i++) {
                    if (storages[i].getM_AttributeSetInstance_ID() == getM_AttributeSetInstance_ID())
                        qty = qty.add(storages[i].getQtyOnHand());
                }
                if (getQtyOrdered().compareTo(qty) > 0) {
                    log.warning("Qty - Stock=" + qty + ", Ordered=" + getQtyOrdered());
                    log.saveError("QtyInsufficient", "=" + qty);
                    return false;
                }
            }
        }
    //	stocked
    }
    //	FreightAmt Not used
    if (Env.ZERO.compareTo(getFreightAmt()) != 0)
        setFreightAmt(Env.ZERO);
    //	Get Line No
    if (getLine() == 0) {
        String sql = "SELECT COALESCE(MAX(Line),0)+10 FROM DD_OrderLine WHERE DD_Order_ID=?";
        int ii = DB.getSQLValue(get_TrxName(), sql, getDD_Order_ID());
        setLine(ii);
    }
    return true;
}
Also used : MProduct(org.compiere.model.MProduct) MLocator(org.compiere.model.MLocator) MStorage(org.compiere.model.MStorage) BigDecimal(java.math.BigDecimal) MAttributeSet(org.compiere.model.MAttributeSet)

Example 25 with MStorage

use of org.compiere.model.MStorage in project adempiere by adempiere.

the class MPPOrder method createIssue.

/**
	 * Create Issue
	 * @param orderBOMLine
	 * @param movementdate
	 * @param qtyToDeliver
	 * @param qtyScrapComponent
	 * @param qtyReject
	 * @param shortages
	 * @param forceIssue
	 */
public static List<MPPCostCollector> createIssue(MPPOrder order, MPPOrderBOMLine orderBOMLine, Timestamp movementdate, BigDecimal qtyToDeliver, BigDecimal qtyScrapComponent, BigDecimal qtyReject, MStorage[] shortages, boolean forceIssue) {
    List<MPPCostCollector> collectors = new ArrayList<MPPCostCollector>();
    if (qtyToDeliver.signum() == 0)
        return null;
    BigDecimal toIssue = qtyToDeliver.add(qtyScrapComponent);
    for (MStorage storage : shortages) {
        if (storage.getQtyOnHand().signum() == 0)
            continue;
        BigDecimal qtyIssue = toIssue.min(storage.getQtyOnHand());
        //create record for negative and positive transaction
        if (qtyIssue.signum() != 0 || qtyScrapComponent.signum() != 0 || qtyReject.signum() != 0) {
            String CostCollectorType = MPPCostCollector.COSTCOLLECTORTYPE_ComponentIssue;
            if (orderBOMLine.isComponentType(MPPOrderBOMLine.COMPONENTTYPE_Co_Product))
                CostCollectorType = MPPCostCollector.COSTCOLLECTORTYPE_MixVariance;
            collectors.add(MPPCostCollector.createCollector(//MPPOrder
            order, //M_Product_ID
            orderBOMLine.getM_Product_ID(), //M_Locator_ID
            storage.getM_Locator_ID(), //M_AttributeSetInstance_ID
            storage.getM_AttributeSetInstance_ID(), //S_Resource_ID
            order.getS_Resource_ID(), //PP_Order_BOMLine_ID
            orderBOMLine.getPP_Order_BOMLine_ID(), //PP_Order_Node_ID
            0, //C_DocType_ID,
            MDocType.getDocType(MDocType.DOCBASETYPE_ManufacturingCostCollector), //Production "-"
            CostCollectorType, //MovementDate
            movementdate, //qty,scrap,reject
            qtyIssue, //qty,scrap,reject
            qtyScrapComponent, //qty,scrap,reject
            qtyReject, //durationSetup,duration
            Env.ZERO, //durationSetup,duration
            Env.ZERO));
            orderBOMLine.load(order.get_TrxName());
            // Method Variance
            if (orderBOMLine.getQtyBatch().signum() == 0 && orderBOMLine.getQtyBOM().signum() == 0)
                order.createMethodChangeVariance(orderBOMLine);
        }
        toIssue = toIssue.subtract(qtyIssue);
        if (toIssue.signum() == 0)
            break;
    }
    if (forceIssue && toIssue.signum() != 0) {
        collectors.add(MPPCostCollector.createCollector(//MPPOrder
        order, //M_Product_ID
        orderBOMLine.getM_Product_ID(), //M_Locator_ID
        orderBOMLine.getM_Locator_ID(), //M_AttributeSetInstance_ID
        orderBOMLine.getM_AttributeSetInstance_ID(), //S_Resource_ID
        order.getS_Resource_ID(), //PP_Order_BOMLine_ID
        orderBOMLine.getPP_Order_BOMLine_ID(), //PP_Order_Node_ID
        0, //C_DocType_ID,
        MDocType.getDocType(MDocType.DOCBASETYPE_ManufacturingCostCollector), //Production "-"
        MPPCostCollector.COSTCOLLECTORTYPE_ComponentIssue, //MovementDate
        movementdate, //qty,scrap,reject
        toIssue, //qty,scrap,reject
        Env.ZERO, //qty,scrap,reject
        Env.ZERO, //durationSetup,duration
        Env.ZERO, //durationSetup,duration
        Env.ZERO));
        return collectors;
    }
    //remove logic to allow qty return component
    if (toIssue.signum() != 0) {
        // should not happen because we validate Qty On Hand on start of this process
        throw new AdempiereException("Should not happen toIssue=" + toIssue);
    }
    return collectors;
}
Also used : AdempiereException(org.adempiere.exceptions.AdempiereException) ArrayList(java.util.ArrayList) MStorage(org.compiere.model.MStorage) BigDecimal(java.math.BigDecimal)

Aggregations

MStorage (org.compiere.model.MStorage)33 BigDecimal (java.math.BigDecimal)27 MProduct (org.compiere.model.MProduct)16 ArrayList (java.util.ArrayList)11 Timestamp (java.sql.Timestamp)9 MLocator (org.compiere.model.MLocator)8 MMovementLine (org.compiere.model.MMovementLine)7 ResultSet (java.sql.ResultSet)6 AdempiereException (org.adempiere.exceptions.AdempiereException)5 MInOutLine (org.compiere.model.MInOutLine)5 PreparedStatement (java.sql.PreparedStatement)4 MClient (org.compiere.model.MClient)4 MMovement (org.compiere.model.MMovement)4 MOrderLine (org.compiere.model.MOrderLine)4 MWarehouse (org.compiere.model.MWarehouse)4 KeyNamePair (org.compiere.util.KeyNamePair)4 MDDOrderLine (org.eevolution.model.MDDOrderLine)4 MAttributeSet (org.compiere.model.MAttributeSet)3 MAttributeSetInstance (org.compiere.model.MAttributeSetInstance)3 MInOut (org.compiere.model.MInOut)3