📄 morder.java
字号:
}
BigDecimal grandTotal = MConversionRate.convertBase(getCtx(),
getGrandTotal(), getC_Currency_ID(), getDateOrdered(),
getC_ConversionType_ID(), getAD_Client_ID(), getAD_Org_ID());
if (MBPartner.SOCREDITSTATUS_CreditHold.equals(bp.getSOCreditStatus(grandTotal)))
{
m_processMsg = "@BPartnerOverOCreditHold@ - @TotalOpenBalance@="
+ bp.getTotalOpenBalance() + ", @GrandTotal@=" + grandTotal
+ ", @SO_CreditLimit@=" + bp.getSO_CreditLimit();
return DocAction.STATUS_Invalid;
}
}
m_justPrepared = true;
// if (!DOCACTION_Complete.equals(getDocAction())) don't set for just prepare
// setDocAction(DOCACTION_Complete);
return DocAction.STATUS_InProgress;
} // prepareIt
/**
* Explode non stocked BOM.
*/
private void explodeBOM ()
{
String where = "AND IsActive='Y' AND EXISTS "
+ "(SELECT * FROM M_Product p WHERE C_OrderLine.M_Product_ID=p.M_Product_ID"
+ " AND p.IsBOM='Y' AND p.IsVerified='Y' AND p.IsStocked='N')";
//
String sql = "SELECT COUNT(*) FROM C_OrderLine "
+ "WHERE C_Order_ID=? " + where;
int count = DB.getSQLValue(get_TrxName(), sql, getC_Order_ID());
while (count != 0)
{
renumberLines (1000); // max 999 bom items
// Order Lines with non-stocked BOMs
MOrderLine[] lines = getLines (where, "ORDER BY Line");
for (int i = 0; i < lines.length; i++)
{
MOrderLine line = lines[i];
MProduct product = MProduct.get (getCtx(), line.getM_Product_ID());
log.fine(product.getName());
// New Lines
int lineNo = line.getLine ();
MProductBOM[] boms = MProductBOM.getBOMLines (product);
for (int j = 0; j < boms.length; j++)
{
MProductBOM bom = boms[j];
MOrderLine newLine = new MOrderLine (this);
newLine.setLine (++lineNo);
newLine.setM_Product_ID (bom.getProduct ()
.getM_Product_ID ());
newLine.setC_UOM_ID (bom.getProduct ().getC_UOM_ID ());
newLine.setQty (line.getQtyOrdered ().multiply (
bom.getBOMQty ()));
if (bom.getDescription () != null)
newLine.setDescription (bom.getDescription ());
//
newLine.setPrice ();
newLine.save (get_TrxName());
}
// Convert into Comment Line
line.setM_Product_ID (0);
line.setM_AttributeSetInstance_ID (0);
line.setPrice (Env.ZERO);
line.setPriceLimit (Env.ZERO);
line.setPriceList (Env.ZERO);
line.setLineNetAmt (Env.ZERO);
line.setFreightAmt (Env.ZERO);
//
String description = product.getName ();
if (product.getDescription () != null)
description += " " + product.getDescription ();
if (line.getDescription () != null)
description += " " + line.getDescription ();
line.setDescription (description);
line.save (get_TrxName());
} // for all lines with BOM
m_lines = null; // force requery
count = DB.getSQLValue (get_TrxName(), sql, getC_Invoice_ID ());
renumberLines (10);
} // while count != 0
} // explodeBOM
/**
* Reserve Inventory.
* Counterpart: MInOut.completeIt()
* @param dt document type or null
* @param lines order lines (ordered by M_Product_ID for deadlock prevention)
* @return true if (un) reserved
*/
private boolean reserveStock (MDocType dt, MOrderLine[] lines)
{
if (dt == null)
dt = MDocType.get(getCtx(), getC_DocType_ID());
// Binding
boolean binding = !dt.isProposal();
// Not binding - i.e. Target=0
if (DOCACTION_Void.equals(getDocAction())
// Closing Binding Quotation
|| (MDocType.DOCSUBTYPESO_Quotation.equals(dt.getDocSubTypeSO())
&& DOCACTION_Close.equals(getDocAction()))
|| isDropShip() )
binding = false;
boolean isSOTrx = isSOTrx();
log.fine("Binding=" + binding + " - IsSOTrx=" + isSOTrx);
// Force same WH for all but SO/PO
int header_M_Warehouse_ID = getM_Warehouse_ID();
if (MDocType.DOCSUBTYPESO_StandardOrder.equals(dt.getDocSubTypeSO())
|| MDocType.DOCBASETYPE_PurchaseOrder.equals(dt.getDocBaseType()))
header_M_Warehouse_ID = 0; // don't enforce
// Always check and (un) Reserve Inventory
for (int i = 0; i < lines.length; i++)
{
MOrderLine line = lines[i];
// Check/set WH/Org
if (header_M_Warehouse_ID != 0) // enforce WH
{
if (header_M_Warehouse_ID != line.getM_Warehouse_ID())
line.setM_Warehouse_ID(header_M_Warehouse_ID);
if (getAD_Org_ID() != line.getAD_Org_ID())
line.setAD_Org_ID(getAD_Org_ID());
}
// Binding
BigDecimal target = binding ? line.getQtyOrdered() : Env.ZERO;
BigDecimal difference = target
.subtract(line.getQtyReserved())
.subtract(line.getQtyDelivered());
if (difference.signum() == 0)
continue;
log.fine("Line=" + line.getLine()
+ " - Target=" + target + ",Difference=" + difference
+ " - Ordered=" + line.getQtyOrdered()
+ ",Reserved=" + line.getQtyReserved() + ",Delivered=" + line.getQtyDelivered());
// Check Product - Stocked and Item
MProduct product = line.getProduct();
if (product != null)
{
if (product.isStocked())
{
BigDecimal ordered = isSOTrx ? Env.ZERO : difference;
BigDecimal reserved = isSOTrx ? difference : Env.ZERO;
int M_Locator_ID = 0;
// Get Locator to reserve
if (line.getM_AttributeSetInstance_ID() != 0) // Get existing Location
M_Locator_ID = MStorage.getM_Locator_ID (line.getM_Warehouse_ID(),
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
ordered, get_TrxName());
// Get default Location
if (M_Locator_ID == 0)
{
MWarehouse wh = MWarehouse.get(getCtx(), line.getM_Warehouse_ID());
M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID();
}
// Update Storage
if (!MStorage.add(getCtx(), line.getM_Warehouse_ID(), M_Locator_ID,
line.getM_Product_ID(),
line.getM_AttributeSetInstance_ID(), line.getM_AttributeSetInstance_ID(),
Env.ZERO, reserved, ordered, get_TrxName()))
return false;
} // stockec
// update line
line.setQtyReserved(line.getQtyReserved().add(difference));
if (!line.save(get_TrxName()))
return false;
} // product
} // reverse inventory
return true;
} // reserveStock
/**
* Calculate Tax and Total
*/
private boolean calculateTaxTotal()
{
log.fine("");
// Delete Taxes
DB.executeUpdate("DELETE C_OrderTax WHERE C_Order_ID=" + getC_Order_ID(), get_TrxName());
m_taxes = null;
// Lines
BigDecimal totalLines = Env.ZERO;
ArrayList<Integer> taxList = new ArrayList<Integer>();
MOrderLine[] lines = getLines();
for (int i = 0; i < lines.length; i++)
{
MOrderLine line = lines[i];
Integer taxID = new Integer(line.getC_Tax_ID());
if (!taxList.contains(taxID))
{
MOrderTax oTax = MOrderTax.get (line, getPrecision(),
false, get_TrxName()); // current Tax
oTax.setIsTaxIncluded(isTaxIncluded());
if (!oTax.calculateTaxFromLines())
return false;
if (!oTax.save(get_TrxName()))
return false;
taxList.add(taxID);
}
totalLines = totalLines.add(line.getLineNetAmt());
}
// Taxes
BigDecimal grandTotal = totalLines;
MOrderTax[] taxes = getTaxes(true);
for (int i = 0; i < taxes.length; i++)
{
MOrderTax oTax = taxes[i];
MTax tax = oTax.getTax();
if (tax.isSummary())
{
MTax[] cTaxes = tax.getChildTaxes(false);
for (int j = 0; j < cTaxes.length; j++)
{
MTax cTax = cTaxes[j];
BigDecimal taxAmt = cTax.calculateTax(oTax.getTaxBaseAmt(), isTaxIncluded(), getPrecision());
//
MOrderTax newOTax = new MOrderTax(getCtx(), 0, get_TrxName());
newOTax.setClientOrg(this);
newOTax.setC_Order_ID(getC_Order_ID());
newOTax.setC_Tax_ID(cTax.getC_Tax_ID());
newOTax.setPrecision(getPrecision());
newOTax.setIsTaxIncluded(isTaxIncluded());
newOTax.setTaxBaseAmt(oTax.getTaxBaseAmt());
newOTax.setTaxAmt(taxAmt);
if (!newOTax.save(get_TrxName()))
return false;
//
if (!isTaxIncluded())
grandTotal = grandTotal.add(taxAmt);
}
if (!oTax.delete(true, get_TrxName()))
return false;
}
else
{
if (!isTaxIncluded())
grandTotal = grandTotal.add(oTax.getTaxAmt());
}
}
//
setTotalLines(totalLines);
setGrandTotal(grandTotal);
return true;
} // calculateTaxTotal
/**
* Approve Document
* @return true if success
*/
public boolean approveIt()
{
log.info("approveIt - " + toString());
setIsApproved(true);
return true;
} // approveIt
/**
* Reject Approval
* @return true if success
*/
public boolean rejectIt()
{
log.info("rejectIt - " + toString());
setIsApproved(false);
return true;
} // rejectIt
/**************************************************************************
* Complete Document
* @return new status (Complete, In Progress, Invalid, Waiting ..)
*/
public String completeIt()
{
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
String DocSubTypeSO = dt.getDocSubTypeSO();
// Just prepare
if (DOCACTION_Prepare.equals(getDocAction()))
{
setProcessed(false);
return DocAction.STATUS_InProgress;
}
// Offers
if (MDocType.DOCSUBTYPESO_Proposal.equals(DocSubTypeSO)
|| MDocType.DOCSUBTYPESO_Quotation.equals(DocSubTypeSO))
{
// Binding
if (MDocType.DOCSUBTYPESO_Quotation.equals(DocSubTypeSO))
reserveStock(dt, getLines(true, "M_Product_ID"));
setProcessed(true);
return DocAction.STATUS_Completed;
}
// Waiting Payment - until we have a payment
if (!m_forceCreation
&& MDocType.DOCSUBTYPESO_PrepayOrder.equals(DocSubTypeSO)
&& getC_Payment_ID() == 0 && getC_CashLine_ID() == 0)
{
setProcessed(true);
return DocAction.STATUS_WaitingPayment;
}
// Re-Check
if (!m_justPrepared)
{
String status = prepareIt();
if (!DocAction.STATUS_InProgress.equals(status))
return status;
}
// Implicit Approval
if (!isApproved())
approveIt();
getLines(true,null);
log.info(toString());
StringBuffer info = new StringBuffer();
boolean realTimePOS = false;
// Create SO Shipment - Force Shipment
MInOut shipment = null;
if (MDocType.DOCSUBTYPESO_OnCreditOrder.equals(DocSubTypeSO) // (W)illCall(I)nvoice
|| MDocType.DOCSUBTYPESO_WarehouseOrder.equals(DocSubTypeSO) // (W)illCall(P)ickup
|| MDocType.DOCSUBTYPESO_POSOrder.equals(DocSubTypeSO) // (W)alkIn(R)eceipt
|| MDocType.DOCSUBTYPESO_PrepayOrder.equals(DocSubTypeSO))
{
if (!DELIVERYRULE_Force.equals(getDeliveryRule()))
setDeliveryRule(DELIVERYRULE_Force);
//
shipment = createShipment (dt, realTimePOS ? null : getDateOrdered());
if (shipment == null)
return DocAction.STATUS_Invalid;
info.append("@M_InOut_ID@: ").append(shipment.getDocumentNo());
String msg = shipment.getProcessMsg();
if (msg != null && msg.length() > 0)
info.append(" (").append(msg).append(")");
} // Shipment
// Create SO Invoice - Always invoice complete Order
if ( MDocType.DOCSUBTYPESO_POSOrder.equals(DocSubTypeSO)
|| MDocType.DOCSUBTYPESO_OnCreditOrder.equals(DocSubTypeSO)
|| MDocType.DOCSUBTYPESO_PrepayOrder.equals(DocSubTypeSO))
{
MInvoice invoice = createInvoice (dt, shipment, realTimePOS ? null : getDateOrdered());
if (invoice == null)
return DocAction.STATUS_Invalid;
info.append(" - @C_Invoice_ID@: ").append(invoice.getDocumentNo());
String msg = invoice.getProcessMsg();
if (msg != null && msg.length() > 0)
info.append(" (").append(msg).append(")");
} // Invoice
// Counter Documents
MOrder counter = createCounterDoc();
if (counter != null)
info.append(" - @CounterDoc@: @Order@=").append(counter.getDocumentNo());
// User Validation
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
if (valid != null)
{
if (info.length() > 0)
info.append(" - ");
info.append(valid);
m_processMsg = info.toString();
return DocAction.STATUS_Invalid;
}
setProcessed(true);
m_processMsg = info.toString();
//
setDocAction(DOCACTION_Close);
return DocAction.STATUS_Completed;
} // completeIt
/**
* Create Shipment
* @param dt order document type
* @param movementDate optional movement date (default today)
* @return shipment or null
*/
private MInOut createShipment(MDocType dt, Timestamp movementDate)
{
log.info("For " + dt);
MInOut shipment = new MInOut (this, dt.getC_DocTypeShipment_ID(), movementDate);
// shipment.setDateAcct(getDateAcct());
if (!shipment.save(get_TrxName()))
{
m_processMsg = "Could not create Shipment";
return null;
}
//
MOrderLine[] oLines = getLines(true, null);
for (int i = 0; i < oLines.length; i++)
{
MOrderLine oLine = oLines[i];
//
MInOutLine ioLine = new MInOutLine(shipment);
// Qty = Ordered - Delivered
BigDecimal MovementQty = oLine.getQtyOrdered().subtract(oLine.getQtyDelivered());
// Location
int M_Locator_ID = MStorage.getM_Locator_ID (oLine.getM_Warehouse_ID(),
oLine.getM_Product_ID(), oLine.getM_AttributeSetInstance_ID(),
MovementQty, get_TrxName());
if (M_Locator_ID == 0) // Get default Location
{
MWarehouse wh = MWarehouse.get(getCtx(), oLine.getM_Warehouse_ID());
M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID();
}
//
ioLine.setOrderLine(oLine, M_Locator_ID, MovementQty);
ioLine.setQty(MovementQty);
if (oLine.getQtyEntered().compareTo(oLine.getQtyOrdered()) != 0)
ioLine.setQtyEntered(MovementQty
.multiply(oLine.getQtyEntered())
.divide(oLine.getQtyOrdered(), 6, BigDecimal.ROUND_HALF_UP));
if (!ioLine.save(get_TrxName()))
{
m_processMsg = "Could not create Shipment Line";
return null;
}
}
// Manually Process Shipment
String status = shipment.completeIt();
shipment.setDocStatus(status);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -