Fixed day payment terms

There are some parties that agree to make the payment of all the invoices on an specific day of the month, for example they only pay on the 10th and 20th of each month. For this cases the payment term should be computed using the next payment date of the month. Here are some examples:

Supose that we agreed with a supplier to pay them on 10th and 20th of each month on a fixed term of 30 days.

  • An invoice with date 01/02/2020 will be due on 10/03/2020 (30days + setting the fixed day)
  • An invoice with date 12/02/2020 will be due on 20/03/2020 (as the due date is after the payment day we go to the next one)
  • An invoice with date 22/02/2020 will be due on 10/04/2020 (fixed day goes to the next month)

With the current relativedelta definition we can define a fixed day to be used with the party by adding two deltas for the payment. One for the number of days and another for the fixed day. This works great until you agree to pay on two diferent days of the same month.

I’ve searched how other erp systems implement this and I found that navision treats this as spanish localization. So my first question is if there are other countries using tryton that have similar requirements?

I never encounter such usage. Nitpicking for ≃15 days of delay seems to give more work then advantage, it is probably heritage from non e-banking area.
Any way, I see no difficulty to customize current delta design. For example, I create a delta for each fixed day and add a condition to apply them or not (return an empty relativedelta or not).

Probably but this is something that is still used because of long lasting comercial relations.

This sound reasonable but the main problem here is that we need to compare the day of the relativedelta with the current due day, which is currently not possible.

Indeed, I guess we could improve the API to pass the current date to the get function.

in France, I have a supplier like that where the payment day should be done on fixed days after a fixed term of 30 days. But it isn’t a common practice.

For me, it isn’t a required functionnality (I am living without it until now), but if present, I would use it.

Only a fixed day or a list of fixed days?

it is a list. in fact it is the same example as your: on 10 or 20 after fixed term of 30 days.

For only one day, payment conditions are already functional (few of my suppliers are using that too).

FYI I wrote Manual payment term on invoice which should help solving those special cases manually.

Thanks for your effort but I do not think we should manage this case manually as we now that for each invoice of this party we have to pay on a specific day so the system should be able to compute the correct day because we know all the terms involved.

If we have to declare it manually it can be easly solved by updating the term days manually once the invoice is posted.

I’m gonna to talk about another use case for Spain too. Just to give more real data to the topic.

A customer of us use this feature for more than 3 percent of its customers (+200 customers over a total of ~=6000) so in our experience is quite usual.

Moreover it is not only used a fixed or a set of fixed days else a period days to make the payments too.

Below some of them as examples. Fixed days are represented separated by commas, period days by dash:

  • 15 days delayed at 6-18 days
  • 18 days delayed at 3,18 days
  • 0 days delayed at 5,15,25 days
  • 50% of amount in 20 days delayed and 50% of amount in 30 days delayed at 20-30 days

Editing the line after posting should be a special case where the terms are re-negotiated afterward.
I still think we need to allow definition of custom terms manually.

Of course, I do not say that this manual edition is a good solution when the term rules are perfectly known. But it will help for one time special case.

I’m still in favor of improving the current payment term design to filter out some lines with the current computed date.

Indeed we have similar scenarios on several customers. By now we use account_payment_days but would be great to get it on core.

We have both these cases too (naturally)…

A famous case, also in France, is for subcontractors typically paid either 45 days + end-of-month OR end-of-month + 45 days.

Perhaps there is a possible solution… The possibility to indicate ‘end-of-month’ would allow a bit more flexibility to the deltas, especially if it were possible to add the terms in a list as indicated above with ‘+’.

This is currently possible. You just have to create two relativedeltas from the same line:

  • One for 30Days
  • Another with day of month 31

This will use always last day of the month.

1 Like

I presume you mean 45days… yes, okay, and inversely for the other case.
But this doesn’t seem to work reliably with a fixed day other than the last day
(which is presumably what instigated this topic in the first place).

For example, if trying to do the similar (30days + day of month the 10th),
it seems to work okay for invoices issued prior to the 10th of the month, but not for later dates.
That is, seems there is missing a check that the next 10th of the month should be used and not the last one.

Is this equivalent to use -1 day as the day of the month?

No, as negative values are not supported for relativedelta day:

>>> from dateutil import relativedelta
>>> from datetime import date
>>> today =
>>> today + relativedelta.relativedelta(day=-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/site-packages/dateutil/", line 405, in __radd__
    return self.__add__(other)
  File "/usr/lib/python3.8/site-packages/dateutil/", line 387, in __add__
    ret = (other.replace(**repl)
ValueError: day is out of range for month

And there is a domain on the field which enforces that the day is between 1 and 31.


…but they are valid for recurrence rules?

Sorry. I mixed Recurrence rules with Payterm.

I got it.

Recurrence rules are dateutil.rrule based and Payterm is relativedelta based:

class PaymentTermLineRelativeDelta(sequence_ordered(), ModelSQL, ModelView):
    'Payment Term Line Relative Delta'
    __name__ = ''
    line = fields.Many2One('account.invoice.payment_term.line',
        'Payment Term Line', required=True, ondelete='CASCADE')
    day = fields.Integer('Day of Month',
            ('day', '=', None),
            [('day', '>=', 1), ('day', '<=', 31)],
    month = fields.Many2One('ir.calendar.month', "Month")

With a self-explained domain.

Yes, that’s something that we are currently missing and also to be able to set multiple fixed thats.