Search in sources :

Example 11 with MInvoice

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

the class CostResult method createInvoiceVendor.

public MInvoice createInvoiceVendor(Timestamp documentDate, BigDecimal qty, BigDecimal price, int M_InOutLine_ID) {
    MInvoice invoice = new MInvoice(getCtx(), 0, trxName);
    invoice.setAD_Org_ID(Env.getAD_Org_ID(getCtx()));
    invoice.setC_DocType_ID(MDocType.getDocType(MDocType.DOCBASETYPE_APInvoice));
    invoice.setIsSOTrx(false);
    invoice.setC_BPartner_ID(bp.getC_BPartner_ID());
    invoice.setDateInvoiced(documentDate);
    invoice.setDateAcct(documentDate);
    invoice.setDocStatus(DocAction.STATUS_Drafted);
    invoice.setDocAction(DocAction.ACTION_Complete);
    invoice.saveEx();
    MInvoiceLine invoiceLine = new MInvoiceLine(invoice);
    invoiceLine.setM_Product_ID(product.getM_Product_ID());
    invoiceLine.setM_InOutLine_ID(M_InOutLine_ID);
    invoiceLine.setQty(qty);
    invoiceLine.setPriceActual(price);
    invoiceLine.saveEx();
    invoice.processIt(DocAction.ACTION_Complete);
    invoice.saveEx();
    return invoice;
}
Also used : MInvoiceLine(org.compiere.model.MInvoiceLine) MInvoice(org.compiere.model.MInvoice)

Example 12 with MInvoice

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

the class CostResult method createBusinessCaseTest.

/**
	 * create Business Test Case
	 * @param trxName
	 */
