Search in sources :

Example 1 with MDunningLevel

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

the class DunningPrint method doIt.

//	prepare
/**
	 * Process
	 * @return info
	 * @throws Exception
	 */
protected String doIt() throws Exception {
    log.info("C_DunningRun_ID=" + p_C_DunningRun_ID + ",R_MailText_ID=" + p_R_MailText_ID + ", EmailPDF=" + p_EMailPDF + ",IsOnlyIfBPBalance=" + p_IsOnlyIfBPBalance + ",PrintUnprocessedOnly=" + p_PrintUnprocessedOnly);
    //	Need to have Template
    if (p_EMailPDF && p_R_MailText_ID == 0)
        throw new AdempiereUserError("@NotFound@: @R_MailText_ID@");
    //		String subject = "";
    MMailText mText = null;
    if (p_EMailPDF) {
        mText = new MMailText(getCtx(), p_R_MailText_ID, get_TrxName());
        if (p_EMailPDF && mText.get_ID() == 0)
            throw new AdempiereUserError("@NotFound@: @R_MailText_ID@ - " + p_R_MailText_ID);
    //			subject = mText.getMailHeader();
    }
    //
    MDunningRun run = new MDunningRun(getCtx(), p_C_DunningRun_ID, get_TrxName());
    if (run.get_ID() == 0)
        throw new AdempiereUserError("@NotFound@: @C_DunningRun_ID@ - " + p_C_DunningRun_ID);
    MClient client = MClient.get(getCtx());
    int count = 0;
    int errors = 0;
    MDunningRunEntry[] entries = run.getEntries(false);
    for (int i = 0; i < entries.length; i++) {
        MDunningRunEntry entry = entries[i];
        //	Print Format on Dunning Level
        MDunningLevel level = new MDunningLevel(getCtx(), entry.getC_DunningLevel_ID(), get_TrxName());
        MPrintFormat format = null;
        if (level.getDunning_PrintFormat_ID() > 0)
            format = MPrintFormat.get(getCtx(), level.getDunning_PrintFormat_ID(), false);
        if (p_IsOnlyIfBPBalance && entry.getAmt().signum() <= 0)
            continue;
        if (p_PrintUnprocessedOnly && entry.isProcessed())
            continue;
        //	To BPartner
        MBPartner bp = new MBPartner(getCtx(), entry.getC_BPartner_ID(), get_TrxName());
        if (bp.get_ID() == 0) {
            addLog(entry.get_ID(), null, null, "@NotFound@: @C_BPartner_ID@ " + entry.getC_BPartner_ID());
            errors++;
            continue;
        }
        //	To User
        MUser to = new MUser(getCtx(), entry.getAD_User_ID(), get_TrxName());
        if (p_EMailPDF) {
            if (to.get_ID() == 0) {
                addLog(entry.get_ID(), null, null, "@NotFound@: @AD_User_ID@ - " + bp.getName());
                errors++;
                continue;
            } else if (to.getEMail() == null || to.getEMail().length() == 0) {
                addLog(entry.get_ID(), null, null, "@NotFound@: @EMail@ - " + to.getName());
                errors++;
                continue;
            }
        }
        //	query
        MQuery query = new MQuery("C_Dunning_Header_v");
        query.addRestriction("C_DunningRunEntry_ID", MQuery.EQUAL, new Integer(entry.getC_DunningRunEntry_ID()));
        //	Engine
        PrintInfo info = new PrintInfo(bp.getName(), MDunningRunEntry.Table_ID, entry.getC_DunningRunEntry_ID(), entry.getC_BPartner_ID());
        info.setDescription(bp.getName() + ", Amt=" + entry.getAmt());
        ReportEngine re = null;
        if (format != null)
            re = new ReportEngine(getCtx(), format, query, info);
        boolean printed = false;
        if (p_EMailPDF) {
            EMail email = client.createEMail(to.getEMail(), null, null);
            if (!email.isValid()) {
                addLog(entry.get_ID(), null, null, "@RequestActionEMailError@ Invalid EMail: " + to);
                errors++;
                continue;
            }
            //	variable context
            mText.setUser(to);
            mText.setBPartner(bp);
            mText.setPO(entry);
            String message = mText.getMailText(true);
            if (mText.isHtml())
                email.setMessageHTML(mText.getMailHeader(), message);
            else {
                email.setSubject(mText.getMailHeader());
                email.setMessageText(message);
            }
            //
            if (re != null) {
                File attachment = re.getPDF(File.createTempFile("Dunning", ".pdf"));
                log.fine(to + " - " + attachment);
                email.addAttachment(attachment);
            }
            //
            String msg = email.send();
            MUserMail um = new MUserMail(mText, entry.getAD_User_ID(), email);
            um.saveEx();
            if (msg.equals(EMail.SENT_OK)) {
                addLog(entry.get_ID(), null, null, bp.getName() + " @RequestActionEMailOK@");
                count++;
                printed = true;
            } else {
                addLog(entry.get_ID(), null, null, bp.getName() + " @RequestActionEMailError@ " + msg);
                errors++;
            }
        } else {
            if (re != null) {
                re.print();
                count++;
                printed = true;
            }
        }
        if (printed) {
            entry.setProcessed(true);
            entry.save();
        }
    }
    //	for all dunning letters
    if (errors == 0) {
        run.setProcessed(true);
        run.saveEx();
    }
    if (p_EMailPDF)
        return "@Sent@=" + count + " - @Errors@=" + errors;
    return "@Printed@=" + count;
}
Also used : AdempiereUserError(org.compiere.util.AdempiereUserError) MMailText(org.compiere.model.MMailText) MUserMail(org.compiere.model.MUserMail) MQuery(org.compiere.model.MQuery) PrintInfo(org.compiere.model.PrintInfo) MDunningRun(org.compiere.model.MDunningRun) MBPartner(org.compiere.model.MBPartner) EMail(org.compiere.util.EMail) MClient(org.compiere.model.MClient) MDunningRunEntry(org.compiere.model.MDunningRunEntry) MPrintFormat(org.compiere.print.MPrintFormat) ReportEngine(org.compiere.print.ReportEngine) MUser(org.compiere.model.MUser) File(java.io.File) MDunningLevel(org.compiere.model.MDunningLevel)

