IDEMPIERE-5433 Better invoice consolidation rules (#1504)
With acknowledgements to Carlos Ruiz for writing the test case.
This commit is contained in:
parent
56fe006d29
commit
84dc2b3f31
|
@ -91,6 +91,8 @@ public class InvoiceGenerate extends SvrProcess
|
|||
private BigDecimal p_MinimumAmtInvSched = null;
|
||||
/** Per Invoice Savepoint */
|
||||
private Savepoint m_savepoint = null;
|
||||
/** BPartner on the last order processed */
|
||||
private int m_bpartnerID = 0;
|
||||
|
||||
/**
|
||||
* Prepare - e.g., get Parameters.
|
||||
|
@ -177,7 +179,7 @@ public class InvoiceGenerate extends SvrProcess
|
|||
//
|
||||
sql.append(") AND o.C_DocType_ID IN (SELECT C_DocType_ID FROM C_DocType ")
|
||||
.append("WHERE DocBaseType='SOO' AND DocSubTypeSO NOT IN ('ON','OB','WR')) ")
|
||||
.append("ORDER BY AD_Org_ID, M_Warehouse_ID, PriorityRule, C_BPartner_ID, Bill_Location_ID, C_Order_ID");
|
||||
.append("ORDER BY AD_Org_ID, M_Warehouse_ID, PriorityRule, C_BPartner_ID, Bill_Location_ID, Bill_User_ID, C_Order_ID");
|
||||
}
|
||||
// sql += " FOR UPDATE";
|
||||
|
||||
|
@ -228,10 +230,13 @@ public class InvoiceGenerate extends SvrProcess
|
|||
StringBuilder msgsup = new StringBuilder(Msg.getMsg(getCtx(), "Processing")).append(" ").append(order.getDocumentInfo());
|
||||
statusUpdate(msgsup.toString());
|
||||
|
||||
// New Invoice Location
|
||||
// New BPartner, or new Invoice Location, or new Invoice Contact
|
||||
if (!p_ConsolidateDocument
|
||||
|| (m_bpartnerID != 0
|
||||
&& m_bpartnerID != order.getC_BPartner_ID())
|
||||
|| (m_invoice != null
|
||||
&& m_invoice.getC_BPartner_Location_ID() != order.getBill_Location_ID()) )
|
||||
&& (m_invoice.getC_BPartner_Location_ID() != order.getBill_Location_ID() ||
|
||||
m_invoice.getAD_User_ID() != order.getBill_User_ID()) ) )
|
||||
completeInvoice();
|
||||
boolean completeOrder = MOrder.INVOICERULE_AfterOrderDelivered.equals(order.getInvoiceRule());
|
||||
|
||||
|
@ -350,6 +355,7 @@ public class InvoiceGenerate extends SvrProcess
|
|||
m_line += 1000;
|
||||
}
|
||||
} // complete Order
|
||||
m_bpartnerID = order.getC_BPartner_ID();
|
||||
} // for all orders
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -107,6 +107,16 @@ public final class DictionaryIDs {
|
|||
}
|
||||
}
|
||||
|
||||
public enum C_BPartner_Location {
|
||||
C_AND_W_STAMFORD(112);
|
||||
|
||||
public final int id;
|
||||
|
||||
private C_BPartner_Location(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
public enum C_Charge {
|
||||
BANK(100),
|
||||
COMMISSIONS(101),
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.compiere.model.MRMA;
|
|||
import org.compiere.model.MRMALine;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.model.SystemIDs;
|
||||
import org.compiere.model.X_C_BP_Relation;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.process.ServerProcessCtl;
|
||||
|
@ -361,4 +362,108 @@ public class InvoiceCustomerTest extends AbstractTestCase {
|
|||
rmaLine.load(getTrxName());
|
||||
assertEquals(1, rmaLine.getQtyInvoiced().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateInvoiceRelatedBP() { // IDEMPIERE-5433
|
||||
X_C_BP_Relation bpr = new X_C_BP_Relation(Env.getCtx(), 0, getTrxName());
|
||||
bpr.setName("C&W may pay invoices for Seed");
|
||||
bpr.setC_BPartner_ID(DictionaryIDs.C_BPartner.SEED_FARM.id);
|
||||
bpr.setC_BPartnerRelation_ID(DictionaryIDs.C_BPartner.C_AND_W.id);
|
||||
bpr.setC_BPartnerRelation_Location_ID(DictionaryIDs.C_BPartner_Location.C_AND_W_STAMFORD.id);
|
||||
bpr.setIsBillTo(true);
|
||||
bpr.setIsRemitTo(true);
|
||||
bpr.saveEx();
|
||||
|
||||
MOrder order1 = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||
order1.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id));
|
||||
order1.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_Standard);
|
||||
order1.setDeliveryRule(MOrder.DELIVERYRULE_CompleteOrder);
|
||||
order1.setInvoiceRule(MOrder.INVOICERULE_Immediate);
|
||||
order1.setDocStatus(DocAction.STATUS_Drafted);
|
||||
order1.setDocAction(DocAction.ACTION_Complete);
|
||||
order1.setBill_BPartner_ID(DictionaryIDs.C_BPartner.C_AND_W.id);
|
||||
order1.setBill_Location_ID(DictionaryIDs.C_BPartner_Location.C_AND_W_STAMFORD.id);
|
||||
Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
|
||||
order1.setDateOrdered(today);
|
||||
order1.setDatePromised(today);
|
||||
order1.saveEx();
|
||||
|
||||
MOrderLine line1 = new MOrderLine(order1);
|
||||
line1.setLine(10);
|
||||
line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.SEEDER.id));
|
||||
line1.setQty(new BigDecimal("1"));
|
||||
line1.setDatePromised(today);
|
||||
line1.saveEx();
|
||||
|
||||
ProcessInfo info1 = MWorkflow.runDocumentActionWorkflow(order1, DocAction.ACTION_Complete);
|
||||
assertFalse(info1.isError(), info1.getSummary());
|
||||
order1.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Completed, order1.getDocStatus());
|
||||
line1.load(getTrxName());
|
||||
assertEquals(1, line1.getQtyReserved().intValue());
|
||||
assertEquals(0, line1.getQtyInvoiced().intValue());
|
||||
|
||||
MOrder order2 = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||
order2.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id));
|
||||
order2.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_Standard);
|
||||
order2.setDeliveryRule(MOrder.DELIVERYRULE_CompleteOrder);
|
||||
order2.setInvoiceRule(MOrder.INVOICERULE_Immediate);
|
||||
order2.setDocStatus(DocAction.STATUS_Drafted);
|
||||
order2.setDocAction(DocAction.ACTION_Complete);
|
||||
order2.setBill_BPartner_ID(DictionaryIDs.C_BPartner.C_AND_W.id);
|
||||
order2.setBill_Location_ID(DictionaryIDs.C_BPartner_Location.C_AND_W_STAMFORD.id);
|
||||
order2.setDateOrdered(today);
|
||||
order2.setDatePromised(today);
|
||||
order2.saveEx();
|
||||
|
||||
MOrderLine line2 = new MOrderLine(order2);
|
||||
line2.setLine(10);
|
||||
line2.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.WEEDER.id));
|
||||
line2.setQty(new BigDecimal("1"));
|
||||
line2.setDatePromised(today);
|
||||
line2.saveEx();
|
||||
|
||||
ProcessInfo info2 = MWorkflow.runDocumentActionWorkflow(order2, DocAction.ACTION_Complete);
|
||||
assertFalse(info2.isError(), info2.getSummary());
|
||||
order2.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Completed, order2.getDocStatus());
|
||||
line2.load(getTrxName());
|
||||
assertEquals(1, line2.getQtyReserved().intValue());
|
||||
assertEquals(0, line2.getQtyInvoiced().intValue());
|
||||
|
||||
int AD_Process_ID = SystemIDs.PROCESS_C_INVOICE_GENERATE;
|
||||
MPInstance instance = new MPInstance(Env.getCtx(), AD_Process_ID, 0);
|
||||
instance.saveEx();
|
||||
|
||||
//call process
|
||||
ProcessInfo pi = new ProcessInfo ("InvoiceGenerate", AD_Process_ID);
|
||||
pi.setAD_PInstance_ID (instance.getAD_PInstance_ID());
|
||||
|
||||
// Add Parameter - Selection=Y
|
||||
MPInstancePara ip = new MPInstancePara(instance, 10);
|
||||
ip.setParameter("DateInvoiced",today);
|
||||
ip.saveEx();
|
||||
// Org
|
||||
ip = new MPInstancePara(instance, 20);
|
||||
ip.setParameter("AD_Org_ID", DictionaryIDs.AD_Org.HQ.id);
|
||||
ip.saveEx();
|
||||
//Add Document action parameter
|
||||
ip = new MPInstancePara(instance, 50);
|
||||
ip.setParameter("DocAction", MOrder.DOCACTION_Prepare);
|
||||
ip.saveEx();
|
||||
// Consolidate
|
||||
ip = new MPInstancePara(instance, 60);
|
||||
ip.setParameter("ConsolidateDocument", true);
|
||||
ip.saveEx();
|
||||
|
||||
ServerProcessCtl processCtl = new ServerProcessCtl(pi, getTrx());
|
||||
processCtl.setManagedTrxForJavaProcess(false);
|
||||
processCtl.run();
|
||||
|
||||
assertFalse(pi.isError(), pi.getSummary());
|
||||
// It must create two invoices because they are for different ship BP
|
||||
// even if they have the same Bill BP and Location
|
||||
assertEquals(pi.getSummary(), "Created = 2");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue