use of org.compiere.model.MTax in project lar_361 by comitsrl.
the class MLARPaymentHeader method recalcPaymentWithholding.
// setPayAmtDirectly
/**
* Realiza el cálculo de la retención sobre la cabecera de pago dada.
* Esto lo lleva a cabo creando por cada confiuración aplicable
* un certificado de retención y un pago de tipo "retención".
*
* @param genera Si es true geera el pago retención y el correspondiente certificado.
* @return verdadero si se generó la retención correctamente
*/
public boolean recalcPaymentWithholding(boolean genera) {
this.load(get_TrxName());
final MDocType dt = new MDocType(getCtx(), getC_DocType_ID(), get_TrxName());
String genwh = dt.get_ValueAsString("GenerateWithholding");
if (genwh == null || genwh.equals("N"))
return true;
// Se Borran los certificados y Pagos Retención del Header
BorrarCertificadosdeRetenciondelHeader();
BorrarPagosRetenciondelHeader();
updateHeaderWithholding(getLAR_PaymentHeader_ID(), get_TrxName());
this.load(get_TrxName());
// Recupera la configuración y calcula
final MBPartner bp = new MBPartner(getCtx(), getC_BPartner_ID(), get_TrxName());
final WithholdingConfig[] configs = WithholdingConfig.getConfig(bp, dt.isSOTrx(), get_TrxName(), null, getDateTrx());
// Si se recuperó correctamente la configuración
if (configs != null)
// Se recorren las configuraciones recuperadas
for (final WithholdingConfig wc : configs) {
log.config("Withholding conf >> " + wc);
BigDecimal impRetencion = Env.ZERO;
// Se recupera el tipo de documento para el Pago Retención
// a partir del tipo de retencion
final int c_DocType_ID = wc.getC_DocType_ID();
int cargoRetencion;
if (c_DocType_ID > 0) {
final MDocType docRet = new MDocType(getCtx(), c_DocType_ID, get_TrxName());
// Se recupera y valida el ID del cargo para retención desde el documento
cargoRetencion = docRet.get_ValueAsInt("LAR_Withholding_Charge_ID");
if (cargoRetencion < 0) {
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Error al crear la retenci\u00f3n (No existe cargo retenci\u00f3n configurado en el documento)");
return false;
}
} else {
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Error al crear la retenci\u00f3n (No existe tipo de documento configurado para el Pago Retenci\u00f3n)");
return false;
}
if (wc.isCalcFromPayment()) {
// Se calcula el importe a retener según el tipo de retención
final MPaymentAllocate[] facturas = getInvoices(get_TrxName());
BigDecimal totalOP = getPayHeaderTotalAmt();
BigDecimal impSujetoaRet = Env.ZERO;
BigDecimal aliquot = wc.getAliquot();
BigDecimal impFijo = Env.ZERO;
// En las retenciones de ganancias estos valores se pisan con los recuperados
// desde la tabla de conceptos LAR_Concepto_Ret_Ganancias
BigDecimal impNoSujeto = wc.getamountRefunded();
BigDecimal impRetMin = wc.getPaymentThresholdMin();
BigDecimal impExencion = Env.ZERO;
BigDecimal porcExencion = Env.ZERO;
// Es retención de Ganancias
if (wc.usaTipoGananciasBP()) {
final String tipoGanancias = (String) bp.get_Value("LAR_TipoGanancias");
// Se toma el importe del pago sin IVA
if (facturas.length <= 0)
impSujetoaRet = totalOP.divide(coef_IVA, 2, RoundingMode.HALF_EVEN);
else {
// Se calcula el importe sujeto a retención
BigDecimal sumaImpago = Env.ZERO;
for (final MPaymentAllocate mp : facturas) {
MInvoice factura = mp.getInvoice();
BigDecimal neto = factura.getTotalLines();
BigDecimal impago = mp.getAmount();
/*
* Se suma el importe "impago" de las facturas, si el importe
* impago supera al neto de la factura, solo se suma el neto ya
* que no podemos tomar como importe Sujeto a Retención los
* impuestos (IVA, percepciones, imp. internos, ect).
*/
impSujetoaRet = impSujetoaRet.add(neto.compareTo(impago) >= 0 ? impago : neto);
sumaImpago = sumaImpago.add(impago);
// Si el importe sujeto tomado de las facturas supera al total de la OP
// se toma como importe sujeto a retención el total de la OP-
}
if (totalOP.compareTo(impSujetoaRet) <= 0)
impSujetoaRet = totalOP;
else {
/*
* Se suma al importe sujeto a retención la diferencia
* exedente de la orden de pago (sin tomar en cuenta
* los impuestos de las facturas.
*/
if (totalOP.compareTo(sumaImpago) > 0)
impSujetoaRet = impSujetoaRet.add(totalOP.subtract(sumaImpago));
}
}
// Recuperar el importe pagado a ese proveedor dentro del mes corriente
BigDecimal impPagado = calculaImportePagado(bp);
// Si hay error al recuperar el importe pagado
if (impPagado.compareTo(Env.ZERO) < 0)
continue;
// Configuración del SdN
X_LAR_Concepto_Ret_Ganancias cg = null;
final int concepto_id = bp.get_ValueAsInt("LAR_Concepto_Ret_Ganancias_ID");
// Si no tiene concepto configurado o es "Sin Especificar"
if (concepto_id == 0 || concepto_id == sinEspecificar_ID)
continue;
else {
try {
// Recuperar toda la información asociada al concepto
String sqlcg = "SELECT * " + " FROM LAR_Concepto_Ret_Ganancias " + " WHERE LAR_Concepto_Ret_Ganancias_ID = ?";
PreparedStatement pstmtcg = DB.prepareStatement(sqlcg, get_TrxName());
pstmtcg.setInt(1, concepto_id);
ResultSet rscg = pstmtcg.executeQuery();
if (rscg.next()) {
cg = new X_LAR_Concepto_Ret_Ganancias(Env.getCtx(), rscg, get_TrxName());
} else {
log.warning("No existe configuraci\u00f3n para el concepto LAR_Concepto_Ret_Ganancias_ID = " + concepto_id);
rscg.close();
pstmtcg.close();
continue;
}
rscg.close();
pstmtcg.close();
} catch (SQLException e) {
log.log(Level.SEVERE, "", e);
return false;
}
}
// Recuperar toda la información asociada al concepto
BigDecimal impPiso = Env.ZERO;
// Es cálculo por escala
if (cg.isCalculo_Por_Escala() && tipoGanancias.equals("I")) {
X_LAR_Escala_Ret_Ganancias eg = null;
final List<X_LAR_Escala_Ret_Ganancias> escala = new ArrayList<X_LAR_Escala_Ret_Ganancias>();
// Recuperar la información de la escala
try {
// Recuperar la información de la escala
String sqleg = "SELECT * " + " FROM LAR_Escala_Ret_Ganancias ";
PreparedStatement pstmteg = DB.prepareStatement(sqleg, get_TrxName());
ResultSet rseg = pstmteg.executeQuery();
while (rseg.next()) {
eg = new X_LAR_Escala_Ret_Ganancias(Env.getCtx(), rseg, get_TrxName());
if (!escala.add(eg)) {
log.severe("Error al agregar configuración de escala a la lista");
continue;
}
}
rseg.close();
pstmteg.close();
} catch (SQLException e) {
log.log(Level.SEVERE, "", e);
return false;
}
// Recorrer la escala para encontrar el rango del pago
for (final X_LAR_Escala_Ret_Ganancias esc : escala) {
if (impSujetoaRet.compareTo(esc.getImporte_Desde()) >= 0 && impSujetoaRet.compareTo(esc.getImporte_Hasta()) <= 0) {
// obtener importe fijo, importe no sujeto y alicuota
aliquot = esc.getAlicuota();
// Se corrige la alícuota e impuesto en la config
// para que el certificado de retención quede correcto
wc.setAliquot(aliquot);
wc.setC_Tax_ID(0);
impFijo = esc.getImporte_Fijo();
impPiso = esc.getImporte_No_Sujeto();
impNoSujeto = tipoGanancias.equals("I") ? cg.getImporte_No_Sujeto_Inscripto() : cg.getImporte_No_Sujeto_No_Insc();
break;
}
}
} else // Es cálculo por escala
// Es cáclulo directo
{
// Obtener importe importe no sujeto y alicuota según si el SdN es
// Inscripto o No en el Impuesto a las Ganancias
aliquot = tipoGanancias.equals("I") ? cg.getAlicuota_Inscripto() : cg.getAlicuota_No_Inscripto();
// Se corrige la alícuota e impuesto en la config
// para que el certificado de retención quede correcto
wc.setAliquot(aliquot);
wc.setC_Tax_ID(0);
impNoSujeto = tipoGanancias.equals("I") ? cg.getImporte_No_Sujeto_Inscripto() : cg.getImporte_No_Sujeto_No_Insc();
}
// Se realiza el calculo del importe sujeto a retención en base
// al acumulado en el mes corriente y el importe no sujeto
BigDecimal acumulado = impSujetoaRet.add(impPagado);
// Si se no alcanza el Monto No Sujeto a Retención en el mes corriente, no se genera retención
if ((acumulado).compareTo(impNoSujeto) < 0)
return true;
else {
/*
* Si se supera el importe No Sujeto a Retención con el importe de
* la OP actual se deja como importe Sujeto a Retención la
* diferencia, caso contrario se calcula la retención con el
* importe Sujeto a retención completo.
*/
if (((acumulado.subtract(impNoSujeto)).compareTo(impSujetoaRet)) < 0)
impSujetoaRet = acumulado.subtract(impNoSujeto);
}
// Si es por escala al importe sujeto se le debe restar el "piso" (Sobre Excedente)
if (cg.isCalculo_Por_Escala())
impSujetoaRet = impSujetoaRet.subtract(impPiso);
impRetencion = impSujetoaRet.multiply(aliquot).divide(Env.ONEHUNDRED).setScale(2, BigDecimal.ROUND_HALF_EVEN);
impRetencion = impRetencion.add(impFijo);
// Exención de Ganancias
if (bp.get_ValueAsBoolean("LAR_Exento_Ret_Ganancias")) {
Date fechaVenc = (Date) bp.get_Value("LAR_Vencimiento_Cert_Ganancias");
if (!fechaVenc.before(getDateTrx())) {
impExencion = (BigDecimal) bp.get_Value("LAR_Importe_Exencion_Ganancias");
porcExencion = (BigDecimal) bp.get_Value("LAR_Exencion_Ganancias");
} else {
// Advertir al ususario que el certificado de Exención esta vencido
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Certificado de Exenci\u00f3n de Ganancias Vencido");
}
}
// Exenciones % e importe fijo
BigDecimal impExentoDesc = impRetencion.multiply(porcExencion).divide(Env.ONEHUNDRED).setScale(2, BigDecimal.ROUND_HALF_EVEN);
impRetencion = impRetencion.subtract(impExentoDesc).subtract(impExencion);
} else // Es retención de Ganancias
{
// La organización está configurada como Responsable Inscripto
if (// no recupera correctamente el loc_taxpayertype_id desde orgInfo && orgI.get_ValueAsInt("LCO_TaxPayerType_ID") == responsableInscripto)
wc.isUseOrgTaxPayerType()) {
// Recupera la categoría de IVA del SdN
final int bpTaxPaxerTypeID = bp.get_ValueAsInt("LCO_TaxPayerType_ID");
// no se genera retención de IVA.
if (bpTaxPaxerTypeID != responsableInscripto && facturas.length <= 0)
continue;
else {
// Se recorren las facturas de la OP
for (final MPaymentAllocate mp : facturas) {
MInvoice factura = mp.getInvoice();
MDocType doc = new MDocType(Env.getCtx(), factura.getC_DocType_ID(), this.get_TrxName());
MInvoiceTax[] impFactura = factura.getTaxes(false);
// Se recorren los impuestos de la factura
for (final MInvoiceTax impuesto : impFactura) {
MTax tax = new MTax(Env.getCtx(), impuesto.getC_Tax_ID(), this.get_TrxName());
// Se recupera la letra del tipo de documento
// si es letra M se retiene el 100% y supera el mínimo
String letra = recuperaLetra(doc.get_ValueAsInt("LAR_DocumentLetter_ID"));
// Si el cálculo esta configurado como Documento se asume que es retención por tipo de doc M
if (wc.getBaseType().equals("D")) {
if (letra.equals("M") && (factura.getGrandTotal().compareTo(wc.getPaymentThresholdMin()) > 0)) {
aliquot = wc.getAliquot();
if (tax.getName().contains("IVA"))
impSujetoaRet = impSujetoaRet.add(impuesto.getTaxAmt());
} else
continue;
} else if (tax.getName().contains("IVA")) {
impSujetoaRet = impSujetoaRet.add(impuesto.getTaxAmt());
// Si es alicuota reducida
if (tax.getRate().compareTo(alicuotaIVAGral) < 0)
aliquot = alicuotaRetReducida;
else
// Si no es reducida, se utiliza la
// alicuota de la configuración
aliquot = wc.getAliquot();
}
// Se calcula y acumula la retención
impRetencion = impRetencion.add(impSujetoaRet.multiply(aliquot).divide(Env.ONEHUNDRED).setScale(2, BigDecimal.ROUND_HALF_EVEN));
}
// Se recorren los impuestos de la factura
}
// Se recorren las facturas de la OP
}
// Exención de IVA
if (bp.get_ValueAsBoolean("LAR_Exento_Retenciones_IVA")) {
Date fechaVenc = (Date) bp.get_Value("LAR_Vencimiento_Cert_IVA");
if (!fechaVenc.before(getDateTrx())) {
impExencion = (BigDecimal) bp.get_Value("LAR_Importe_Exencion_IVA");
porcExencion = (BigDecimal) bp.get_Value("LAR_Exencion_IVA");
} else {
// Advertir al ususario que el certificado de Exención esta vencido
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Certificado de Exenci\u00f3n de IVA Vencido");
}
}
// Exenciones % e importe fijo
BigDecimal impExentoDesc = impRetencion.multiply(porcExencion).divide(Env.ONEHUNDRED).setScale(2, BigDecimal.ROUND_HALF_EVEN);
impRetencion = impRetencion.subtract(impExentoDesc).subtract(impExencion);
// el importe a pagar
if (totalOP.compareTo(impRetencion) < 0)
impRetencion = totalOP;
}
// Es retención de IVA
}
// Considerar las Exenciones
final X_LCO_WithholdingType wt = new X_LCO_WithholdingType(Env.getCtx(), wc.getWithholdingType_ID(), get_TrxName());
// Exención de IIBB
if (wc.isUseBPISIC() && bp.get_ValueAsBoolean("LAR_Exento_Ret_IIBB")) {
Date fechaVenc = (Date) bp.get_Value("LAR_Vencimiento_Cert_IIBB");
Date fechaInicio = (Date) bp.get_Value("LAR_Inicio_Cert_IIBB");
if (!fechaInicio.after(getDateTrx()) && !fechaVenc.before(getDateTrx())) {
impExencion = (BigDecimal) bp.get_Value("LAR_Importe_Exencion_IIBB");
porcExencion = (BigDecimal) bp.get_Value("LAR_Exencion_IIBB");
} else {
// Advertir al ususario que el certificado de Exención esta vencido
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Certificado de Exenci\u00f3n de IIBB Vencido");
}
// Exenciones % e importe fijo
BigDecimal impExentoDesc = impRetencion.multiply(porcExencion).divide(Env.ONEHUNDRED).setScale(2, BigDecimal.ROUND_HALF_EVEN);
impRetencion = impRetencion.subtract(impExentoDesc).subtract(impExencion);
}
// Exención de SUSS
if (wt.getName().contains("SUSS") && bp.get_ValueAsBoolean("LAR_Exento_Retenciones_SUSS")) {
Date fechaVenc = (Date) bp.get_Value("LAR_Vencimiento_Cert_SUSS");
Date fechaInicio = (Date) bp.get_Value("LAR_Inicio_Cert_SUSS");
if (!fechaInicio.after(getDateTrx()) && !fechaVenc.before(getDateTrx())) {
impExencion = (BigDecimal) bp.get_Value("LAR_Importe_Exencion_SUSS");
porcExencion = (BigDecimal) bp.get_Value("LAR_Exencion_SUSS");
} else {
// Advertir al ususario que el certificado de Exención esta vencido
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Certificado de Exenci\u00f3n de SUSS Vencido");
}
// Exenciones % e importe fijo
BigDecimal impExentoDesc = impRetencion.multiply(porcExencion).divide(Env.ONEHUNDRED).setScale(2, BigDecimal.ROUND_HALF_EVEN);
impRetencion = impRetencion.subtract(impExentoDesc).subtract(impExencion);
}
// Si el importe de la retención no supera el mínimo o es cero
if (impRetencion.compareTo(impRetMin) < 0 || impRetencion.compareTo(Env.ZERO) <= 0)
continue;
// Validar que si existen facturas, quede importe disponible a pagar
if (facturas.length > 0) {
BigDecimal sumaRemanente = Env.ZERO;
for (final MPaymentAllocate mp : facturas) sumaRemanente = sumaRemanente.add(mp.getAmount());
if (sumaRemanente.compareTo(impRetencion) < 0) {
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "No existe suficiente importe pendiente de pago (Revisar las facturas cargadas en la Orden de Pago).");
return false;
}
}
// @fchiappano verifico que existan pagos en los que se pueda
// descontar el importe de la retención.
MPayment pago = null;
boolean compensar = false;
for (MPayment payment : getPayments(get_TrxName())) {
if (!payment.getTenderType().equals("Z") && !payment.get_ValueAsBoolean("EsRetencionIIBB") && payment.getPayAmt().compareTo(impRetencion) >= 0) {
pago = payment;
compensar = true;
// lo utilice prefrentemente por encima de los demás TT que pueden compensar.
if (payment.getTenderType().equals("X"))
break;
}
}
// Existe un pago que permite compensar el importe de la retención
if (compensar && genera) {
// Se crea el Pago Retención compensando el importe
final MPayment pagoRetencion = creaPagoRetencion(impRetencion, cargoRetencion, c_DocType_ID, pago, compensar);
if (pagoRetencion == null) {
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Error al generar el Pago Retenci\u00f3n");
return false;
}
log.config("Pago Retenci\u00f3n: " + pagoRetencion.getC_Payment_ID());
// Se crea el Certificado de Retención
final MLARPaymentWithholding certificado = creaCertificadodeRetencion(impRetencion, impSujetoaRet, wc, pagoRetencion.getC_Payment_ID());
if (certificado == null) {
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Error al generar el Certificado de Retenci\u00f3n");
return false;
}
log.config("Certificado Retenci\u00f3n: " + certificado.getLAR_PaymentWithholding_ID());
} else if (genera) {
// Se crea el Pago Retención sin compensar el importe
final MPayment pagoRetencion = creaPagoRetencion(impRetencion, cargoRetencion, c_DocType_ID, pago, false);
if (pagoRetencion == null) {
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Error al generar el Pago Retenci\u00f3n");
return false;
}
log.config("Pago Retenci\u00f3n: " + pagoRetencion.getC_Payment_ID());
// Se crea el Certificado de Retención
final MLARPaymentWithholding certificado = creaCertificadodeRetencion(impRetencion, impSujetoaRet, wc, pagoRetencion.getC_Payment_ID());
if (certificado == null) {
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Error al generar el Certificado de Retenci\u00f3n");
return false;
}
log.config("Certificado Retenci\u00f3n: " + certificado.getLAR_PaymentWithholding_ID());
} else
this.setWithholdingAmt(impRetencion);
this.saveEx();
}
}
else // Se recorren las configuraciones recuperadas
{
JDialog dialog = new JDialog();
dialog.setIconImage(Adempiere.getImage16());
ADialog.warn(1, dialog, "Error al recuperar configuración desde el SdN");
return false;
}
// pero en la pestaña se visualizan los eliminados y es necesario refrescar manualmente para ver los nuevos.
return true;
}
use of org.compiere.model.MTax in project lar_361 by comitsrl.
the class WithholdingConfig method getConfig.
/**
*******************************************************
* Obtiene la configuración de retenciones/percepciones
* @param MBPartner Socio del Negocio
* @param isSOTrx
* @return Configuraciones de retención
*/
public static WithholdingConfig[] getConfig(final MBPartner bp, boolean isSOTrx, String trxName, MOrder order, Timestamp dateTrx) {
log.info("");
final List<WithholdingConfig> list = new ArrayList<WithholdingConfig>();
try {
// Fill variables normally needed
// BP variables
Integer bp_isic_int = (Integer) bp.get_Value("LCO_ISIC_ID");
int bp_isic_id = 0;
if (bp_isic_int != null)
bp_isic_id = bp_isic_int.intValue();
Integer bp_taxpayertype_int = (Integer) bp.get_Value("LCO_TaxPayerType_ID");
int bp_taxpayertype_id = 0;
if (bp_taxpayertype_int != null)
bp_taxpayertype_id = bp_taxpayertype_int.intValue();
String lar_tipoganancias = bp.get_ValueAsString("LAR_TipoGanancias");
/*
* No se utiliza la dirección del BP en los tipos de retenciones/percepciones que
* aplicamos. TODO: Revisar la forma de recuperar la dirección sin estar en un
* operación que obligue a seleccionarla.
*/
MBPartnerLocation mbpl = new MBPartnerLocation(Env.getCtx(), bp.getLocations(true)[0].get_ID(), trxName);
MLocation bpl = MLocation.get(Env.getCtx(), mbpl.getC_Location_ID(), trxName);
int bp_city_id = bpl.getC_City_ID();
// OrgInfo variables
MOrgInfo oi = MOrgInfo.get(Env.getCtx(), Env.getAD_Org_ID(Env.getCtx()), trxName);
Integer org_isic_int = (Integer) oi.get_Value("LCO_ISIC_ID");
int org_isic_id = 0;
if (org_isic_int != null)
org_isic_id = org_isic_int.intValue();
Integer org_taxpayertype_int = (Integer) oi.get_Value("LCO_TaxPayerType_ID");
int org_taxpayertype_id = 0;
if (org_taxpayertype_int != null)
org_taxpayertype_id = org_taxpayertype_int.intValue();
MLocation ol = MLocation.get(Env.getCtx(), oi.getC_Location_ID(), trxName);
int org_city_id = ol.getC_City_ID();
// Search withholding types applicable depending on IsSOTrx
String sqlt = "SELECT LCO_WithholdingType_ID " + " FROM LCO_WithholdingType " + " WHERE IsSOTrx = ? AND IsActive = 'Y'";
PreparedStatement pstmtt = DB.prepareStatement(sqlt, trxName);
pstmtt.setString(1, isSOTrx ? "Y" : "N");
ResultSet rst = pstmtt.executeQuery();
while (rst.next()) {
// Por cada una de las retenciones aplicables
X_LCO_WithholdingType wt = new X_LCO_WithholdingType(Env.getCtx(), rst.getInt(1), trxName);
X_LCO_WithholdingRuleConf wrc = null;
log.info("Withholding Type: " + wt.getLCO_WithholdingType_ID() + "/" + wt.getName());
// look the conf fields
String sqlrc = "SELECT * " + " FROM LCO_WithholdingRuleConf " + " WHERE LCO_WithholdingType_ID = ? AND IsActive = 'Y'";
PreparedStatement pstmtrc = DB.prepareStatement(sqlrc, trxName);
pstmtrc.setInt(1, wt.getLCO_WithholdingType_ID());
ResultSet rsrc = pstmtrc.executeQuery();
if (rsrc.next()) {
wrc = new X_LCO_WithholdingRuleConf(Env.getCtx(), rsrc, trxName);
} else {
log.warning("No LCO_WithholdingRuleConf for LCO_WithholdingType = " + wt.getLCO_WithholdingType_ID());
rsrc.close();
pstmtrc.close();
continue;
}
rsrc.close();
pstmtrc.close();
// look for applicable rules according to config fields (rule)
StringBuffer sqlr = new StringBuffer("SELECT LCO_WithholdingRule_ID " + " FROM LCO_WithholdingRule " + " WHERE LCO_WithholdingType_ID = ? " + " AND IsActive = 'Y' " + " AND ValidFrom <= ? ");
if (wrc.isUseBPISIC())
sqlr.append(" AND LCO_BP_ISIC_ID = ? ");
if (wrc.isUseBPTaxPayerType())
sqlr.append(" AND LCO_BP_TaxPayerType_ID = ? ");
if (wrc.isUseOrgISIC())
sqlr.append(" AND LCO_Org_ISIC_ID = ? ");
if (wrc.isUseOrgTaxPayerType())
sqlr.append(" AND LCO_Org_TaxPayerType_ID = ? ");
if (wrc.isUseBPCity())
sqlr.append(" AND LCO_BP_City_ID = ? ");
if (wrc.isUseOrgCity())
sqlr.append(" AND LCO_Org_City_ID = ? ");
if (wrc.get_ValueAsBoolean("LAR_UsaTipoGananciasBP"))
sqlr.append(" AND LAR_TipoGananciasBP = ? ");
if (isSOTrx) {
if (order != null) {
// Add withholding categories of lines
if (wrc.isUseWithholdingCategory()) {
// look the conf fields
String sqlwcs = "SELECT DISTINCT COALESCE (p.LCO_WithholdingCategory_ID, COALESCE (c.LCO_WithholdingCategory_ID, 0)) " + " FROM C_OrderLine il " + " LEFT OUTER JOIN M_Product p ON (il.M_Product_ID = p.M_Product_ID) " + " LEFT OUTER JOIN C_Charge c ON (il.C_Charge_ID = c.C_Charge_ID) " + " WHERE C_OrderLine_ID = ? AND il.IsActive='Y'";
PreparedStatement pstmtwcs = DB.prepareStatement(sqlwcs, trxName);
pstmtwcs.setInt(1, order.getC_Order_ID());
ResultSet rswcs = pstmtwcs.executeQuery();
int i = 0;
int wcid = 0;
boolean addedlines = false;
while (rswcs.next()) {
wcid = rswcs.getInt(1);
if (wcid > 0) {
if (i == 0) {
sqlr.append(" AND LCO_WithholdingCategory_ID IN (");
addedlines = true;
} else {
sqlr.append(",");
}
sqlr.append(wcid);
i++;
}
}
if (addedlines)
sqlr.append(") ");
rswcs.close();
pstmtwcs.close();
}
}
// Add tax categories of lines
if (wrc.isUseProductTaxCategory()) {
// look the conf fields
String sqlwct = "SELECT DISTINCT COALESCE (p.C_TaxCategory_ID, COALESCE (c.C_TaxCategory_ID, 0)) " + " FROM C_InvoiceLine il " + " LEFT OUTER JOIN M_Product p ON (il.M_Product_ID = p.M_Product_ID) " + " LEFT OUTER JOIN C_Charge c ON (il.C_Charge_ID = c.C_Charge_ID) " + " WHERE C_Invoice_ID = ? AND il.IsActive='Y'";
PreparedStatement pstmtwct = DB.prepareStatement(sqlwct, trxName);
pstmtwct.setInt(1, order.getC_Order_ID());
ResultSet rswct = pstmtwct.executeQuery();
int i = 0;
int wcid = 0;
boolean addedlines = false;
while (rswct.next()) {
wcid = rswct.getInt(1);
if (wcid > 0) {
if (i == 0) {
sqlr.append(" AND C_TaxCategory_ID IN (");
addedlines = true;
} else {
sqlr.append(",");
}
sqlr.append(wcid);
i++;
}
}
if (addedlines)
sqlr.append(") ");
rswct.close();
pstmtwct.close();
}
}
PreparedStatement pstmtr = DB.prepareStatement(sqlr.toString(), trxName);
int idxpar = 1;
pstmtr.setInt(idxpar, wt.getLCO_WithholdingType_ID());
idxpar++;
pstmtr.setTimestamp(idxpar, dateTrx);
if (wrc.isUseBPISIC()) {
idxpar++;
pstmtr.setInt(idxpar, bp_isic_id);
}
if (wrc.isUseBPTaxPayerType()) {
idxpar++;
pstmtr.setInt(idxpar, bp_taxpayertype_id);
}
if (wrc.isUseOrgISIC()) {
idxpar++;
pstmtr.setInt(idxpar, org_isic_id);
}
if (wrc.isUseOrgTaxPayerType()) {
idxpar++;
pstmtr.setInt(idxpar, org_taxpayertype_id);
}
if (wrc.isUseBPCity()) {
idxpar++;
pstmtr.setInt(idxpar, bp_city_id);
if (bp_city_id <= 0)
log.warning("Possible configuration error bp city is used but not set");
}
if (wrc.isUseOrgCity()) {
idxpar++;
pstmtr.setInt(idxpar, org_city_id);
if (org_city_id <= 0)
log.warning("Possible configuration error org city is used but not set");
}
if (wrc.get_ValueAsBoolean("LAR_UsaTipoGananciasBP")) {
idxpar++;
if (lar_tipoganancias.equals("")) {
log.warning("No existe configuraci\u00f3n de Ganancias para el SdN");
return null;
}
pstmtr.setString(idxpar, lar_tipoganancias);
}
ResultSet rsr = pstmtr.executeQuery();
while (rsr.next()) {
// for each applicable rule
X_LCO_WithholdingRule wr = new X_LCO_WithholdingRule(Env.getCtx(), rsr.getInt(1), trxName);
// bring record for withholding calculation
X_LCO_WithholdingCalc wc = new X_LCO_WithholdingCalc(Env.getCtx(), wr.getLCO_WithholdingCalc_ID(), trxName);
if (wc.getLCO_WithholdingCalc_ID() == 0) {
log.severe("Regla sin c\u00e1lculo configurado: " + wr.getName());
continue;
}
// bring record for tax
MTax tax = new MTax(Env.getCtx(), wc.getC_Tax_ID(), trxName);
log.info("WithholdingRule: " + wr.getLCO_WithholdingRule_ID() + "/" + wr.getName() + " BaseType:" + wc.getBaseType() + " Calc: " + wc.getLCO_WithholdingCalc_ID() + "/" + wc.getName() + " CalcOnInvoice:" + wc.isCalcOnInvoice() + " Tax: " + tax.getC_Tax_ID() + "/" + tax.getName());
BigDecimal alicuota = BigDecimal.ZERO;
BigDecimal tasa = BigDecimal.ZERO;
alicuota = tax.getRate().setScale(4, BigDecimal.ROUND_HALF_EVEN);
tasa = alicuota.multiply(BigDecimal.valueOf(100));
WithholdingConfig config = new WithholdingConfig(alicuota, tasa, (BigDecimal) wrc.get_Value("PaymentThresholdMin"), wc.getThresholdmin(), wc.getThresholdMax(), wc.getAmountRefunded(), wc.isCalcOnPayment(), wr.getLCO_WithholdingRule_ID(), wr.getLCO_WithholdingType_ID(), wc.getC_Tax_ID(), wrc.get_ValueAsInt("C_DocType_ID"), wr.getC_TaxCategory_ID(), wrc.isUseBPISIC(), wrc.get_ValueAsBoolean("LAR_UsaTipoGananciasBP"), wrc.get_ValueAsBoolean("IsUseOrgTaxPayerType"), wc.getBaseType());
if (!list.add(config)) {
log.severe("Error al agregar configuración a la lista");
continue;
}
;
}
// while each applicable rule
}
// while each applicable withholding
} catch (SQLException e) {
log.log(Level.SEVERE, "", e);
return null;
}
return list.toArray(new WithholdingConfig[list.size()]);
}
use of org.compiere.model.MTax in project adempiere by adempiere.
the class Doc_Order method getCommitmentsSales.
// getCommitmentRelease
/**
* Get Commitments Sales
* @param doc document
* @param maxQty Qty invoiced/matched
* @param C_OrderLine_ID invoice line
* @return commitments (order lines)
*/
protected static DocLine[] getCommitmentsSales(Doc doc, BigDecimal maxQty, int M_InOutLine_ID) {
int precision = -1;
//
ArrayList<DocLine> list = new ArrayList<DocLine>();
String sql = "SELECT * FROM C_OrderLine ol " + "WHERE EXISTS " + "(SELECT * FROM M_InOutLine il " + "WHERE il.C_OrderLine_ID=ol.C_OrderLine_ID" + " AND il.M_InOutLine_ID=?)";
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, M_InOutLine_ID);
rs = pstmt.executeQuery();
while (rs.next()) {
if (maxQty.signum() == 0)
continue;
MOrderLine line = new MOrderLine(doc.getCtx(), rs, null);
DocLine docLine = new DocLine(line, doc);
// Currency
if (precision == -1) {
doc.setC_Currency_ID(docLine.getC_Currency_ID());
precision = MCurrency.getStdPrecision(doc.getCtx(), docLine.getC_Currency_ID());
}
// Qty
BigDecimal Qty = line.getQtyOrdered().max(maxQty);
docLine.setQty(Qty, false);
//
BigDecimal PriceActual = line.getPriceActual();
BigDecimal PriceCost = line.getPriceCost();
BigDecimal LineNetAmt = null;
if (PriceCost != null && PriceCost.signum() != 0)
LineNetAmt = Qty.multiply(PriceCost);
else if (Qty.equals(maxQty))
LineNetAmt = line.getLineNetAmt();
else
LineNetAmt = Qty.multiply(PriceActual);
maxQty = maxQty.subtract(Qty);
// DR
docLine.setAmount(LineNetAmt);
BigDecimal PriceList = line.getPriceList();
int C_Tax_ID = docLine.getC_Tax_ID();
// Correct included Tax
if (C_Tax_ID != 0 && line.getParent().isTaxIncluded()) {
MTax tax = MTax.get(doc.getCtx(), C_Tax_ID);
if (!tax.isZeroTax()) {
BigDecimal LineNetAmtTax = tax.calculateTax(LineNetAmt, true, precision);
s_log.fine("LineNetAmt=" + LineNetAmt + " - Tax=" + LineNetAmtTax);
LineNetAmt = LineNetAmt.subtract(LineNetAmtTax);
BigDecimal PriceListTax = tax.calculateTax(PriceList, true, precision);
PriceList = PriceList.subtract(PriceListTax);
}
}
// correct included Tax
docLine.setAmount(LineNetAmt, PriceList, Qty);
list.add(docLine);
}
} catch (Exception e) {
s_log.log(Level.SEVERE, sql, e);
} finally {
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
// Return Array
DocLine[] dl = new DocLine[list.size()];
list.toArray(dl);
return dl;
}
use of org.compiere.model.MTax in project lar_361 by comitsrl.
the class LAR_Validator method accountingForWithholdingOnPayment.
// voidWarehouseOrder
/**
* Process acounting for withholding on sales payment
*/
private String accountingForWithholdingOnPayment(final MAllocationHdr ah) {
final Doc doc = ah.getDoc();
final List<Fact> facts = doc.getFacts();
// One fact per acctschema
for (int i = 0; i < facts.size(); i++) {
Fact fact = facts.get(i);
MAcctSchema as = fact.getAcctSchema();
MAllocationLine[] allocLines = ah.getLines(false);
for (int j = 0; j < allocLines.length; j++) {
MAllocationLine al = allocLines[j];
// TODO is this line necesary?
doc.setC_BPartner_ID(al.getC_BPartner_ID());
int c_Payment_ID = al.getC_Payment_ID();
if (c_Payment_ID <= 0)
continue;
MPayment payment = new MPayment(ah.getCtx(), c_Payment_ID, ah.get_TrxName());
if (payment == null || payment.getC_Payment_ID() == 0)
continue;
// Se determina si se procesan cobros o pagos
if (payment.isReceipt()) {
// //////////////// PROCESA COBROS //////////////////
// Determine if is an withholding or not
int c_TaxWithholding_ID = payment.get_ValueAsInt("C_TaxWithholding_ID");
if (c_TaxWithholding_ID <= 0)
continue;
if (payment.getWriteOffAmt().compareTo(Env.ZERO) <= 0)
continue;
// Iterates over factlines, searching one with writeoff account
// in order to change it to the retrieved from processed payment
final FactLine[] factlines = fact.getLines();
for (int ifl = 0; ifl < factlines.length; ifl++) {
final FactLine fl = factlines[ifl];
// if factline account is WriteOff, change it
if (fl.getAccount().equals(doc.getAccount(Doc.ACCTTYPE_WriteOff, as))) {
// Creates factline with proper account (using c_taxwithholding_id from processed payment)
final BigDecimal withholdingAmt = payment.getWriteOffAmt();
final MTax tw = new MTax(ah.getCtx(), c_TaxWithholding_ID, ah.get_TrxName());
final DocTax taxLine = new DocTax(c_TaxWithholding_ID, tw.getName(), tw.getRate(), Env.ZERO, withholdingAmt, tw.isSalesTax());
final FactLine newFactLine = fact.createLine(null, taxLine.getAccount(DocTax.ACCTTYPE_TaxCredit, as), as.getC_Currency_ID(), withholdingAmt, null);
if (newFactLine != null)
newFactLine.setC_Tax_ID(c_TaxWithholding_ID);
// Removes factline with writeoff account from fact
log.info(String.format("Replace factline: %s -> %s", fl, newFactLine));
fact.remove(fl);
}
}
}
}
}
return null;
}
use of org.compiere.model.MTax in project lar_361 by comitsrl.
the class FiscalDocumentPrint method loadDocumentLines.
// loadDNFHLines
/**
* Carga las líneas que se encuentran en el documento de ADempiere hacia
* el documento de impresoras fiscales.
* @param mInvoice Documento de ADempiere.
* @param document Documento de impresoras fiscales.
*/
private void loadDocumentLines(final MInvoice mInvoice, final Document document) {
// Se obtiene el indicador de si los precios contienen los impuestos incluido
boolean taxIncluded = MPriceList.get(ctx, mInvoice.getM_PriceList_ID(), getTrxName()).isTaxIncluded();
// Se obtiene el redondeo para precios de la moneda de la factura
// int scale = MCurrency.get(oxpDocument.getCtx(), oxpDocument.getC_Currency_ID()).getCostingPrecision();
MInvoiceLine[] lines = mInvoice.getLines();
BigDecimal totalLineAmt = BigDecimal.ZERO;
// String description = "";
for (int i = 0; i < lines.length; i++) {
MInvoiceLine mLine = lines[i];
BigDecimal qtyEntered = mLine.getQtyEntered();
// @emmie - avoid "special" invoice lines (as shipments comments lines)
if (qtyEntered.compareTo(BigDecimal.ZERO) > 0) {
DocumentLine docLine = new DocumentLine();
docLine.setLineNumber(mLine.getLine());
docLine.setDescription(manageLineDescription(docLine, mLine));
// TODO - Review discounts at invoice behavior
// Calcula el precio unitario de la línea.
// Aquí tenemos dos casos de línea: Con Bonificaciones o Sin
// Bonificaciones
// 1. Sin Bonificaciones
// El precio unitario es entonces simplemente el precio actual
// de la
// línea, es decir el PriceActual.
// if (!mLine.hasBonus()) {
BigDecimal unitPrice = mLine.getPriceActual();
totalLineAmt = totalLineAmt.add(unitPrice);
// } else {
// 2. Con Bonificaciones
// Aquí NO se puede utilizar el mLine.getPriceActual() ya que el
// mismo tiene contemplado las bonificaciones mientras que en la
// impresión del ticket, las bonificaciones se restan al final
// del mismo. De esta forma, el precio unitario para el ticket
// va a ser mayor que el PriceActual de la línea en caso de que
// la misma contenga bonificaciones.
// El cálculo a realizar es:
// (PriceList * Qty - LineDiscountAmt) / Qty
//
// unitPrice =
// (mLine.getPriceList().multiply(mLine.getQtyEntered())
// .subtract(mLine.getLineDiscountAmt())).divide(
// mLine.getQtyEntered(), scale, RoundingMode.HALF_UP);
// }
// LAR - Process discount for invoice
final I_C_OrderLine ol = mLine.getC_OrderLine();
final BigDecimal discountRate = ol.getDiscount();
if (discountRate.compareTo(BigDecimal.ZERO) > 0) {
final BigDecimal originalAmt = BigDecimal.valueOf(100).multiply(unitPrice).divide(BigDecimal.valueOf(100).subtract(discountRate), 2, BigDecimal.ROUND_FLOOR);
final DiscountLine discountLine = new DiscountLine("Dto aplicado", originalAmt.subtract(unitPrice).multiply(mLine.getQtyEntered()), true, false, discountRate);
// Add discount to document line
docLine.setDiscount(discountLine);
// Set proper unitPrice
unitPrice = originalAmt;
}
// LAR - Process discount for invoice
docLine.setUnitPrice(unitPrice);
docLine.setQuantity(mLine.getQtyEntered());
docLine.setPriceIncludeIva(taxIncluded);
// Se obtiene la tasa del IVA de la línea
// Se asume que el impuesto es siempre IVA, a futuro se verá
// que hacer si el producto tiene otro impuesto que no sea IVA.
MTax mTax = MTax.get(Env.getCtx(), mLine.getC_Tax_ID());
docLine.setIvaRate(mTax.getRate());
// Se agrega la línea al documento.
document.addLine(docLine);
}
}
// TODO - Improve this behavior
BigDecimal amt = mInvoice.get_Value("WithHoldingAmt") == null ? Env.ZERO : // LAR perception are negative
((BigDecimal) mInvoice.get_Value("WithHoldingAmt")).negate();
if (amt.compareTo(BigDecimal.ZERO) > 0) {
// TODO Corregir el calculo del porcentaje de percepción.
// BigDecimal rate = amt.divide(totalLineAmt, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
// @mzuniga - Se agrega la provincia correspondiente a la Percepción en la descripción de la línea
String sql = "SELECT l.RegionName FROM AD_OrgInfo oi JOIN C_Location l ON oi.C_Location_ID = l.C_Location_ID WHERE oi.AD_Org_ID=?";
String prov = DB.getSQLValueString(mInvoice.get_TrxName(), sql, (Integer) mInvoice.get_Value("AD_Org_ID"));
// String.format("Percepci\u00f3n", rate);
String desc = "Perc. IIBB " + prov;
// @mzuniga
PerceptionLine perceptionLine = new PerceptionLine(desc, amt, null);
document.setPerceptionLine(perceptionLine);
}
}
Aggregations