diff --git a/org.adempiere.base.process/src/org/adempiere/process/InOutGenerateRMA.java b/org.adempiere.base.process/src/org/adempiere/process/InOutGenerateRMA.java index 362828dcc0..800dd08514 100644 --- a/org.adempiere.base.process/src/org/adempiere/process/InOutGenerateRMA.java +++ b/org.adempiere.base.process/src/org/adempiere/process/InOutGenerateRMA.java @@ -169,6 +169,8 @@ public class InOutGenerateRMA extends SvrProcess shipment.setC_Activity_ID(originalReceipt.getC_Activity_ID()); shipment.setUser1_ID(originalReceipt.getUser1_ID()); shipment.setUser2_ID(originalReceipt.getUser2_ID()); + shipment.setMovementDate(p_movementDate); + shipment.setDateAcct(p_movementDate); if (!shipment.save()) { diff --git a/org.adempiere.base.process/src/org/adempiere/process/InvoiceGenerateRMA.java b/org.adempiere.base.process/src/org/adempiere/process/InvoiceGenerateRMA.java index c6c7648ee9..decb2beae2 100644 --- a/org.adempiere.base.process/src/org/adempiere/process/InvoiceGenerateRMA.java +++ b/org.adempiere.base.process/src/org/adempiere/process/InvoiceGenerateRMA.java @@ -69,16 +69,20 @@ public class InvoiceGenerateRMA extends SvrProcess ; else if (name.equals("Selection")) p_Selection = "Y".equals(para[i].getParameter()); + else if (name.equals("DateInvoiced")) + m_dateinvoiced = (Timestamp)para[i].getParameter(); else if (name.equals("DocAction")) p_docAction = (String)para[i].getParameter(); else MProcessPara.validateUnknownParameter(getProcessInfo().getAD_Process_ID(), para[i]); } - m_dateinvoiced = Env.getContextAsDate(getCtx(), Env.DATE); - if (m_dateinvoiced == null) - { - m_dateinvoiced = new Timestamp(System.currentTimeMillis()); + if (m_dateinvoiced == null) { + m_dateinvoiced = Env.getContextAsDate(getCtx(), Env.DATE); + if (m_dateinvoiced == null) + { + m_dateinvoiced = new Timestamp(System.currentTimeMillis()); + } } if (getProcessInfo().getAD_InfoWindow_ID() > 0) p_Selection=true; } @@ -142,10 +146,12 @@ public class InvoiceGenerateRMA extends SvrProcess throw new IllegalStateException("Could not get invoice document type for Customer RMA"); } - MInvoice invoice = new MInvoice(getCtx(), 0, get_TrxName()); + MInvoice invoice = new MInvoice(getCtx(), 0, get_TrxName()); invoice.setRMA(rma); invoice.setC_DocTypeTarget_ID(docTypeId); + invoice.setDateInvoiced(m_dateinvoiced); + invoice.setDateAcct(m_dateinvoiced); if (!invoice.save()) { throw new IllegalStateException("Could not create invoice"); diff --git a/org.idempiere.test/src/org/idempiere/test/model/InvoiceCustomerTest.java b/org.idempiere.test/src/org/idempiere/test/model/InvoiceCustomerTest.java index bd0e3654b9..4eb94a5bba 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/InvoiceCustomerTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/InvoiceCustomerTest.java @@ -30,6 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.sql.Timestamp; +import java.util.Calendar; import java.util.List; import java.util.logging.LogRecord; @@ -507,4 +508,148 @@ public class InvoiceCustomerTest extends AbstractTestCase { } assertEquals(invoiceTaxes.length, match, "MInvoiceTax record doesn't match child tax records"); } + + /** + * https://idempiere.atlassian.net/browse/IDEMPIERE-5915 + */ + @Test + public void testInvoiceGenerateRMAManualDateInvoiced() { + MOrder order = new MOrder(Env.getCtx(), 0, getTrxName()); + order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id)); + order.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_Standard); + order.setDeliveryRule(MOrder.DELIVERYRULE_CompleteOrder); + order.setDocStatus(DocAction.STATUS_Drafted); + order.setDocAction(DocAction.ACTION_Complete); + + Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(currentDate.getTime()); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.add(Calendar.DAY_OF_MONTH, -2); + Timestamp date1 = new Timestamp(cal.getTimeInMillis()); + cal.setTimeInMillis(currentDate.getTime()); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.add(Calendar.DAY_OF_MONTH, -1); + Timestamp date2 = new Timestamp(cal.getTimeInMillis()); + + order.setDateOrdered(date1); + order.setDatePromised(date1); + order.setSalesRep_ID(getAD_User_ID()); + order.saveEx(); + + MOrderLine line1 = new MOrderLine(order); + line1.setLine(10); + line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.AZALEA_BUSH.id)); + line1.setQty(new BigDecimal("1")); + line1.setDatePromised(date1); + line1.saveEx(); + + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + order.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, order.getDocStatus()); + line1.load(getTrxName()); + assertEquals(1, line1.getQtyReserved().intValue()); + + MInOut shipment = new MInOut(order, DictionaryIDs.C_DocType.MM_SHIPMENT.id, order.getDateOrdered()); + shipment.setDocStatus(DocAction.STATUS_Drafted); + shipment.setDocAction(DocAction.ACTION_Complete); + shipment.saveEx(); + + // Shipment + MInOutLine shipmentLine = new MInOutLine(shipment); + shipmentLine.setOrderLine(line1, 0, new BigDecimal("1")); + shipmentLine.setQty(new BigDecimal("1")); + shipmentLine.saveEx(); + + info = MWorkflow.runDocumentActionWorkflow(shipment, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + shipment.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, shipment.getDocStatus()); + + // Invoice + MInvoice invoice = new MInvoice(shipment, date1); + invoice.saveEx(); + MInvoiceLine invoiceLine = new MInvoiceLine(invoice); + invoiceLine.setShipLine(shipmentLine); + invoiceLine.setQty(new BigDecimal("1")); + invoiceLine.saveEx(); + + info = MWorkflow.runDocumentActionWorkflow(invoice, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + invoice.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, invoice.getDocStatus()); + + line1.load(getTrxName()); + assertEquals(0, line1.getQtyReserved().intValue()); + assertEquals(1, line1.getQtyDelivered().intValue()); + assertEquals(1, line1.getQtyInvoiced().intValue()); + + // RMA + MRMA rma = new MRMA(Env.getCtx(), 0, getTrxName()); + rma.setInOut_ID(shipment.get_ID()); + rma.setC_BPartner_ID(shipment.getC_BPartner_ID()); + rma.setC_Currency_ID(order.getC_Currency_ID()); + rma.setM_RMAType_ID(DictionaryIDs.M_RMAType.DAMAGE_ON_ARRIVAL.id); + rma.setC_DocType_ID(DictionaryIDs.C_DocType.CUSTOMER_RETURN_MATERIAL.id); + rma.setSalesRep_ID(order.getSalesRep_ID()); + rma.setIsSOTrx(true); + rma.setName("testInvoiceGenerateRMAManualDateInvoiced"); + rma.saveEx(); + + MRMALine rmaLine = new MRMALine(Env.getCtx(), 0, getTrxName()); + rmaLine.setM_RMA_ID(rma.get_ID()); + rmaLine.setM_InOutLine_ID(shipmentLine.get_ID()); + rmaLine.setM_Product_ID(shipmentLine.getM_Product_ID()); + rmaLine.setQty(new BigDecimal("1")); + rmaLine.saveEx(); + assertEquals(0, rmaLine.getQtyInvoiced().intValue()); + + info = MWorkflow.runDocumentActionWorkflow(rma, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + rma.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, rma.getDocStatus()); + + int AD_Process_ID = SystemIDs.PROCESS_C_INVOICE_GENERATERMA_MANUAL; + MPInstance instance = new MPInstance(Env.getCtx(), AD_Process_ID, 0, 0, null); + instance.saveEx(); + String insert = "INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID) Values (?, ?)"; + DB.executeUpdateEx(insert, new Object[] {instance.getAD_PInstance_ID(), rma.get_ID()}, null); + + // Call InvoiceGenerateRMAManual process + ProcessInfo pi = new ProcessInfo ("InvoiceGenerateRMAManual", AD_Process_ID); + pi.setAD_PInstance_ID (instance.getAD_PInstance_ID()); + + // Add Selection parameter Selection=Y + MPInstancePara ip = new MPInstancePara(instance, 10); + ip.setParameter("Selection","Y"); + ip.saveEx(); + // Add Document Action parameter + ip = new MPInstancePara(instance, 20); + ip.setParameter("DocAction", "CO"); + ip.saveEx(); + // Add Date Invoiced action parameter + ip = new MPInstancePara(instance, 30); + ip.setParameter("DateInvoiced", date2); + ip.saveEx(); + + ServerProcessCtl processCtl = new ServerProcessCtl(pi, getTrx()); + processCtl.setManagedTrxForJavaProcess(false); + processCtl.run(); + + assertFalse(pi.isError(), pi.getSummary()); + rmaLine.load(getTrxName()); + assertEquals(1, rmaLine.getQtyInvoiced().intValue()); + + int C_Invoice_ID = DB.getSQLValueEx(getTrxName(), "SELECT C_Invoice_ID FROM C_Invoice WHERE M_RMA_ID=?", rma.getM_RMA_ID()); + MInvoice creditMemo = new MInvoice(Env.getCtx(), C_Invoice_ID, getTrxName()); + assertEquals(date2, creditMemo.getDateInvoiced()); + assertEquals(date2, creditMemo.getDateAcct()); + } } diff --git a/org.idempiere.test/src/org/idempiere/test/model/PurchaseOrderTest.java b/org.idempiere.test/src/org/idempiere/test/model/PurchaseOrderTest.java index fc430bd396..46e08e5a4c 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/PurchaseOrderTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/PurchaseOrderTest.java @@ -32,6 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.sql.Timestamp; +import java.util.Calendar; import java.util.Properties; import org.compiere.model.MAttributeSetInstance; @@ -680,4 +681,131 @@ public class PurchaseOrderTest extends AbstractTestCase { rmaLine.load(getTrxName()); assertEquals(rmaLine.getQty().intValue(), rmaLine.getQtyDelivered().intValue(), "RMA Line QtyDelivered not updated by shipment for Vendor RMA"); } + + /** + * https://idempiere.atlassian.net/browse/IDEMPIERE-5915 + */ + @Test + public void testInOutGenerateRMAManualMovementDate() { + MOrder order = new MOrder(Env.getCtx(), 0, getTrxName()); + order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id)); + order.setC_DocTypeTarget_ID(DictionaryIDs.C_DocType.PURCHASE_ORDER.id); + order.setIsSOTrx(false); + order.setSalesRep_ID(DictionaryIDs.AD_User.GARDEN_ADMIN.id); + order.setDocStatus(DocAction.STATUS_Drafted); + order.setDocAction(DocAction.ACTION_Complete); + + Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(currentDate.getTime()); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.add(Calendar.DAY_OF_MONTH, -2); + Timestamp date1 = new Timestamp(cal.getTimeInMillis()); + cal.setTimeInMillis(currentDate.getTime()); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.add(Calendar.DAY_OF_MONTH, -1); + Timestamp date2 = new Timestamp(cal.getTimeInMillis()); + + order.setDateOrdered(date1); + order.setDatePromised(date1); + order.saveEx(); + + MOrderLine line1 = new MOrderLine(order); + line1.setLine(10); + line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id)); + line1.setQty(new BigDecimal("1")); + line1.setDatePromised(date1); + line1.saveEx(); + + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + order.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, order.getDocStatus()); + + MInOut receipt = new MInOut(order, DictionaryIDs.C_DocType.MM_RECEIPT.id, order.getDateOrdered()); + receipt.setDocStatus(DocAction.STATUS_Drafted); + receipt.setDocAction(DocAction.ACTION_Complete); + receipt.saveEx(); + + MInOutLine receiptLine1 = new MInOutLine(receipt); + receiptLine1.setOrderLine(line1, 0, new BigDecimal("1")); + receiptLine1.setQty(new BigDecimal("1")); + receiptLine1.saveEx(); + + info = MWorkflow.runDocumentActionWorkflow(receipt, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + receipt.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, receipt.getDocStatus()); + + MRMA rma = new MRMA(Env.getCtx(), 0, getTrxName()); + rma.setM_InOut_ID(receipt.getM_InOut_ID()); + rma.setC_BPartner_ID(receipt.getC_BPartner_ID()); + rma.setC_Currency_ID(order.getC_Currency_ID()); + rma.setIsSOTrx(false); + rma.setName("testInOutGenerateRMAManualMovementDate"); + rma.setC_DocType_ID(DictionaryIDs.C_DocType.VENDOR_RETURN_MATERIAL.id); + rma.setSalesRep_ID(order.getSalesRep_ID()); + rma.setM_RMAType_ID(DictionaryIDs.M_RMAType.DAMAGE_ON_ARRIVAL.id); + rma.saveEx(); + + MRMALine rmaLine = new MRMALine(Env.getCtx(), 0, getTrxName()); + rmaLine.setM_RMA_ID(rma.get_ID()); + rmaLine.setM_InOutLine_ID(receiptLine1.get_ID()); + rmaLine.setQty(receiptLine1.getMovementQty()); + rmaLine.saveEx(); + assertEquals(0, rmaLine.getQtyDelivered().intValue(), "Unexpected RMA Line QtyDelivered value"); + + info = MWorkflow.runDocumentActionWorkflow(rma, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + rma.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, rma.getDocStatus()); + + int AD_Process_ID = PROCESS_M_INOUT_GENERATERMA_MANUAL; + MPInstance instance = new MPInstance(Env.getCtx(), AD_Process_ID, 0, 0, null); + instance.saveEx(); + + String insert = "INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID) Values (?, ?)"; + DB.executeUpdateEx(insert, new Object[] {instance.getAD_PInstance_ID(), rma.get_ID()}, null); + + // Call InOutGenerateRMAManual process + ProcessInfo pi = new ProcessInfo ("InOutGenRMA", AD_Process_ID); + pi.setAD_PInstance_ID (instance.getAD_PInstance_ID()); + + // Add Selection parameter Selection=Y + MPInstancePara ip = new MPInstancePara(instance, 10); + ip.setParameter("Selection","Y"); + ip.saveEx(); + // Add Document Action parameter + ip = new MPInstancePara(instance, 20); + ip.setParameter("DocAction", "CO"); + ip.saveEx(); + // Add Warehouse parameter + ip = new MPInstancePara(instance, 30); + ip.setParameter("M_Warehouse_ID", getM_Warehouse_ID()); + ip.saveEx(); + // Add Movement Date parameter + ip = new MPInstancePara(instance, 40); + ip.setParameter("MovementDate", date2); + ip.saveEx(); + + ServerProcessCtl processCtl = new ServerProcessCtl(pi, getTrx()); + processCtl.setManagedTrxForJavaProcess(false); + processCtl.run(); + + assertFalse(pi.isError(), pi.getSummary()); + + rmaLine.load(getTrxName()); + assertEquals(rmaLine.getQty().intValue(), rmaLine.getQtyDelivered().intValue(), "RMA Line QtyDelivered not updated by shipment for Vendor RMA"); + + int M_InOut_ID = DB.getSQLValueEx(getTrxName(), "SELECT M_InOut_ID FROM M_InOut WHERE M_RMA_ID=?", rma.getM_RMA_ID()); + MInOut vendorReturn = new MInOut(Env.getCtx(), M_InOut_ID, getTrxName()); + assertEquals(date2, vendorReturn.getMovementDate()); + assertEquals(date2, vendorReturn.getDateAcct()); + } }