void createBusinessCaseTest(String trxName) {
    createDataMaster();
    generateHistoryCost();
    Timestamp dateAcct;
    //First Purchase Receipt 
    dateAcct = today;
    MOrder purchase1 = createPurchaseOrder(dateAcct, new BigDecimal(100), new BigDecimal(36));
    MInOut receipt1 = null;
    for (MOrderLine line : purchase1.getLines()) {
        receipt1 = createMaterialReceipt(dateAcct, new BigDecimal(10), line.getC_OrderLine_ID());
    }
    for (MInOutLine line : receipt1.getLines()) {
        CostResult costResult = new CostResult(product.getM_Product_ID(), //currentCostPrice
        new BigDecimal("47.7292"), // cumulateQty
        new BigDecimal("30"), //cumulateAmt
        new BigDecimal("1431.8748"), //cdAmt
        new BigDecimal("477.2920"), //cdAdjutment
        new BigDecimal("0"), //cdQty
        new BigDecimal("10"), //cdCurrentCostPrice
        new BigDecimal("53.5937"), //cdCumulateQty
        new BigDecimal("20"), //cdCumulateAmt
        new BigDecimal("1071.8748"), dateAcct);
        assertCostReceipt(costResult, line.getM_InOutLine_ID(), as, trxName);
    }
    //Create Sales Order Order Credit by 5
    dateAcct = TimeUtil.addDays(today, 15);
    MOrder sales1 = createSalesOrder(dateAcct, new BigDecimal(5), new BigDecimal(45));
    for (MOrderLine line : sales1.getLines()) {
        CostResult costResult = new CostResult(product.getM_Product_ID(), new BigDecimal("47.7292"), new BigDecimal("25"), new BigDecimal("1193.2288"), new BigDecimal("238.6460"), new BigDecimal("0"), new BigDecimal("-5"), new BigDecimal("47.7292"), new BigDecimal("30"), new BigDecimal("1431.8748"), dateAcct);
        assertCostShipment(costResult, line.getC_OrderLine_ID(), as, trxName);
    }
    //Second Purchase Receipt 7 day forward
    dateAcct = TimeUtil.addDays(today, 31);
    MOrder purchase2 = createPurchaseOrder(dateAcct, new BigDecimal(100), new BigDecimal(34));
    MInOut receipt2 = null;
    for (MOrderLine line : purchase2.getLines()) {
        receipt2 = createMaterialReceipt(dateAcct, new BigDecimal(10), line.getC_OrderLine_ID());
    }
    for (MInOutLine line : receipt2.getLines()) {
        CostResult costResult = new CostResult(product.getM_Product_ID(), //currentCostPrice
        new BigDecimal("43.8065"), // cumulateQty
        new BigDecimal("35"), //cumulateAmt
        new BigDecimal("1533.2288"), //cdAmt
        new BigDecimal("438.0650"), //cdAdjutment
        new BigDecimal("0"), //cdQty
        new BigDecimal("10"), //cdCurrentCostPrice
        new BigDecimal("47.7292"), //cdCumulateQty
        new BigDecimal("25"), //cdCumulateAmt
        new BigDecimal("1193.2288"), dateAcct);
        assertCostReceipt(costResult, line.getM_InOutLine_ID(), as, trxName);
    }
    //Create Sales Order Order Credit by 5
    dateAcct = TimeUtil.addDays(today, 60);
    MOrder sales2 = createSalesOrder(dateAcct, new BigDecimal(10), new BigDecimal(45));
    for (MOrderLine line : sales2.getLines()) {
        CostResult costResult = new CostResult(product.getM_Product_ID(), new BigDecimal("43.8065"), new BigDecimal("25"), new BigDecimal("1095.1638"), new BigDecimal("438.0650"), new BigDecimal("0"), new BigDecimal("-10"), new BigDecimal("43.8065"), new BigDecimal("35"), new BigDecimal("1533.2288"), dateAcct);
        assertCostShipment(costResult, line.getC_OrderLine_ID(), as, trxName);
    }
    dateAcct = receipt1.getDateAcct();
    int M_InOutLine_ID = 0;
    for (MInOutLine line : receipt1.getLines()) {
        M_InOutLine_ID = line.getM_InOutLine_ID();
        MInvoice invoice = createInvoiceVendor(dateAcct, new BigDecimal(10), new BigDecimal(38), line.getM_InOutLine_ID());
    }
    CostResult costResult = new CostResult(product.getM_Product_ID(), //currentCostPrice
    new BigDecimal("44.2827"), // cumulateQty
    new BigDecimal("25"), //cumulateAmt
    new BigDecimal("1107.0688"), //cdAmt
    new BigDecimal("380.0000"), //cdAdjutment
    new BigDecimal("20.0000"), //cdQty
    new BigDecimal("10"), //cdCurrentCostPrice
    new BigDecimal("53.5937"), //cdCumulateQty
    new BigDecimal("20"), //cdCumulateAmt
    new BigDecimal("1071.8748"), dateAcct);
    assertCostInvoice(costResult, M_InOutLine_ID, as, trxName);
    dateAcct = Timestamp.valueOf("2010-01-16 00:00:00.0");
    for (MOrderLine line : sales1.getLines()) {
        costResult = new CostResult(line.getM_Product_ID(), new BigDecimal("44.2827"), new BigDecimal("25"), new BigDecimal("1107.0688"), new BigDecimal("241.9790"), new BigDecimal("0"), new BigDecimal("-5"), new BigDecimal("48.3958"), new BigDecimal("30"), new BigDecimal("1451.8748"), dateAcct);
        assertCostShipmentAdjust(costResult, line.getC_OrderLine_ID(), as, trxName);
    }
    //Reverse Material Receipt		
    dateAcct = today;
    receipt1.processIt(DocAction.ACTION_Reverse_Correct);
    receipt1.saveEx();
    for (MInOutLine line : receipt1.getLines(true)) {
        costResult = new CostResult(product.getM_Product_ID(), //currentCostPrice
        new BigDecimal("44.2827"), // cumulateQty
        new BigDecimal("25"), //cumulateAmt
        new BigDecimal("1107.0688"), //cdAmt
        new BigDecimal("380.0000"), //cdAdjutment
        new BigDecimal("20.0000"), //cdQty
        new BigDecimal("10"), //cdCurrentCostPrice
        new BigDecimal("53.5937"), //cdCumulateQty
        new BigDecimal("20"), //cdCumulateAmt
        new BigDecimal("1071.8748"), dateAcct);
        assertCostReceiptReversal(costResult, line.getM_InOutLine_ID(), as, trxName);
    }
    MInOut reversal = new MInOut(getCtx(), receipt1.getReversal_ID(), trxName);
    for (MInOutLine line : reversal.getLines(true)) {
        costResult = new CostResult(product.getM_Product_ID(), //currentCostPrice
        new BigDecimal("46.8373"), // cumulateQty
        new BigDecimal("19"), //cumulateAmt
        new BigDecimal("889.9081"), //cdAmt
        new BigDecimal("380"), //cdAdjutment
        new BigDecimal("20"), //cdQty
        new BigDecimal("-10"), //cdCurrentCostPrice
        new BigDecimal("49.0073"), //cdCumulateQty
        new BigDecimal("34"), //cdCumulateAmt
        new BigDecimal("1666.2496"), dateAcct);
        assertCostReceiptReversal(costResult, line.getM_InOutLine_ID(), as, trxName);
    }
    //Second Purchase Receipt 7 day forward
    dateAcct = TimeUtil.addDays(today, 7);
    MOrder purchase3 = createPurchaseOrder(dateAcct, new BigDecimal(100), new BigDecimal(37));
    MInOut receipt3 = null;
    for (MOrderLine line : purchase3.getLines()) {
        receipt3 = createMaterialReceipt(dateAcct, new BigDecimal(20), line.getC_OrderLine_ID());
    }
    for (MInOutLine line : receipt3.getLines()) {
        costResult = new CostResult(product.getM_Product_ID(), //currentCostPrice
        new BigDecimal("42.0489"), // cumulateQty
        new BigDecimal("45"), //cumulateAmt
        new BigDecimal("1892.1983"), //cdAmt
        new BigDecimal("876.7500"), //cdAdjutment
        new BigDecimal("0"), //cdQty
        new BigDecimal("20"), //cdCurrentCostPrice
        new BigDecimal("48.3958"), //cdCumulateQty
        new BigDecimal("30"), //cdCumulateAmt
        new BigDecimal("1451.8748"), dateAcct);
        assertCostReceipt(costResult, line.getM_InOutLine_ID(), as, trxName);
    }
    dateAcct = TimeUtil.addDays(today, 65);
    MMovement move = createMovement(dateAcct, new BigDecimal("5"));
    for (MMovementLine line : move.getLines(true)) {
        costResult = new CostResult(product.getM_Product_ID(), //currentCostPrice
        new BigDecimal("53.5938"), // cumulateQty
        new BigDecimal("9"), //cumulateAmt
        new BigDecimal("482.3442"), //cdAmt
        new BigDecimal("267.9690"), //cdAdjutment
        new BigDecimal("0"), //cdQty
        new BigDecimal("5"), //cdCurrentCostPrice
        new BigDecimal("53.5938"), //cdCumulateQty
        new BigDecimal("4"), //cdCumulateAmt
        new BigDecimal("214.3752"), dateAcct);
        assertCostMovement(costResult, line.getM_MovementLine_ID(), as, trxName);
    }
    dateAcct = TimeUtil.addDays(today, 70);
    MInventory inventory = createPhisicalInventory(dateAcct, new BigDecimal("20"), costResult.cumulateQty);
    for (MInventoryLine line : inventory.getLines(true)) {
        costResult = new CostResult(product.getM_Product_ID(), //currentCostPrice
        new BigDecimal("42.0488"), // cumulateQty
        new BigDecimal("51"), //cumulateAmt
        new BigDecimal("2144.4906"), //cdAmt
        new BigDecimal("462.5368"), //cdAdjutment
        new BigDecimal("0"), //cdQty
        new BigDecimal("11"), //cdCurrentCostPrice
        new BigDecimal("42.0488"), //cdCumulateQty
        new BigDecimal("40"), //cdCumulateAmt
        new BigDecimal("1681.9538"), dateAcct);
        assertCostPhisicalInventory(costResult, line.getM_InventoryLine_ID(), as, trxName);
        break;
    }
    dateAcct = TimeUtil.addDays(today, 80);
    inventory = createInvetoryInternalUse(dateAcct, new BigDecimal("-5"));
    for (MInventoryLine line : inventory.getLines(true)) {
        costResult = new CostResult(product.getM_Product_ID(), //currentCostPrice
        new BigDecimal("42.0488"), // cumulateQty
        new BigDecimal("56"), //cumulateAmt
        new BigDecimal("2354.7346"), //cdAmt
        new BigDecimal("210.2440"), //cdAdjutment
        new BigDecimal("0"), //cdQty
        new BigDecimal("5"), //cdCurrentCostPrice
        new BigDecimal("42.0488"), //cdCumulateQty
        new BigDecimal("51"), //cdCumulateAmt
        new BigDecimal("2144.4906"), dateAcct);
        assertCostPhisicalInventory(costResult, line.getM_InventoryLine_ID(), as, trxName);
        ;
    }
    createTrxAndInventoryValuationReport();
}
Also used : MInOut(org.compiere.model.MInOut) MInOutLine(org.compiere.model.MInOutLine) MInventoryLine(org.compiere.model.MInventoryLine) MInvoice(org.compiere.model.MInvoice) Timestamp(java.sql.Timestamp) BigDecimal(java.math.BigDecimal) MOrder(org.compiere.model.MOrder) MInventory(org.compiere.model.MInventory) MOrderLine(org.compiere.model.MOrderLine) MMovementLine(org.compiere.model.MMovementLine) MMovement(org.compiere.model.MMovement)

