⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 doc_allocation.java

📁 大家共享愉快, 共享愉快, 共享愉快, 共享愉快,共享愉快
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		catch (Exception e)
		{
			pstmt = null;
		}
		
		//
		if (getC_BankAccount_ID() <= 0)
		{
			log.log(Level.SEVERE, "NONE for C_Payment_ID=" + C_Payment_ID);
			return null;
		}
		return getAccount (accountType, as);
	}	//	getPaymentAcct
	
	/**
	 * 	Get Cash (Transfer) Acct of CashBook
	 *	@param as accounting schema
	 *	@param C_CashLine_ID
	 *	@return acct
	 */
	private MAccount getCashAcct (MAcctSchema as, int C_CashLine_ID)
	{
		String sql = "SELECT c.C_CashBook_ID "
			+ "FROM C_Cash c, C_CashLine cl "
			+ "WHERE c.C_Cash_ID=cl.C_Cash_ID AND cl.C_CashLine_ID=?";
		setC_CashBook_ID(DB.getSQLValue(null, sql, C_CashLine_ID));
		if (getC_CashBook_ID() <= 0)
		{
			log.log(Level.SEVERE, "NONE for C_CashLine_ID=" + C_CashLine_ID);
			return null;
		}
		return getAccount(Doc.ACCTTYPE_CashTransfer, as);
	}	//	getCashAcct
	

	/**************************************************************************
	 * 	Create Realized Gain & Loss.
	 * 	Compares the Accounted Amount of the Invoice to the
	 * 	Accounted Amount of the Allocation
	 *	@param as accounting schema
	 *	@param fact fact
	 *	@param invoice invoice
	 *	@param allocationSource source amt
	 *	@param allocationAccounted acct amt
	 *	@return Error Message or null if OK
	 */
	private String createRealizedGainLoss (MAcctSchema as, Fact fact, MAccount acct,
		MInvoice invoice, BigDecimal allocationSource, BigDecimal allocationAccounted)
	{
		BigDecimal invoiceSource = null;
		BigDecimal invoiceAccounted = null;
		//
		String sql = "SELECT " 
			+ (invoice.isSOTrx() 
				? "SUM(AmtSourceDr), SUM(AmtAcctDr)"	//	so 
				: "SUM(AmtSourceCr), SUM(AmtAcctCr)")	//	po
			+ " FROM Fact_Acct "
			+ "WHERE AD_Table_ID=318 AND Record_ID=?"	//	Invoice
			+ " AND C_AcctSchema_ID=?"
			+ " AND PostingType='A'";
			//AND C_Currency_ID=102
		PreparedStatement pstmt = null;
		try
		{
			pstmt = DB.prepareStatement(sql, getTrxName());
			pstmt.setInt(1, invoice.getC_Invoice_ID());
			pstmt.setInt(2, as.getC_AcctSchema_ID());
			ResultSet rs = pstmt.executeQuery();
			if (rs.next())
			{
				invoiceSource = rs.getBigDecimal(1);
				invoiceAccounted = rs.getBigDecimal(2);
			}
			rs.close();
			pstmt.close();
			pstmt = null;
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, sql, e);
		}
		try
		{
			if (pstmt != null)
				pstmt.close();
			pstmt = null;
		}
		catch (Exception e)
		{
			pstmt = null;
		}
		// 	Requires that Invoice is Posted
		if (invoiceSource == null || invoiceAccounted == null)
			return "Gain/Loss - Invoice not posted yet";
		//
		String description = "Invoice=(" + invoice.getC_Currency_ID() + ")" + invoiceSource + "/" + invoiceAccounted
			+ " - Allocation=(" + getC_Currency_ID() + ")" + allocationSource + "/" + allocationAccounted;
		log.fine(description);
		//	Allocation not Invoice Currency
		if (getC_Currency_ID() != invoice.getC_Currency_ID())
		{
			BigDecimal allocationSourceNew = MConversionRate.convert(getCtx(), 
				allocationSource, getC_Currency_ID(), 
				invoice.getC_Currency_ID(), getDateAcct(), 
				invoice.getC_ConversionType_ID(), invoice.getAD_Client_ID(), invoice.getAD_Org_ID());
			if (allocationSourceNew == null)
				return "Gain/Loss - No Conversion from Allocation->Invoice";
			String d2 = "Allocation=(" + getC_Currency_ID() + ")" + allocationSource 
				+ "->(" + invoice.getC_Currency_ID() + ")" + allocationSourceNew;
			log.fine(d2);
			description += " - " + d2;
			allocationSource = allocationSourceNew;
		}

		BigDecimal acctDifference = null;	//	gain is negative
		//	Full Payment in currency
		if (allocationSource.compareTo(invoiceSource) == 0)
		{
			acctDifference = invoiceAccounted.subtract(allocationAccounted);	//	gain is negative
			String d2 = "(full) = " + acctDifference;
			log.fine(d2);
			description += " - " + d2;
		}
		else	//	partial or MC
		{
			//	percent of total payment
			double multiplier = allocationSource.doubleValue() / invoiceSource.doubleValue();
			//	Reduce Orig Invoice Accounted
			invoiceAccounted = invoiceAccounted.multiply(new BigDecimal(multiplier));
			//	Difference based on percentage of Orig Invoice
			acctDifference = invoiceAccounted.subtract(allocationAccounted);	//	gain is negative
			//	ignore Tolerance
			if (acctDifference.abs().compareTo(TOLERANCE) < 0)
				acctDifference = Env.ZERO;
			//	Round
			int precision = as.getStdPrecision();
			if (acctDifference.scale() > precision)
				acctDifference = acctDifference.setScale(precision, BigDecimal.ROUND_HALF_UP);
			String d2 = "(partial) = " + acctDifference + " - Multiplier=" + multiplier;
			log.fine(d2);
			description += " - " + d2;
		}
		
		if (acctDifference.signum() == 0)
		{
			log.fine("No Difference");
			return null;
		}
		
		MAccount gain = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedGain_Acct());
		MAccount loss = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedLoss_Acct());
		//
		if (invoice.isSOTrx())
		{
			FactLine fl = fact.createLine (null, loss, gain, 
				as.getC_Currency_ID(), acctDifference);
			fl.setDescription(description);
			fact.createLine (null, acct, 
				as.getC_Currency_ID(), acctDifference.negate());
			fl.setDescription(description);
		}
		else
		{
			fact.createLine (null, acct,
				as.getC_Currency_ID(), acctDifference);
			FactLine fl = fact.createLine (null, loss, gain, 
				as.getC_Currency_ID(), acctDifference.negate());
		}
		return null;
	}	//	createRealizedGainLoss


	/**************************************************************************
	 * 	Create Tax Correction.
	 * 	Requirement: Adjust the tax amount, if you did not receive the full
	 * 	amount of the invoice (payment discount, write-off).
	 * 	Applies to many countries with VAT.
	 * 	Example:
	 * 		Invoice:	Net $100 + Tax1 $15 + Tax2 $5 = Total $120
	 * 		Payment:	$115 (i.e. $5 underpayment)
	 * 		Tax Adjustment = Tax1 = 0.63 (15/120*5) Tax2 = 0.21 (5/120/5) 
	 * 
	 * 	@param as accounting schema
	 * 	@param fact fact
	 *	@param DiscountAccount discount acct
	 *	@param WriteOffAccoint write off acct
	 *	@return true if created
	 */
	private boolean createTaxCorrection (MAcctSchema as, Fact fact, 
		DocLine_Allocation line,
		MAccount DiscountAccount, MAccount WriteOffAccoint)
	{
		log.info ("createTaxCorrection - " + line);
		Doc_AllocationTax tax = new Doc_AllocationTax (
			DiscountAccount, line.getDiscountAmt(),
			WriteOffAccoint, line.getWriteOffAmt());
		
		//	Get Source Amounts with account
		String sql = "SELECT * "
			+ "FROM Fact_Acct "
			+ "WHERE AD_Table_ID=318 AND Record_ID=?"	//	Invoice
			+ " AND C_AcctSchema_ID=?"
			+ " AND Line_ID IS NULL";	//	header lines like tax or total
		PreparedStatement pstmt = null;
		try
		{
			pstmt = DB.prepareStatement(sql, getTrxName());
			pstmt.setInt(1, line.getC_Invoice_ID());
			pstmt.setInt(2, as.getC_AcctSchema_ID());
			ResultSet rs = pstmt.executeQuery();
			while (rs.next())
				tax.addInvoiceFact (new MFactAcct(getCtx(), rs, fact.get_TrxName()));
			rs.close();
			pstmt.close();
			pstmt = null;
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, sql, e);
		}
		try
		{
			if (pstmt != null)
				pstmt.close();
			pstmt = null;
		}
		catch (Exception e)
		{
			pstmt = null;
		}
		//	Invoice Not posted
		if (tax.getLineCount() == 0)
		{
			log.warning ("Invoice not posted yet - " + line);
			return false;
		}
		//	size = 1 if no tax
		if (tax.getLineCount() < 2)
			return true;
		return tax.createEntries (as, fact, line);
		
	}	//	createTaxCorrection

}   //  Doc_Allocation