Example 2 with MDunningLevel

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

the class DunningRunCreate method doIt.

//	prepare
/**
	 * 	Process
	 *	@return message
	 *	@throws Exception
	 */
protected String doIt() throws Exception {
    log.info("C_DunningRun_ID=" + p_C_DunningRun_ID + ", Dispute=" + p_IncludeInDispute + ", C_BP_Group_ID=" + p_C_BP_Group_ID + ", C_BPartner_ID=" + p_C_BPartner_ID);
    m_run = new MDunningRun(getCtx(), p_C_DunningRun_ID, get_TrxName());
    if (m_run.get_ID() == 0)
        throw new IllegalArgumentException("Not found MDunningRun");
    if (!m_run.deleteEntries(true))
        throw new IllegalArgumentException("Cannot delete existing entries");
    if (p_SalesRep_ID == 0)
        throw new IllegalArgumentException("No SalesRep");
    if (p_C_Currency_ID == 0)
        throw new IllegalArgumentException("No Currency");
    //
    for (MDunningLevel l_level : m_run.getLevels()) {
        addInvoices(l_level);
        addPayments(l_level);
        if (l_level.isChargeFee())
            addFees(l_level);
        // we need to check whether this is a statement or not and some other rules
        checkDunningEntry(l_level);
    }
    int entries = DB.getSQLValue(get_TrxName(), "SELECT COUNT(*) FROM C_DunningRunEntry WHERE C_DunningRun_ID=?", m_run.get_ID());
    return "@C_DunningRunEntry_ID@ #" + entries;
}
Also used : MDunningRun(org.compiere.model.MDunningRun) MDunningLevel(org.compiere.model.MDunningLevel)

Example 3 with MDunningLevel

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

the class DunningRunCreate method addInvoices.

//	doIt
/**************************************************************************
	 * 	Add Invoices to Run
	 *  @param level  the Dunning level
	 *  @return no of invoices
	 */