Example 13 with MInvoice

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

the class DocumentEngine method processIt.

//	process
/**
	 * 	Process actual document - do not call directly.
	 * 	Calls the individual actions which call the document action
	 *	@param action document action
	 *	@return true if performed
	 */
public boolean processIt(String action) {
    m_message = null;
    m_action = action;
    //
    if (ACTION_Unlock.equals(m_action))
        return unlockIt();
    if (ACTION_Invalidate.equals(m_action))
        return invalidateIt();
    if (ACTION_Prepare.equals(m_action))
        return STATUS_InProgress.equals(prepareIt());
    if (ACTION_Approve.equals(m_action))
        return approveIt();
    if (ACTION_Reject.equals(m_action))
        return rejectIt();
    if (ACTION_Complete.equals(m_action) || ACTION_WaitComplete.equals(m_action)) {
        String status = null;
        if (//	prepare if not prepared yet
        isDrafted() || isInvalid()) {
            status = prepareIt();
            if (!STATUS_InProgress.equals(status))
                return false;
        }
        status = completeIt();
        boolean ok = STATUS_Completed.equals(status) || STATUS_InProgress.equals(status) || STATUS_WaitingPayment.equals(status) || STATUS_WaitingConfirmation.equals(status);
        if (m_document != null && ok) {
            // PostProcess documents when invoice or inout (this is to postprocess the generated MatchPO and MatchInv if any)
            ArrayList<PO> docsPostProcess = new ArrayList<PO>();
            if (m_document instanceof MInvoice || m_document instanceof MInOut) {
                if (m_document instanceof MInvoice) {
                    docsPostProcess = ((MInvoice) m_document).getDocsPostProcess();
                }
                if (m_document instanceof MInOut) {
                    docsPostProcess = ((MInOut) m_document).getDocsPostProcess();
                }
            }
            if (m_document instanceof PO && docsPostProcess.size() > 0) {
                // Process (this is to update the ProcessedOn flag with a timestamp after the original document)
                for (PO docafter : docsPostProcess) {
                    docafter.setProcessedOn("Processed", true, false);
                    docafter.saveEx();
                }
            }
            if (STATUS_Completed.equals(status) && MClient.isClientAccountingImmediate()) {
                m_document.saveEx();
                postIt();
                if (m_document instanceof PO && docsPostProcess.size() > 0) {
                    for (PO docafter : docsPostProcess) {
                        @SuppressWarnings("unused") String ignoreError = DocumentEngine.postImmediate(docafter.getCtx(), docafter.getAD_Client_ID(), docafter.get_Table_ID(), docafter.get_ID(), true, docafter.get_TrxName());
                    }
                }
            }
        }
        return ok;
    }
    if (ACTION_ReActivate.equals(m_action))
        return reActivateIt();
    if (ACTION_Reverse_Accrual.equals(m_action))
        return reverseAccrualIt();
    if (ACTION_Reverse_Correct.equals(m_action))
        return reverseCorrectIt();
    if (ACTION_Close.equals(m_action))
        return closeIt();
    if (ACTION_Void.equals(m_action))
        return voidIt();
    if (ACTION_Post.equals(m_action))
        return postIt();
    //
    return false;
}
Also used : MInOut(org.compiere.model.MInOut) ArrayList(java.util.ArrayList) MInvoice(org.compiere.model.MInvoice) PO(org.compiere.model.PO)