/**
 * 	Allocation Document Tax Handing
 *	
 *  @author Jorg Janke
 *  @version $Id: Doc_Allocation.java,v 1.17 2005/10/28 01:00:53 jjanke Exp $
 */
class Doc_AllocationTax
{
	/**
	 * 	Allocation Tax Adjustment
	 *	@param DiscountAccount discount acct
	 *	@param DiscountAmt discount amt
	 *	@param WriteOffAccount write off acct
	 *	@param WriteOffAmt write off amt
	 */
	public Doc_AllocationTax (MAccount DiscountAccount, BigDecimal DiscountAmt,
		MAccount WriteOffAccount, BigDecimal WriteOffAmt)
	{
		m_DiscountAccount = DiscountAccount;
		m_DiscountAmt = DiscountAmt;
		m_WriteOffAccount = WriteOffAccount;
		m_WriteOffAmt = WriteOffAmt;
	}	//	Doc_AllocationTax

	private CLogger				log = CLogger.getCLogger(getClass());

	private MAccount			m_DiscountAccount;
	private BigDecimal 			m_DiscountAmt;
	private MAccount			m_WriteOffAccount;
	private BigDecimal 			m_WriteOffAmt;

	private ArrayList<MFactAcct>	m_facts  = new ArrayList<MFactAcct>();
	private int					m_totalIndex = 0;