private int addInvoices(MDunningLevel level) {
    int count = 0;
    String sql = "SELECT i.C_Invoice_ID, i.C_Currency_ID," + " i.GrandTotal*i.MultiplierAP," + " invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID)*MultiplierAP," + // ##1/2
    " COALESCE(daysBetween(?,ips.DueDate),paymentTermDueDays(i.C_PaymentTerm_ID,i.DateInvoiced,?))," + " i.IsInDispute, i.C_BPartner_ID, i.C_InvoicePaySchedule_ID " + "FROM C_Invoice_v i " + " LEFT OUTER JOIN C_InvoicePaySchedule ips ON (i.C_InvoicePaySchedule_ID=ips.C_InvoicePaySchedule_ID) " + //	##3
    "WHERE i.IsPaid='N' AND i.AD_Client_ID=?" + " AND i.DocStatus IN ('CO','CL')" + " AND (i.DunningGrace IS NULL OR i.DunningGrace<?) " + //	Only BP(Group) with Dunning defined
    " AND EXISTS (SELECT * FROM C_DunningLevel dl " + //	//	##4
    "WHERE dl.C_DunningLevel_ID=?" + " AND dl.C_Dunning_ID IN " + "(SELECT COALESCE(bp.C_Dunning_ID, bpg.C_Dunning_ID) " + "FROM C_BPartner bp" + " INNER JOIN C_BP_Group bpg ON (bp.C_BP_Group_ID=bpg.C_BP_Group_ID) " + "WHERE i.C_BPartner_ID=bp.C_BPartner_ID" + " AND (bp.DunningGrace IS NULL OR bp.DunningGrace<?)))";
    if (p_C_BPartner_ID != 0)
        //	##5
        sql += " AND i.C_BPartner_ID=?";
    else if (p_C_BP_Group_ID != 0)
        sql += " AND EXISTS (SELECT * FROM C_BPartner bp " + //	##5
        "WHERE i.C_BPartner_ID=bp.C_BPartner_ID AND bp.C_BP_Group_ID=?)";
    if (p_OnlySOTrx)
        sql += " AND i.IsSOTrx='Y'";
    if (!p_IsAllCurrencies)
        sql += " AND i.C_Currency_ID=" + p_C_Currency_ID;
    if (p_AD_Org_ID != 0)
        sql += " AND i.AD_Org_ID=" + p_AD_Org_ID;
    //	log.info(sql);
    String sql2 = null;
    // which this invoice is not yet included!
    if (level.getParent().isCreateLevelsSequentially()) {
        // Build a list of all topmost Dunning Levels
        MDunningLevel[] previousLevels = level.getPreviousLevels();
        if (previousLevels != null && previousLevels.length > 0) {
            String sqlAppend = "";
            for (MDunningLevel element : previousLevels) {
                sqlAppend += " AND i.C_Invoice_ID IN (SELECT C_Invoice_ID FROM C_DunningRunLine WHERE " + "C_DunningRunEntry_ID IN (SELECT C_DunningRunEntry_ID FROM C_DunningRunEntry WHERE " + "C_DunningRun_ID IN (SELECT C_DunningRun_ID FROM C_DunningRunEntry WHERE " + "C_DunningLevel_ID=" + element.get_ID() + ")) AND Processed<>'N')";
            }
            sql += sqlAppend;
        }
    }
    // ensure that we do only dunn what's not yet dunned, so we lookup the max of last Dunn Date which was processed
    sql2 = "SELECT COUNT(*), COALESCE(DAYSBETWEEN(MAX(dr2.DunningDate), MAX(dr.DunningDate)),0)" + "FROM C_DunningRun dr2, C_DunningRun dr" + " INNER JOIN C_DunningRunEntry dre ON (dr.C_DunningRun_ID=dre.C_DunningRun_ID)" + " INNER JOIN C_DunningRunLine drl ON (dre.C_DunningRunEntry_ID=drl.C_DunningRunEntry_ID) " + // ##1 ##2
    "WHERE dr2.C_DunningRun_ID=? AND drl.C_Invoice_ID=?";
    BigDecimal DaysAfterDue = level.getDaysAfterDue();
    int DaysBetweenDunning = level.getDaysBetweenDunning();
    PreparedStatement pstmt = null;
    PreparedStatement pstmt2 = null;
    ResultSet rs = null;
    try {
        pstmt = DB.prepareStatement(sql, get_TrxName());
        pstmt.setTimestamp(1, m_run.getDunningDate());
        pstmt.setTimestamp(2, m_run.getDunningDate());
        pstmt.setInt(3, m_run.getAD_Client_ID());
        pstmt.setTimestamp(4, m_run.getDunningDate());
        pstmt.setInt(5, level.getC_DunningLevel_ID());
        pstmt.setTimestamp(6, m_run.getDunningDate());
        if (p_C_BPartner_ID != 0)
            pstmt.setInt(7, p_C_BPartner_ID);
        else if (p_C_BP_Group_ID != 0)
            pstmt.setInt(7, p_C_BP_Group_ID);
        //
        pstmt2 = DB.prepareStatement(sql2, get_TrxName());
        //
        rs = pstmt.executeQuery();
        while (rs.next()) {
            int C_Invoice_ID = rs.getInt(1);
            int C_Currency_ID = rs.getInt(2);
            BigDecimal GrandTotal = rs.getBigDecimal(3);
            BigDecimal Open = rs.getBigDecimal(4);
            int DaysDue = rs.getInt(5);
            boolean IsInDispute = "Y".equals(rs.getString(6));
            int C_BPartner_ID = rs.getInt(7);
            int C_InvoicePaySchedule_ID = rs.getInt(8);
            log.fine("DaysAfterDue: " + DaysAfterDue.intValue() + " isShowAllDue: " + level.isShowAllDue());
            log.fine("C_Invoice_ID - DaysDue - GrandTotal: " + C_Invoice_ID + " - " + DaysDue + " - " + GrandTotal);
            log.fine("C_InvoicePaySchedule_ID: " + C_InvoicePaySchedule_ID);
            // Check for Dispute
            if (!p_IncludeInDispute && IsInDispute)
                continue;
            // Check the day again based on rulesets
            if (DaysDue > 0 && DaysDue < DaysAfterDue.intValue() && !level.isShowAllDue())
                continue;
            // Check for an open amount
            if (Env.ZERO.compareTo(Open) == 0)
                continue;
            //
            int TimesDunned = 0;
            int DaysAfterLast = 0;
            //	SubQuery
            pstmt2.setInt(1, m_run.get_ID());
            pstmt2.setInt(2, C_Invoice_ID);
            ResultSet rs2 = pstmt2.executeQuery();
            if (rs2.next()) {
                TimesDunned = rs2.getInt(1);
                DaysAfterLast = rs2.getInt(2);
            }
            rs2.close();
            //          there is something which we really must Dunn.
            if (DaysBetweenDunning != 0 && TimesDunned > 0 && DaysAfterLast < DaysBetweenDunning && !level.isShowAllDue() && !level.isShowNotDue())
                continue;
            // We don't want to show non due documents
            if (DaysDue < 0 && !level.isShowNotDue())
                continue;
            // See also checkDunningEntry()
            if (DaysAfterLast < DaysBetweenDunning)
                TimesDunned = TimesDunned * -1;
            //
            if (createInvoiceLine(C_Invoice_ID, C_InvoicePaySchedule_ID, C_Currency_ID, GrandTotal, Open, DaysDue, IsInDispute, C_BPartner_ID, TimesDunned, DaysAfterLast, level.getC_DunningLevel_ID())) {
                count++;
            }
        }
    } catch (Exception e) {
        log.log(Level.SEVERE, "addInvoices", e);
        getProcessInfo().addLog(getProcessInfo().getAD_PInstance_ID(), null, null, e.getLocalizedMessage());
    } finally {
        DB.close(rs, pstmt);
        rs = null;
        pstmt = null;
        pstmt2 = null;
    }
    return count;
}
Also used : ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) BigDecimal(java.math.BigDecimal) BPartnerNoAddressException(org.adempiere.exceptions.BPartnerNoAddressException) MDunningLevel(org.compiere.model.MDunningLevel)

Aggregations

MDunningLevel (org.compiere.model.MDunningLevel)3 MDunningRun (org.compiere.model.MDunningRun)2 File (java.io.File)1 BigDecimal (java.math.BigDecimal)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 BPartnerNoAddressException (org.adempiere.exceptions.BPartnerNoAddressException)1 MBPartner (org.compiere.model.MBPartner)1 MClient (org.compiere.model.MClient)1 MDunningRunEntry (org.compiere.model.MDunningRunEntry)1 MMailText (org.compiere.model.MMailText)1 MQuery (org.compiere.model.MQuery)1 MUser (org.compiere.model.MUser)1 MUserMail (org.compiere.model.MUserMail)1 PrintInfo (org.compiere.model.PrintInfo)1 MPrintFormat (org.compiere.print.MPrintFormat)1 ReportEngine (org.compiere.print.ReportEngine)1 AdempiereUserError (org.compiere.util.AdempiereUserError)1 EMail (org.compiere.util.EMail)1