Example 14 with MInvoice

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

the class ExpenseAPInvoice method doIt.

//	prepare
/**
	 *  Perform process.
	 *  @return Message (clear text)
	 *  @throws Exception if not successful
	 */
protected String doIt() throws java.lang.Exception {
    StringBuffer sql = new StringBuffer("SELECT * " + "FROM S_TimeExpense e " + "WHERE e.Processed='Y'" + //	#1
    " AND e.AD_Client_ID=?");
    if (m_C_BPartner_ID != 0)
        //	#2
        sql.append(" AND e.C_BPartner_ID=?");
    if (m_DateFrom != null)
        //	#3
        sql.append(" AND e.DateReport >= ?");
    if (m_DateTo != null)
        //	#4
        sql.append(" AND e.DateReport <= ?");
    sql.append(" AND EXISTS (SELECT * FROM S_TimeExpenseLine el " + "WHERE e.S_TimeExpense_ID=el.S_TimeExpense_ID" + " AND el.C_InvoiceLine_ID IS NULL" + " AND el.ConvertedAmt<>0) " + "ORDER BY e.C_BPartner_ID, e.S_TimeExpense_ID");
    //
    int old_BPartner_ID = -1;
    MInvoice invoice = null;
    //
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
        pstmt = DB.prepareStatement(sql.toString(), get_TrxName());
        int par = 1;
        pstmt.setInt(par++, getAD_Client_ID());
        if (m_C_BPartner_ID != 0)
            pstmt.setInt(par++, m_C_BPartner_ID);
        if (m_DateFrom != null)
            pstmt.setTimestamp(par++, m_DateFrom);
        if (m_DateTo != null)
            pstmt.setTimestamp(par++, m_DateTo);
        rs = pstmt.executeQuery();
        while (//	********* Expense Line Loop
        rs.next()) {
            MTimeExpense te = new MTimeExpense(getCtx(), rs, get_TrxName());
            //	New BPartner - New Order
            if (te.getC_BPartner_ID() != old_BPartner_ID) {
                completeInvoice(invoice);
                MBPartner bp = new MBPartner(getCtx(), te.getC_BPartner_ID(), get_TrxName());
                //
                log.info("New Invoice for " + bp);
                invoice = new MInvoice(getCtx(), 0, null);
                invoice.setClientOrg(te.getAD_Client_ID(), te.getAD_Org_ID());
                //	API
                invoice.setC_DocTypeTarget_ID(MDocType.DOCBASETYPE_APInvoice);
                invoice.setDocumentNo(te.getDocumentNo());
                //
                invoice.setBPartner(bp);
                if (invoice.getC_BPartner_Location_ID() == 0) {
                    log.log(Level.SEVERE, "No BP Location: " + bp);
                    addLog(0, te.getDateReport(), null, "No Location: " + te.getDocumentNo() + " " + bp.getName());
                    invoice = null;
                    break;
                }
                invoice.setM_PriceList_ID(te.getM_PriceList_ID());
                invoice.setSalesRep_ID(te.getDoc_User_ID());
                String descr = Msg.translate(getCtx(), "S_TimeExpense_ID") + ": " + te.getDocumentNo() + " " + DisplayType.getDateFormat(DisplayType.Date).format(te.getDateReport());
                invoice.setDescription(descr);
                if (!invoice.save())
                    new IllegalStateException("Cannot save Invoice");
                old_BPartner_ID = bp.getC_BPartner_ID();
            }
            MTimeExpenseLine[] tel = te.getLines(false);
            for (int i = 0; i < tel.length; i++) {
                MTimeExpenseLine line = tel[i];
                //	Already Invoiced or nothing to be reimbursed
                if (line.getC_InvoiceLine_ID() != 0 || Env.ZERO.compareTo(line.getQtyReimbursed()) == 0 || Env.ZERO.compareTo(line.getPriceReimbursed()) == 0)
                    continue;
                //	Update Header info
                if (line.getC_Activity_ID() != 0 && line.getC_Activity_ID() != invoice.getC_Activity_ID())
                    invoice.setC_Activity_ID(line.getC_Activity_ID());
                if (line.getC_Campaign_ID() != 0 && line.getC_Campaign_ID() != invoice.getC_Campaign_ID())
                    invoice.setC_Campaign_ID(line.getC_Campaign_ID());
                if (line.getC_Project_ID() != 0 && line.getC_Project_ID() != invoice.getC_Project_ID())
                    invoice.setC_Project_ID(line.getC_Project_ID());
                if (!invoice.save())
                    new IllegalStateException("Cannot save Invoice");
                //	Create OrderLine
                MInvoiceLine il = new MInvoiceLine(invoice);
                //
                if (line.getM_Product_ID() != 0)
                    il.setM_Product_ID(line.getM_Product_ID(), true);
                //	Entered/Invoiced
                il.setQty(line.getQtyReimbursed());
                il.setDescription(line.getDescription());
                //
                il.setC_Project_ID(line.getC_Project_ID());
                il.setC_ProjectPhase_ID(line.getC_ProjectPhase_ID());
                il.setC_ProjectTask_ID(line.getC_ProjectTask_ID());
                il.setC_Activity_ID(line.getC_Activity_ID());
                il.setC_Campaign_ID(line.getC_Campaign_ID());
                //
                //	il.setPrice();	//	not really a list/limit price for reimbursements
                //
                il.setPrice(line.getPriceReimbursed());
                il.setTax();
                if (!il.save())
                    new IllegalStateException("Cannot save Invoice Line");
                //	Update TEL
                line.setC_InvoiceLine_ID(il.getC_InvoiceLine_ID());
                line.saveEx();
            }
        //	for all expense lines
        }
    //	********* Expense Line Loop
    } catch (Exception e) {
        log.log(Level.SEVERE, sql.toString(), e);
    } finally {
        DB.close(rs, pstmt);
        rs = null;
        pstmt = null;
    }
    completeInvoice(invoice);
    return "@Created@=" + m_noInvoices;
}
Also used : MInvoiceLine(org.compiere.model.MInvoiceLine) MInvoice(org.compiere.model.MInvoice) PreparedStatement(java.sql.PreparedStatement) MBPartner(org.compiere.model.MBPartner) ResultSet(java.sql.ResultSet) MTimeExpense(org.compiere.model.MTimeExpense) MTimeExpenseLine(org.compiere.model.MTimeExpenseLine)

