/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* For the text or an alternative of this public license, you may reach us *
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
* or via info@compiere.org or http://www.compiere.org/license.html *
*****************************************************************************/
package org.compiere.model;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Properties;
import java.util.logging.Level;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.idempiere.cache.ImmutablePOSupport;
/**
* Business Partner Model
*
* @author Jorg Janke
* @version $Id: MBPartner.java,v 1.5 2006/09/23 19:38:07 comdivision Exp $
*
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
*
BF [ 1568774 ] Walk-In BP: invalid created/updated values
* BF [ 1817752 ] MBPartner.getLocations should return only active one
* @author Armen Rizal, GOODWILL CONSULT
* BF [ 2041226 ] BP Open Balance should count only Completed Invoice
* BF [ 2498949 ] BP Get Not Invoiced Shipment Value return null
*/
public class MBPartner extends X_C_BPartner implements ImmutablePOSupport
{
/**
* generated serial id
*/
private static final long serialVersionUID = 2256035503713773448L;
/**
* Create new Business Partner from template (not save)
* @param ctx context
* @param AD_Client_ID client
* @return new Business Partner created from template or null
*/
public static MBPartner getTemplate (Properties ctx, int AD_Client_ID)
{
MBPartner template = getBPartnerCashTrx (ctx, AD_Client_ID);
if (template == null)
template = new MBPartner (ctx, 0, null);
// Reset
if (template != null)
{
template.set_ValueNoCheck ("C_BPartner_ID", Integer.valueOf(0));
template.set_ValueNoCheck ("C_BPartner_UU", (String)null);
template.setAD_OrgBP_ID(0);
template.setLogo_ID(0);
template.setValue ("");
template.setName ("");
template.setName2 (null);
template.setDUNS("");
template.setFirstSale(null);
//
template.setSO_CreditLimit (Env.ZERO);
template.setSO_CreditUsed (Env.ZERO);
template.setTotalOpenBalance (Env.ZERO);
//
template.setActualLifeTimeValue(Env.ZERO);
template.setPotentialLifeTimeValue(Env.ZERO);
template.setAcqusitionCost(Env.ZERO);
template.setShareOfCustomer(0);
template.setSalesVolume(0);
// Reset Created, Updated to current system time ( teo_sarca )
Timestamp ts = new Timestamp(System.currentTimeMillis());
template.set_ValueNoCheck("Created", ts);
template.set_ValueNoCheck("Updated", ts);
template.set_ValueNoCheck("CreatedBy", Env.getAD_User_ID(ctx));
template.set_ValueNoCheck("UpdatedBy", Env.getAD_User_ID(ctx));
}
return template;
} // getTemplate
/**
* Get Cash Trx Business Partner (as template for new BP)
* @param ctx context
* @param AD_Client_ID client
* @return Cash Trx Business Partner or null
*/
public static MBPartner getBPartnerCashTrx (Properties ctx, int AD_Client_ID)
{
MBPartner retValue = (MBPartner) MClientInfo.get(ctx, AD_Client_ID).getC_BPartnerCashTrx();
if (retValue == null)
s_log.log(Level.SEVERE, "Not found for AD_Client_ID=" + AD_Client_ID);
return retValue;
} // getBPartnerCashTrx
/**
* Get BPartner with Value
* @param ctx context
* @param Value value
* @return BPartner or null
*/
public static MBPartner get (Properties ctx, String Value) {
return get(ctx,Value,null);
}
/**
* Get BPartner with Value in a transaction
* @param ctx context
* @param Value value
* @param trxName transaction
* @return BPartner or null
*/
public static MBPartner get (Properties ctx, String Value, String trxName)
{
if (Value == null || Value.length() == 0)
return null;
final String whereClause = "Value=? AND AD_Client_ID=?";
MBPartner retValue = new Query(ctx, I_C_BPartner.Table_Name, whereClause, trxName)
.setParameters(Value,Env.getAD_Client_ID(ctx))
.firstOnly();
return retValue;
} // get
/**
* Get BPartner with taxID in a transaction
* @param ctx context
* @param taxID taxID
* @param trxName transaction
* @return BPartner or null
*/
public static MBPartner getFirstWithTaxID (Properties ctx, String taxID, String trxName)
{
final String whereClause = "TaxID=? AND AD_Client_ID=?";
MBPartner retValue = new Query(ctx, Table_Name, whereClause, trxName)
.setParameters(taxID, Env.getAD_Client_ID(ctx))
.setOrderBy(COLUMNNAME_C_BPartner_ID)
.first();
return retValue;
} // getFirstWithTaxID
/**
* Get BPartner with id
* @param ctx context
* @param C_BPartner_ID
* @return BPartner or null
*/
public static MBPartner get (Properties ctx, int C_BPartner_ID)
{
return get(ctx,C_BPartner_ID,null);
}
/**
* Get BPartner with id in a transaction
* @param ctx context
* @param C_BPartner_ID
* @param trxName transaction
* @return BPartner or null
*/
public static MBPartner get (Properties ctx, int C_BPartner_ID, String trxName)
{
final String whereClause = "C_BPartner_ID=? AND AD_Client_ID=?";
MBPartner retValue = new Query(ctx,I_C_BPartner.Table_Name,whereClause,trxName)
.setParameters(C_BPartner_ID,Env.getAD_Client_ID(ctx))
.firstOnly();
return retValue;
} // get
/**
* Get Not Invoiced Shipment Value
* @param C_BPartner_ID partner
* @return value in accounting currency
*/
public static BigDecimal getNotInvoicedAmt (int C_BPartner_ID)
{
BigDecimal retValue = null;
String sql = "SELECT COALESCE(SUM(COALESCE("
+ "currencyBase((ol.QtyDelivered-ol.QtyInvoiced)*ol.PriceActual,o.C_Currency_ID,o.DateOrdered, o.AD_Client_ID,o.AD_Org_ID) ,0)),0) "
+ "FROM C_OrderLine ol"
+ " INNER JOIN C_Order o ON (ol.C_Order_ID=o.C_Order_ID) "
+ "WHERE o.IsSOTrx='Y' AND Bill_BPartner_ID=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement (sql, null);
pstmt.setInt (1, C_BPartner_ID);
rs = pstmt.executeQuery ();
if (rs.next ())
retValue = rs.getBigDecimal(1);
}
catch (Exception e)
{
s_log.log(Level.SEVERE, sql, e);
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
return retValue;
} // getNotInvoicedAmt
/** Static Logger */
private static CLogger s_log = CLogger.getCLogger (MBPartner.class);
/**
* Constructor for new BPartner from Template
* @param ctx context
*/
public MBPartner (Properties ctx)
{
this (ctx, -1, null);
} // MBPartner
/**
* @param ctx context
* @param rs ResultSet to load from
* @param trxName transaction
*/
public MBPartner (Properties ctx, ResultSet rs, String trxName)
{
super(ctx, rs, trxName);
} // MBPartner
/**
* UUID based Constructor
* @param ctx Context
* @param C_BPartner_UU UUID key
* @param trxName Transaction
*/
public MBPartner(Properties ctx, String C_BPartner_UU, String trxName) {
super(ctx, C_BPartner_UU, trxName);
if (Util.isEmpty(C_BPartner_UU))
setInitialDefaults();
}
/**
* @param ctx context
* @param C_BPartner_ID partner or 0 or -1 (load from template)
* @param trxName transaction
*/
public MBPartner (Properties ctx, int C_BPartner_ID, String trxName)
{
super (ctx, C_BPartner_ID, trxName);
//
if (C_BPartner_ID == -1)
{
initTemplate (Env.getContextAsInt(ctx, "AD_Client_ID"));
C_BPartner_ID = 0;
}
if (C_BPartner_ID == 0)
setInitialDefaults();
if (log.isLoggable(Level.FINE)) log.fine(toString());
} // MBPartner
/**
* Set the initial defaults for a new record
*/
private void setInitialDefaults() {
//
setIsCustomer (true);
setIsProspect (true);
//
setSendEMail (false);
setIsOneTime (false);
setIsVendor (false);
setIsSummary (false);
setIsEmployee (false);
setIsSalesRep (false);
setIsTaxExempt(false);
setIsPOTaxExempt(false);
setIsDiscountPrinted(false);
//
setSO_CreditLimit (Env.ZERO);
setSO_CreditUsed (Env.ZERO);
setTotalOpenBalance (Env.ZERO);
setSOCreditStatus(SOCREDITSTATUS_NoCreditCheck);
//
setFirstSale(null);
setActualLifeTimeValue(Env.ZERO);
setPotentialLifeTimeValue(Env.ZERO);
setAcqusitionCost(Env.ZERO);
setShareOfCustomer(0);
setSalesVolume(0);
}
/**
* Import Constructor
* @param impBP import
*/
public MBPartner (X_I_BPartner impBP)
{
this (impBP.getCtx(), 0, impBP.get_TrxName());
setClientOrg(impBP);
setUpdatedBy(impBP.getUpdatedBy());
//
String value = impBP.getValue();
if (value == null || value.length() == 0)
value = impBP.getEMail();
if (value == null || value.length() == 0)
value = impBP.getContactName();
setValue(value);
String name = impBP.getName();
if (name == null || name.length() == 0)
name = impBP.getContactName();
if (name == null || name.length() == 0)
name = impBP.getEMail();
setName(name);
setName2(impBP.getName2());
setDescription(impBP.getDescription());
// setHelp(impBP.getHelp());
setDUNS(impBP.getDUNS());
setTaxID(impBP.getTaxID());
setNAICS(impBP.getNAICS());
setC_BP_Group_ID(impBP.getC_BP_Group_ID());
} // MBPartner
/**
* Copy constructor
* @param copy
*/
public MBPartner(MBPartner copy)
{
this(Env.getCtx(), copy);
}
/**
* Copy constructor
* @param ctx
* @param copy
*/
public MBPartner(Properties ctx, MBPartner copy)
{
this(ctx, copy, (String) null);
}
/**
* Copy constructor
* @param ctx
* @param copy
* @param trxName
*/
public MBPartner(Properties ctx, MBPartner copy, String trxName)
{
this(ctx, 0, trxName);
copyPO(copy);
this.m_contacts = copy.m_contacts != null ? Arrays.stream(copy.m_contacts).map(e -> {return new MUser(ctx, e, trxName);}).toArray(MUser[]::new) : null;
this.m_locations = copy.m_locations != null ? Arrays.stream(copy.m_locations).map(e -> {return new MBPartnerLocation(ctx, e, trxName);}).toArray(MBPartnerLocation[]::new) : null;
this.m_accounts = copy.m_accounts != null ? Arrays.stream(copy.m_accounts).map(e -> {return new MBPBankAccount(ctx, e, trxName);}).toArray(MBPBankAccount[]::new) : null;
this.m_primaryC_BPartner_Location_ID = copy.m_primaryC_BPartner_Location_ID;
this.m_primaryAD_User_ID = copy.m_primaryAD_User_ID;
this.m_group = copy.m_group != null ? new MBPGroup(ctx, copy.m_group, trxName) : null;
}
/**
* @param ctx
* @param C_BPartner_ID
* @param trxName
* @param virtualColumns
*/
public MBPartner(Properties ctx, int C_BPartner_ID, String trxName, String... virtualColumns) {
super(ctx, C_BPartner_ID, trxName, virtualColumns);
}
/** Users */
protected MUser[] m_contacts = null;
/** Addressed */
protected MBPartnerLocation[] m_locations = null;
/** BP Bank Accounts */
protected MBPBankAccount[] m_accounts = null;
/** Prim Address */
protected Integer m_primaryC_BPartner_Location_ID = null;
/** Prim User */
protected Integer m_primaryAD_User_ID = null;
/** BP Group */
protected MBPGroup m_group = null;
/**
* Initialize BPartner record from template
* @param AD_Client_ID client
* @return true if loaded
*/
protected boolean initTemplate (int AD_Client_ID)
{
if (AD_Client_ID == 0)
throw new IllegalArgumentException ("Client_ID=0");
boolean success = true;
String sql = "SELECT * FROM C_BPartner "
+ "WHERE C_BPartner_ID IN (SELECT C_BPartnerCashTrx_ID FROM AD_ClientInfo WHERE AD_Client_ID=?)";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, AD_Client_ID);
rs = pstmt.executeQuery();
if (rs.next())
success = load (rs);
else
{
load(0, null);
success = false;
log.severe ("None found");
}
}
catch (Exception e)
{
log.log(Level.SEVERE, sql, e);
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
setStandardDefaults();
// Reset
set_ValueNoCheck ("C_BPartner_ID", I_ZERO);
setValue ("");
setName ("");
setName2(null);
set_ValueNoCheck ("C_BPartner_UU", "");
return success;
} // getTemplate
/**
* Get All Contacts
* @param reload true to reload from DB
* @return contacts
*/
public MUser[] getContacts (boolean reload)
{
if (reload || m_contacts == null || m_contacts.length == 0)
;
else
return m_contacts;
//
ArrayList list = new ArrayList();
final String sql = "SELECT * FROM AD_User WHERE C_BPartner_ID=? AND IsActive = 'Y' ORDER BY AD_User_ID";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, get_TrxName());
pstmt.setInt(1, getC_BPartner_ID());
rs = pstmt.executeQuery();
while (rs.next())
list.add(new MUser (getCtx(), rs, get_TrxName()));
}
catch (Exception e)
{
log.log(Level.SEVERE, sql, e);
}
finally
{
DB.close(rs, pstmt);
rs = null; pstmt = null;
}
m_contacts = new MUser[list.size()];
list.toArray(m_contacts);
return m_contacts;
} // getContacts
/**
* Get specified or first Contact
* @param AD_User_ID optional user
* @return contact or null
*/
public MUser getContact (int AD_User_ID)
{
MUser[] users = getContacts(false);
if (users.length == 0)
return null;
for (int i = 0; AD_User_ID != 0 && i < users.length; i++)
{
if (users[i].getAD_User_ID() == AD_User_ID)
return users[i];
}
return users[0];
} // getContact
/**
* Get All Locations (only active)
* @param reload true to reload from DB
* @return locations
*/
public MBPartnerLocation[] getLocations (boolean reload)
{
if (reload || m_locations == null || m_locations.length == 0)
;
else
return m_locations;
//
ArrayList list = new ArrayList();
final String sql = "SELECT * FROM C_BPartner_Location WHERE C_BPartner_ID=? AND IsActive='Y'"
+ " ORDER BY C_BPartner_Location_ID";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, get_TrxName());
pstmt.setInt(1, getC_BPartner_ID());
rs = pstmt.executeQuery();
while (rs.next())
list.add(new MBPartnerLocation (getCtx(), rs, get_TrxName()));
}
catch (Exception e)
{
log.log(Level.SEVERE, sql, e);
}
finally
{
DB.close(rs, pstmt);
rs = null; pstmt = null;
}
m_locations = new MBPartnerLocation[list.size()];
list.toArray(m_locations);
return m_locations;
} // getLocations
/**
* Get location for C_BPartner_Location_ID or first bill Location or first location
* @param C_BPartner_Location_ID optional explicit location
* @return location or null
*/
public MBPartnerLocation getLocation(int C_BPartner_Location_ID)
{
MBPartnerLocation[] locations = getLocations(false);
if (locations.length == 0)
return null;
MBPartnerLocation retValue = null;
for (int i = 0; i < locations.length; i++)
{
if (locations[i].getC_BPartner_Location_ID() == C_BPartner_Location_ID)
return locations[i];
if (retValue == null && locations[i].isBillTo())
retValue = locations[i];
}
if (retValue == null)
return locations[0];
return retValue;
} // getLocation
/**
* Get Bank Accounts
* @param requery true to reload from DB
* @return Bank Accounts
*/
public MBPBankAccount[] getBankAccounts (boolean requery)
{
if (m_accounts != null && m_accounts.length >= 0 && !requery) // re-load
return m_accounts;
//
ArrayList list = new ArrayList();
String sql = "SELECT * FROM C_BP_BankAccount WHERE C_BPartner_ID=? AND IsActive='Y'";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, get_TrxName());
pstmt.setInt(1, getC_BPartner_ID());
rs = pstmt.executeQuery();
while (rs.next())
list.add(new MBPBankAccount (getCtx(), rs, get_TrxName()));
}
catch (Exception e)
{
log.log(Level.SEVERE, sql, e);
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
m_accounts = new MBPBankAccount[list.size()];
list.toArray(m_accounts);
return m_accounts;
} // getBankAccounts
/**
* String Representation
* @return info
*/
@Override
public String toString ()
{
StringBuilder sb = new StringBuilder ("MBPartner[ID=")
.append(get_ID())
.append(",Value=").append(getValue())
.append(",Name=").append(getName())
.append(",Open=").append(getTotalOpenBalance())
.append ("]");
return sb.toString ();
} // toString
/**
* Set Client/Org
* @param AD_Client_ID client
* @param AD_Org_ID org
*/
@Override
public void setClientOrg (int AD_Client_ID, int AD_Org_ID)
{
super.setClientOrg(AD_Client_ID, AD_Org_ID);
} // setClientOrg
/**
* Get Linked Organization.
* (is Button)
* The Business Partner is another Organization
* for explicit Inter-Org transactions
* @return AD_Org_ID if BP
* @deprecated
*/
@Deprecated(forRemoval = true, since = "11")
public int getAD_OrgBP_ID_Int()
{
return getAD_OrgBP_ID();
} // getAD_OrgBP_ID_Int
/**
* Get Primary C_BPartner_Location_ID (First BillTo or First)
* @return C_BPartner_Location_ID
*/
public int getPrimaryC_BPartner_Location_ID()
{
if (m_primaryC_BPartner_Location_ID == null)
{
MBPartnerLocation[] locs = getLocations(false);
for (int i = 0; m_primaryC_BPartner_Location_ID == null && i < locs.length; i++)
{
if (locs[i].isBillTo())
{
setPrimaryC_BPartner_Location_ID (locs[i].getC_BPartner_Location_ID());
break;
}
}
// get first
if (m_primaryC_BPartner_Location_ID == null && locs.length > 0)
setPrimaryC_BPartner_Location_ID (locs[0].getC_BPartner_Location_ID());
}
if (m_primaryC_BPartner_Location_ID == null)
return 0;
return m_primaryC_BPartner_Location_ID.intValue();
} // getPrimaryC_BPartner_Location_ID
/**
* Get Primary C_BPartner_Location (BillTo or First)
* @return C_BPartner_Location
*/
public MBPartnerLocation getPrimaryC_BPartner_Location()
{
if (m_primaryC_BPartner_Location_ID == null)
{
m_primaryC_BPartner_Location_ID = getPrimaryC_BPartner_Location_ID();
}
if (m_primaryC_BPartner_Location_ID == null)
return null;
return new MBPartnerLocation(getCtx(), m_primaryC_BPartner_Location_ID, null);
} // getPrimaryC_BPartner_Location
/**
* Get Primary AD_User_ID
* @return AD_User_ID or 0
*/
public int getPrimaryAD_User_ID()
{
if (m_primaryAD_User_ID == null)
{
MUser[] users = getContacts(false);
if (m_primaryAD_User_ID == null && users.length > 0)
setPrimaryAD_User_ID(users[0].getAD_User_ID());
}
if (m_primaryAD_User_ID == null)
return 0;
return m_primaryAD_User_ID.intValue();
} // getPrimaryAD_User_ID
/**
* Set Primary C_BPartner_Location_ID
* @param C_BPartner_Location_ID id
*/
public void setPrimaryC_BPartner_Location_ID(int C_BPartner_Location_ID)
{
m_primaryC_BPartner_Location_ID = Integer.valueOf(C_BPartner_Location_ID);
} // setPrimaryC_BPartner_Location_ID
/**
* Set Primary AD_User_ID
* @param AD_User_ID id
*/
public void setPrimaryAD_User_ID(int AD_User_ID)
{
m_primaryAD_User_ID = Integer.valueOf(AD_User_ID);
} // setPrimaryAD_User_ID
/**
* Calculate Total Open Balance and SO_CreditUsed.
*/
public void setTotalOpenBalance ()
{
log.info("");
BigDecimal SO_CreditUsed = null;
BigDecimal TotalOpenBalance = null;
//AZ Goodwill -> BF2041226 : only count completed/closed docs.
String sql = "SELECT "
// SO Credit Used
+ "COALESCE((SELECT SUM(currencyBase(invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID),i.C_Currency_ID,i.DateInvoiced, i.AD_Client_ID,i.AD_Org_ID)) FROM C_Invoice_v i "
+ "WHERE i.C_BPartner_ID=bp.C_BPartner_ID AND i.IsSOTrx='Y' AND i.IsPaid='N' AND i.DocStatus IN ('CO','CL')),0), "
// Balance (incl. unallocated payments)
+ "COALESCE((SELECT SUM(currencyBase(invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID),i.C_Currency_ID,i.DateInvoiced, i.AD_Client_ID,i.AD_Org_ID)*i.MultiplierAP) FROM C_Invoice_v i "
+ "WHERE i.C_BPartner_ID=bp.C_BPartner_ID AND i.IsPaid='N' AND i.DocStatus IN ('CO','CL')),0) - "
+ "COALESCE((SELECT SUM(currencyBase(Paymentavailable(p.C_Payment_ID),p.C_Currency_ID,p.DateTrx,p.AD_Client_ID,p.AD_Org_ID)) FROM C_Payment_v p "
+ "WHERE p.C_BPartner_ID=bp.C_BPartner_ID AND p.IsAllocated='N'"
+ " AND p.C_Charge_ID IS NULL AND p.DocStatus IN ('CO','CL')),0) "
+ "FROM C_BPartner bp "
+ "WHERE C_BPartner_ID=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement (sql, get_TrxName());
pstmt.setInt (1, getC_BPartner_ID());
rs = pstmt.executeQuery ();
if (rs.next ())
{
SO_CreditUsed = rs.getBigDecimal(1);
TotalOpenBalance = rs.getBigDecimal(2);
}
}
catch (Exception e)
{
log.log(Level.SEVERE, sql, e);
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
//
if (SO_CreditUsed != null)
super.setSO_CreditUsed (SO_CreditUsed);
if (TotalOpenBalance != null)
super.setTotalOpenBalance(TotalOpenBalance);
setSOCreditStatus();
} // setTotalOpenBalance
/**
* Calculate Actual Life Time Invoiced Value from DB
*/
public void setActualLifeTimeValue()
{
BigDecimal ActualLifeTimeValue = null;
//AZ Goodwill -> BF2041226 : only count completed/closed docs.
String sql = "SELECT "
+ "COALESCE ((SELECT SUM(currencyBase(i.GrandTotal,i.C_Currency_ID,i.DateInvoiced, i.AD_Client_ID,i.AD_Org_ID)) FROM C_Invoice_v i "
+ "WHERE i.C_BPartner_ID=bp.C_BPartner_ID AND i.IsSOTrx='Y' AND i.DocStatus IN ('CO','CL')),0) "
+ "FROM C_BPartner bp "
+ "WHERE C_BPartner_ID=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement (sql, get_TrxName());
pstmt.setInt (1, getC_BPartner_ID());
rs = pstmt.executeQuery ();
if (rs.next ())
ActualLifeTimeValue = rs.getBigDecimal(1);
}
catch (Exception e)
{
log.log(Level.SEVERE, sql, e);
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
if (ActualLifeTimeValue != null)
super.setActualLifeTimeValue (ActualLifeTimeValue);
} // setActualLifeTimeValue
/**
* Update Credit Status for sales transaction
*/
public void setSOCreditStatus ()
{
BigDecimal creditLimit = getSO_CreditLimit();
// Nothing to do
if (SOCREDITSTATUS_NoCreditCheck.equals(getSOCreditStatus())
|| SOCREDITSTATUS_CreditStop.equals(getSOCreditStatus())
|| Env.ZERO.compareTo(creditLimit) == 0)
return;
// Above Credit Limit
if (creditLimit.compareTo(getTotalOpenBalance()) < 0)
setSOCreditStatus(SOCREDITSTATUS_CreditHold);
else
{
// Above Watch Limit
BigDecimal watchAmt = creditLimit.multiply(getCreditWatchRatio());
if (watchAmt.compareTo(getTotalOpenBalance()) < 0)
setSOCreditStatus(SOCREDITSTATUS_CreditWatch);
else // is OK
setSOCreditStatus (SOCREDITSTATUS_CreditOK);
}
} // setSOCreditStatus
/**
* Get SO CreditStatus with additional amount
* @param additionalAmt additional amount in Accounting Currency
* @return simulated credit status
*/
public String getSOCreditStatus (BigDecimal additionalAmt)
{
if (additionalAmt == null || additionalAmt.signum() == 0)
return getSOCreditStatus();
//
BigDecimal creditLimit = getSO_CreditLimit();
// Nothing to do
if (SOCREDITSTATUS_NoCreditCheck.equals(getSOCreditStatus())
|| SOCREDITSTATUS_CreditStop.equals(getSOCreditStatus())
|| Env.ZERO.compareTo(creditLimit) == 0)
return getSOCreditStatus();
// Above (reduced) Credit Limit
creditLimit = creditLimit.subtract(additionalAmt);
if (creditLimit.compareTo(getTotalOpenBalance()) < 0)
return SOCREDITSTATUS_CreditHold;
// Above Watch Limit
BigDecimal watchAmt = creditLimit.multiply(getCreditWatchRatio());
if (watchAmt.compareTo(getTotalOpenBalance()) < 0)
return SOCREDITSTATUS_CreditWatch;
// is OK
return SOCREDITSTATUS_CreditOK;
} // getSOCreditStatus
/**
* Get Credit Watch Ratio
* @return BP Group ratio or 0.9
*/
public BigDecimal getCreditWatchRatio()
{
return getBPGroup().getCreditWatchRatio();
} // getCreditWatchRatio
/**
* Credit Status is Stop or Hold.
* @return true if Stop/Hold
*/
public boolean isCreditStopHold()
{
String status = getSOCreditStatus();
return SOCREDITSTATUS_CreditStop.equals(status)
|| SOCREDITSTATUS_CreditHold.equals(status);
} // isCreditStopHold
/**
* Get BP Group
* @return group
*/
public MBPGroup getBPGroup()
{
if (m_group == null)
{
if (getC_BP_Group_ID() == 0)
m_group = MBPGroup.getDefault(getCtx());
else
m_group = MBPGroup.getCopy(getCtx(), getC_BP_Group_ID(), get_TrxName());
}
return m_group;
} // getBPGroup
/**
* Set BP Group
* @param group group
*/
public void setBPGroup(MBPGroup group)
{
m_group = group;
if (m_group == null)
return;
setC_BP_Group_ID(m_group.getC_BP_Group_ID());
if (m_group.getC_Dunning_ID() != 0)
setC_Dunning_ID(m_group.getC_Dunning_ID());
if (m_group.getM_PriceList_ID() != 0)
setM_PriceList_ID(m_group.getM_PriceList_ID());
if (m_group.getPO_PriceList_ID() != 0)
setPO_PriceList_ID(m_group.getPO_PriceList_ID());
if (m_group.getM_DiscountSchema_ID() != 0)
setM_DiscountSchema_ID(m_group.getM_DiscountSchema_ID());
if (m_group.getPO_DiscountSchema_ID() != 0)
setPO_DiscountSchema_ID(m_group.getPO_DiscountSchema_ID());
} // setBPGroup
/**
* Get PriceList ID
* @return BP M_PriceList_ID or BP Group M_PriceList_ID
*/
public int getM_PriceList_ID ()
{
int ii = super.getM_PriceList_ID();
if (ii == 0)
ii = getBPGroup().getM_PriceList_ID();
return ii;
} // getM_PriceList_ID
/**
* Get PO PriceList ID
* @return BP PO price list id or BP Group PO price list id
*/
public int getPO_PriceList_ID ()
{
int ii = super.getPO_PriceList_ID();
if (ii == 0)
ii = getBPGroup().getPO_PriceList_ID();
return ii;
} //
/**
* Get DiscountSchema id
* @return Discount Schema id
*/
public int getM_DiscountSchema_ID ()
{
int ii = super.getM_DiscountSchema_ID ();
if (ii == 0)
ii = getBPGroup().getM_DiscountSchema_ID();
return ii;
} // getM_DiscountSchema_ID
/**
* Get PO DiscountSchema id
* @return po discount schema id
*/
public int getPO_DiscountSchema_ID ()
{
int ii = super.getPO_DiscountSchema_ID ();
if (ii == 0)
ii = getBPGroup().getPO_DiscountSchema_ID();
return ii;
} // getPO_DiscountSchema_ID
@Override
protected boolean beforeSave (boolean newRecord)
{
// Set default from BP Group (for new record or if C_BP_Group_ID has change)
if (newRecord || is_ValueChanged("C_BP_Group_ID"))
{
MBPGroup grp = getBPGroup();
if (grp == null)
{
log.saveError("Error", Msg.parseTranslation(getCtx(), "@NotFound@: @C_BP_Group_ID@"));
return false;
}
setBPGroup(grp); // setDefaults
}
return true;
} // beforeSave
@Override
protected boolean afterSave (boolean newRecord, boolean success)
{
if (!success)
return success;
if (newRecord)
{
// Create Tree Record
insert_Tree(MTree_Base.TREETYPE_BPartner);
// Create Accounting Record
StringBuilder msgacc = new StringBuilder("p.C_BP_Group_ID=")
.append(getC_BP_Group_ID() > MTable.MAX_OFFICIAL_ID && Env.isLogMigrationScript(get_TableName())
? "toRecordId('C_BP_Group',"+DB.TO_STRING(MBPGroup.get(getC_BP_Group_ID()).getC_BP_Group_UU())+")"
: getC_BP_Group_ID());
insert_Accounting("C_BP_Customer_Acct", "C_BP_Group_Acct", msgacc.toString());
insert_Accounting("C_BP_Vendor_Acct", "C_BP_Group_Acct",msgacc.toString());
}
if (newRecord || is_ValueChanged(COLUMNNAME_Value))
update_Tree(MTree_Base.TREETYPE_BPartner);
// Value/Name change, update Combination and Description of C_ValidCombination
if (!newRecord
&& (is_ValueChanged("Value") || is_ValueChanged("Name"))){
StringBuilder msgacc = new StringBuilder("C_BPartner_ID=").append(getC_BPartner_ID());
MAccount.updateValueDescription(getCtx(), msgacc.toString(), get_TrxName());
}
return success;
} // afterSave
@Override
protected boolean afterDelete (boolean success)
{
// Delete tree record
if (success)
delete_Tree(MTree_Base.TREETYPE_BPartner);
return success;
} // afterDelete
@Override
protected boolean postDelete() {
if (getLogo_ID() > 0) {
MImage img = new MImage(getCtx(), getLogo_ID(), get_TrxName());
if (!img.delete(true)) {
log.warning("Associated image could not be deleted for bpartner - AD_Image_ID=" + getLogo_ID());
return false;
}
}
return true;
}
@Override
public MBPartner markImmutable() {
if (is_Immutable())
return this;
makeImmutable();
return this;
}
} // MBPartner