Define the logic that sets (or not) contribution receive_date in relation to payments
We discovered that Payment.create that completed a contribution was having a side-effect of updating the contribution's receive_date
to today's date.
The PR at https://github.com/civicrm/civicrm-core/pull/17688 corrected that by ensuring the payment's date is properly passed through into the underlying BAO code that does the updates and now tests that the receive_date
is set to the trxn_date
of the new payment.
However it raised questions: why should a payment update the contribution's receive_date
?
Rather than hold up a PR which was around fixing a definitely-not-what-we-want behaviour, we started this issue to have the discussion. It is referenced in the docblock of the new test in tests/phpunit/api/v3/PaymentTest.php called testPaymentCreateTrxnIdAndDates
Before we jump in about one field, let's consider the whole picture (which I may or may not describe properly here)
-
A contribution is created in Pending state, which generates:
- a contribution record, which has a
receive_date
, but alsorevenue_recognition_date
(and less importantly: cancel, receipt and thankyou dates) - a "financial item" for each line item. This has a
transaction_date
field, as well as acreate_date
field. - depending on config (and possible bugs), a financial transaction record transferring the total amount from the line items' financial types' configured income accounts to Accounts Receivable account, and this table (
civicrm_financial_trxn
) has atrxn_date
field.
- a contribution record, which has a
-
A contribution may receive various "payments" (in API speak, but it's really about financial transactions). Typically this represents the full payment for the whole contribution, and in which case it "completes" the contribution. But it also seems to cover various changes, cancellations, refunds, partial payments... For the 90% case where it completes the contribution, this generate:
- a(nother)
civicrm_financial_trxn
row which has atrxn_date
, and transferrs the funds into (Dr) the payment instrument's configured account from (Cr) the Accounts Receivable account. - Currently, it will update the
receive_date
for the contribution, too.
- a(nother)
So, dates-wise we have:
Reference | date | observed current behaviour |
---|---|---|
➊ | contribution receive_date
|
Shown in lists. Create date, then updated. |
➋ | contribution revenue_recognition_date
|
NULL - don't know when/if this gets set |
➌ | financial item 1's create_date
|
Date contribution was created |
➍ | financial item 1's transaction_date
|
Date completing (or latest?) payment made |
➎ | financial trxn 1's trxn_date
|
Could not observe; is not created (think this is a bug see link above) |
➏ | financial trxn 2's trxn_date
|
Date of the completing payment |
I can see that there are situations where it makes sense to update the receive date: for most payments that are made in a single lump, it's probably the most important date: when did we get the money (not just the promise/hope/intent of money)? But as soon as you get into partial payments, refunds etc. then that's only going to be an approximation.
CiviContribute sets up pending contributions willy-nilly which can also represent abandoned baskets, but there's the case when this is set up before midnight and the payment comes a minute later but after midnight. Direct Debit processors may set them up for future payments, or initial payments, but the receive dates may differ due to local banking rules (e.g. bank/public holidays, lack of funds...).
So, what should we do? Leave receive_date
alone instead of updating it to the completion date? Do the other dates have enough exposure to do this (ie. is it clear to users what the dates mean)? Set it as the date the first funds were received? The latest funds (completing or not) received? Do we update it for cancelled/refunded/partially refunded?
Enjoy the discussion! (not sure if I need to @ people about this, but in case I do, here's an incomplete list: @eileen @JoeMurray @mattwire @KarinG )