Example 15 with MInvoice

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

the class AllocationAuto method allocateBPOldestFirst.

//	allocateBPartnerAll
/**
	 * 	Allocate Oldest First using Accounting currency
	 *	@return allocations
	 */
private int allocateBPOldestFirst() throws Exception {
    int C_Currency_ID = MClient.get(getCtx()).getC_Currency_ID();
    Timestamp dateAcct = null;
    //	Payments
    BigDecimal totalPayments = Env.ZERO;
    for (int p = 0; p < m_payments.length; p++) {
        MPayment payment = m_payments[p];
        if (payment.isAllocated())
            continue;
        if (payment.getC_Currency_ID() != C_Currency_ID)
            continue;
        BigDecimal allocatedAmt = payment.getAllocatedAmt();
        log.info(payment + ", Allocated=" + allocatedAmt);
        BigDecimal availableAmt = payment.getPayAmt().add(payment.getDiscountAmt()).add(payment.getWriteOffAmt()).add(payment.getOverUnderAmt());
        availableAmt = availableAmt.subtract(allocatedAmt);
        if (!payment.isReceipt())
            availableAmt = availableAmt.negate();
        log.fine("Available=" + availableAmt);
        if (dateAcct == null || payment.getDateAcct().after(dateAcct))
            dateAcct = payment.getDateAcct();
        totalPayments = totalPayments.add(availableAmt);
    }
    //	Invoices
    BigDecimal totalInvoices = Env.ZERO;
    for (int i = 0; i < m_invoices.length; i++) {
        MInvoice invoice = m_invoices[i];
        if (invoice.isPaid())
            continue;
        if (invoice.getC_Currency_ID() != C_Currency_ID)
            continue;
        BigDecimal openAmt = invoice.getOpenAmt(true, null);
        log.fine("" + invoice);
        if (!invoice.isSOTrx())
            openAmt = openAmt.negate();
        //	Foreign currency
        log.fine("Open=" + openAmt);
        if (dateAcct == null || invoice.getDateAcct().after(dateAcct))
            dateAcct = invoice.getDateAcct();
        totalInvoices = totalInvoices.add(openAmt);
    }
    //	must be either AP or AR balance
    if (totalInvoices.signum() != totalPayments.signum()) {
        log.fine("Signum - Invoices=" + totalInvoices.signum() + " <> Payments=" + totalPayments.signum());
        return 0;
    }
    BigDecimal difference = totalInvoices.subtract(totalPayments);
    BigDecimal maxAmt = totalInvoices.abs().min(totalPayments.abs());
    if (totalInvoices.signum() < 0)
        maxAmt = maxAmt.negate();
    log.info("= Invoices=" + totalInvoices + " - Payments=" + totalPayments + " = Difference=" + difference + " - Max=" + maxAmt);
    //	Allocate Payments up to max
    BigDecimal allocatedPayments = Env.ZERO;
    for (int p = 0; p < m_payments.length; p++) {
        MPayment payment = m_payments[p];
        if (payment.isAllocated())
            continue;
        if (payment.getC_Currency_ID() != C_Currency_ID)
            continue;
        BigDecimal allocatedAmt = payment.getAllocatedAmt();
        // comment following lines to allow partial allocation
        // if (allocatedAmt != null && allocatedAmt.signum() != 0)
        // 	continue;
        BigDecimal availableAmt = payment.getPayAmt().add(payment.getDiscountAmt()).add(payment.getWriteOffAmt()).add(payment.getOverUnderAmt());
        availableAmt = availableAmt.subtract(allocatedAmt);
        if (!payment.isReceipt())
            availableAmt = availableAmt.negate();
        allocatedPayments = allocatedPayments.add(availableAmt);
        if ((totalInvoices.signum() > 0 && allocatedPayments.compareTo(maxAmt) > 0) || (totalInvoices.signum() < 0 && allocatedPayments.compareTo(maxAmt) < 0)) {
            BigDecimal diff = allocatedPayments.subtract(maxAmt);
            availableAmt = availableAmt.subtract(diff);
            allocatedPayments = allocatedPayments.subtract(diff);
        }
        log.fine("Payment Allocated=" + availableAmt);
        if (!createAllocation(C_Currency_ID, "BP Oldest (" + difference.abs() + ")", dateAcct, availableAmt, null, null, null, payment.getC_BPartner_ID(), payment.getC_Payment_ID(), 0, payment.getAD_Org_ID())) {
            throw new AdempiereSystemError("Cannot create Allocation");
        }
        if (allocatedPayments.compareTo(maxAmt) == 0)
            break;
    }
    //	for all payments
    //	Allocated Invoices up to max
    BigDecimal allocatedInvoices = Env.ZERO;
    for (int i = 0; i < m_invoices.length; i++) {
        MInvoice invoice = m_invoices[i];
        if (invoice.isPaid())
            continue;
        if (invoice.getC_Currency_ID() != C_Currency_ID)
            continue;
        BigDecimal openAmt = invoice.getOpenAmt(true, null);
        if (!invoice.isSOTrx())
            openAmt = openAmt.negate();
        allocatedInvoices = allocatedInvoices.add(openAmt);
        if ((totalInvoices.signum() > 0 && allocatedInvoices.compareTo(maxAmt) > 0) || (totalInvoices.signum() < 0 && allocatedInvoices.compareTo(maxAmt) < 0)) {
            BigDecimal diff = allocatedInvoices.subtract(maxAmt);
            openAmt = openAmt.subtract(diff);
            allocatedInvoices = allocatedInvoices.subtract(diff);
        }
        if (openAmt.signum() == 0)
            break;
        log.fine("Invoice Allocated=" + openAmt);
        if (!createAllocation(C_Currency_ID, "BP Oldest (" + difference.abs() + ")", dateAcct, openAmt, null, null, null, invoice.getC_BPartner_ID(), 0, invoice.getC_Invoice_ID(), invoice.getAD_Org_ID())) {
            throw new AdempiereSystemError("Cannot create Allocation");
        }
        if (allocatedInvoices.compareTo(maxAmt) == 0)
            break;
    }
    if (allocatedPayments.compareTo(allocatedInvoices) != 0) {
        throw new AdempiereSystemError("Allocated Payments=" + allocatedPayments + " <> Invoices=" + allocatedInvoices);
    }
    processAllocation();
    return 1;
}
Also used : AdempiereSystemError(org.compiere.util.AdempiereSystemError) MPayment(org.compiere.model.MPayment) MInvoice(org.compiere.model.MInvoice) Timestamp(java.sql.Timestamp) BigDecimal(java.math.BigDecimal)

Aggregations

MInvoice (org.compiere.model.MInvoice)70 BigDecimal (java.math.BigDecimal)25 MInvoiceLine (org.compiere.model.MInvoiceLine)23 MPayment (org.compiere.model.MPayment)12 ResultSet (java.sql.ResultSet)10 Timestamp (java.sql.Timestamp)10 MBPartner (org.compiere.model.MBPartner)10 MInOut (org.compiere.model.MInOut)10 MOrder (org.compiere.model.MOrder)10 PreparedStatement (java.sql.PreparedStatement)9 MInOutLine (org.compiere.model.MInOutLine)8 MOrderLine (org.compiere.model.MOrderLine)6 ArrayList (java.util.ArrayList)5 AdempiereException (org.adempiere.exceptions.AdempiereException)5 MDocType (org.compiere.model.MDocType)5 KeyNamePair (org.compiere.util.KeyNamePair)5 ValueNamePair (org.compiere.util.ValueNamePair)5 MCashLine (org.compiere.model.MCashLine)4 MClient (org.compiere.model.MClient)4 MProduct (org.compiere.model.MProduct)4