	/**
	 * 	Add Invoice Fact Line
	 *	@param fact fact line
	 */
	public void addInvoiceFact (MFactAcct fact)
	{
		m_facts.add(fact);
	}	//	addInvoiceLine
		
	/**
	 * 	Get Line Count
	 *	@return number of lines
	 */
	public int getLineCount()
	{
		return m_facts.size();
	}	//	getLineCount
		
	/**
	 * 	Create Accounting Entries
	 *	@param as account schema
	 *	@param fact fact to add lines
	 *	@return true if created
	 */
	public boolean createEntries (MAcctSchema as, Fact fact, DocLine line)
	{
		//	get total index (the Receivables/Liabilities line)
		BigDecimal total = Env.ZERO;
		for (int i = 0; i < m_facts.size(); i++)
		{
			MFactAcct factAcct = (MFactAcct)m_facts.get(i);
			if (factAcct.getAmtSourceDr().compareTo(total) > 0)
			{
				total = factAcct.getAmtSourceDr();
				m_totalIndex = i; 
			}
			if (factAcct.getAmtSourceCr().compareTo(total) > 0)
			{
				total = factAcct.getAmtSourceCr();
				m_totalIndex = i; 
			}
		}
		
		MFactAcct factAcct = (MFactAcct)m_facts.get(m_totalIndex);
		log.info ("createEntries - Total Invoice = " + total + " - " +  factAcct);
		int precision = as.getStdPrecision();
		for (int i = 0; i < m_facts.size(); i++)
		{
			//	No Tax Line
			if (i == m_totalIndex)
				continue;
			
			factAcct = (MFactAcct)m_facts.get(i);
			log.info (i + ": " + factAcct);
			
			//	Create Tax Account
			MAccount taxAcct = factAcct.getMAccount();
			if (taxAcct == null || taxAcct.get_ID() == 0)
			{
				log.severe ("Tax Account not found/created");
				return false;
			}
			
			
			//	Discount Amount	
			if (Env.ZERO.compareTo(m_DiscountAmt) != 0)
			{
				//	Original Tax is DR - need to correct it CR
				if (Env.ZERO.compareTo(factAcct.getAmtSourceDr()) != 0)
				{
					BigDecimal amount = calcAmount(factAcct.getAmtSourceDr(), 
						total, m_DiscountAmt, precision);
					if (amount.signum() != 0)
					{
						fact.createLine (line, m_DiscountAccount,
							as.getC_Currency_ID(), amount, null);
						fact.createLine (line, taxAcct,
							as.getC_Currency_ID(), null, amount);
					}
				}
				//	Original Tax is CR - need to correct it DR
				else
				{
					BigDecimal amount = calcAmount(factAcct.getAmtSourceCr(), 
						total, m_DiscountAmt, precision);
					if (amount.signum() != 0)
					{
						fact.createLine (line, taxAcct,
							as.getC_Currency_ID(), amount, null);
						fact.createLine (line, m_DiscountAccount,
							as.getC_Currency_ID(), null, amount);
					}
				}
			}	//	Discount
			
			//	WriteOff Amount	
			if (Env.ZERO.compareTo(m_WriteOffAmt) != 0)
			{
				//	Original Tax is DR - need to correct it CR
				if (Env.ZERO.compareTo(factAcct.getAmtSourceDr()) != 0)
				{
					BigDecimal amount = calcAmount(factAcct.getAmtSourceDr(), 
						total, m_WriteOffAmt, precision);
					if (amount.signum() != 0)
					{
						fact.createLine (line, m_WriteOffAccount,
							as.getC_Currency_ID(), amount, null);
						fact.createLine (line, taxAcct,
							as.getC_Currency_ID(), null, amount);
					}
				}
				//	Original Tax is CR - need to correct it DR
				else
				{
					BigDecimal amount = calcAmount(factAcct.getAmtSourceCr(), 
						total, m_WriteOffAmt, precision);
					if (amount.signum() != 0)
					{
						fact.createLine (line, taxAcct,
							as.getC_Currency_ID(), amount, null);
						fact.createLine (line, m_WriteOffAccount,
							as.getC_Currency_ID(), null, amount);
					}
				}
			}	//	WriteOff
			
		}	//	for all lines
		return true;
	}	//	createEntries
	
	/**
	 * 	Calc Amount tax / total * amt
	 *	@param tax tax
	 *	@param total total
	 *	@param amt reduction amt
	 *	@param precision precision
	 *	@return tax / total * amt
	 */
	private BigDecimal calcAmount (BigDecimal tax, BigDecimal total, BigDecimal amt, int precision)
	{
		log.fine("Tax=" + tax + " / Total=" + total + " * Amt=" + amt);
		if (tax.signum() == 0 
			|| total.signum() == 0
			|| amt.signum() == 0)
			return Env.ZERO;
		/**
		BigDecimal percentage = tax.divide(total, 10, BigDecimal.ROUND_HALF_UP); 
		BigDecimal retValue = percentage.multiply(amt);
		if (retValue.scale() > precision)
			retValue = retValue.setScale(precision, BigDecimal.ROUND_HALF_UP);
		log.fine("calcAmount - Percentage=" + percentage + ", Result=" + retValue);
		**/
		BigDecimal retValue = tax.multiply(amt).divide(total, precision, BigDecimal.ROUND_HALF_UP);
		log.fine("Result=" + retValue);
		return retValue;
	}	//	calcAmount
		
}	//	Doc_AllocationTax

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -