Hi,
currently ADempiere allow two methods for scheduling of payment: a single C_PaymentTerm with multiple configurations which result in a single due date, or multiple C_PaySchedule each giving a different due date. The first method is quite flexible because you can pay at a fixed month's day, while the other simply add the specified days to the invoice date.
Now in Italy one common requirement is to split invoice payments parts due at the end of each month like:
invoice on date 5-feb-2011 for a total of 1200,00
1st payment 400,00 at 28-feb-2011
2nd payment 400,00 at 31-mar-2011
3rd payment 400,00 at 30-apr-2011
with the current approach i not possible to generate such due dates.
I have done a slight change in MInvoicePaySchedule (MInvoice invoice, MPaySchedule paySchedule) method to handle this requirement. To make it work you have to fill the following fields:
C_PaymentTerm.isDueFixed = 'Y'
C_PaymentTerm.FixMonthDay = 31
C_PaySchedule,NetDays = a multiple of 30 (zero is ok)
The starting date is calculated with the standard paymenttermduedate() function, then the number of months added is simply the result of NetDays/30
Calculating a discount date could be tricky with this approach so I decided to simply subtract the DiscountDays from the calculated due date, this is the final code:
public MInvoicePaySchedule (MInvoice invoice, MPaySchedule paySchedule)
{
...
MPaymentTerm payTerm = paySchedule.getParent();
// if PaymentTerm is DueFixed at end of the month and scheduled at multiple of 30, add months
if(payTerm.isDueFixed() && payTerm.getFixMonthDay() == 31 && paySchedule.getNetDays() % 30 == 0)
{
// use the standard logic to get the starting date (avoid to use DUAL)
String sql = "SELECT paymenttermduedate(?, ?) FROM C_PAYMENTTERM WHERE C_PAYMENTTERM_ID = ?";
Timestamp startDate = DB.getSQLValueTS(invoice.get_TrxName(), sql
, payTerm.getC_PaymentTerm_ID(), invoice.getDateInvoiced(), payTerm.getC_PaymentTerm_ID());
int months = paySchedule.getNetDays() / 30;
// add months to calculate Due Date, adjust to last day
Timestamp dueDate = MoreTimeUtil.addMonths(startDate, months, MoreTimeUtil.DAY_Last);
setDueDate (dueDate);
// use discount days starting from dueDate and going backward
int dDays = paySchedule.getDiscountDays();
if(dDays > 0) dDays=-dDays; // negate
Timestamp discountDate = TimeUtil.addDays(dueDate, dDays);
setDiscountDate (discountDate);
}
else // old behaviour
{
// Dates
Timestamp dueDate = TimeUtil.addDays(invoice.getDateInvoiced(), paySchedule.getNetDays());
setDueDate (dueDate);
Timestamp discountDate = TimeUtil.addDays(invoice.getDateInvoiced(), paySchedule.getDiscountDays());
setDiscountDate (discountDate);
}
} // MInvoicePaySchedule
I'm posting here to get some feedback and because this requirement could be common in other countries too
Regards,
Angelo Dabalà