Aller directement à la fin des métadonnées
Aller au début des métadonnées

Data model Changes

Data Model Changes

1. Solve the problem of deciding which asset account to use as the TO ACCOUNT for payments:

  • Link each payment instrument directly to an Asset Account via civicrm_entity_financial_account. Users can then expand default payment instrument list - for example adding "Check - Deposit to Account 910", "Check - Deposit to Account 841", etc. Use default asset account for the case of null in payment instrument for both form postProcess and in upgrades. CRM-11516
  • Link each payment processor directly to an Asset Account via civicrm_entity_financial_account. Remove financial_type_id from civicrm_payment_processor table. CRM-11515
  • Remove 'Asset Account is' related accounts from all Financial Types

2. Support batch export and (eventually) multiple payments against a contribution (obligation) without requiring rewrite of search and report code for now:

  • Add payment_instrument_id and check_num to civicrm_financial_trxn.
  • Retain both columns in civicrm_contribution for now as a 'cache' for simple (single payment) transactions.

3. Solve the problem of which Accounts Receivable account to use for pay-later contributions (which can have multiple line items with different financial types):

  • Retain financial_type_id in contribution, contribution_page, event, membership_type, and determine the accounts receivable account from that top-level financial_type_id rather than from line_item's financial_type_id's. Asset accounts for payments against pay later obligations are determined same as #1 above.

4. Solve the problem of which Expense account to use for contribution fees (since the contribution can have multiple line items with different financial types):

  • (same as #3 above)

Deferred Revenue Improvements

Deferred Revenue Improvements CRM-16189

Deferred Revenue Transactions were added in CRM-16189 to support deferred revenue when this option is enabled (see CRM-16189 Deferred Revenue Support).

The column entitled 'Deferred Revenue Transactions' in the tables below details how these transactions should be recorded. Please note: only membership and event revenue can be deferred at the moment. Although all revenue is recorded in the civicrm_contribution and associated tables, there is no support at present for deferred revenue for donations or sales of goods or services other than memberships and events.

Transactions with more than one line item may have some line items with revenue that is to be deferred and others where it is recognized as current revenue. This is determined by whether the line item represents membership or event revenue that meets the following criteria:

  • membership periods of one month or less, four weeks or less, and 31 days or less do not trigger revenue deferral
  • event registrations for events that start and end in the same calendar month as the purchase date do not trigger revenue deferral

There will be an 'Is Deferred Revenue Account' relationship defined for the financial_type of deferred revenue line_items which will provide the financial_account_id of the deferred revenue account.

We will use $revenue($i) below to represent the amount of revenue that is to be recognized in month $i. $i=0 is the starting month of the service, which is either the calendar month when a membership begins or the month when the first day of an event occurs. The dimensions of this array is the total months of service, which will range from 1 for events that occur all in one month (but start in the future), to 12, 24 or 60 in the case 1 year, 2 year or 5 year memberships.

$deferred_date($i) represents the date that $deferred_revenue($i) should be recognized in month $i. For memberships, $deferred_date(0) is the membership start_date, and $deferred_date($i) = $deferred_date(0) + $i months (adjusted to last day of month if that day of month 0 does not exist in month $i eg for 29th, 30th or 31st days of months). For events, $deferred_date(0) is first day of event, $deferred_date($i) is first of month for $i>0.

For memberships, $months_of_service is determined by the number of calendar months some or all of which are included between civicrm_membership.start_date and civicrm_membership.end_date. $total_amount is the amount paid for the membership after discounts etc have been applied. $revenue($i) = $total_amount / $months_of_service.

For events,

  1. $revenue($i) = line item amount for month of civicrm_event.start_date, 0 otherwise
  2. Future optional calculation: $revenue($i) = line item amount * (# of days of event in month $i) / total number of days in event, $months_of_service = number of months with one or more days in period from start to end of event.

For line items that are neither memberships nor event registrations, then $revenue($i)= line item amount for civicrm_contribution.revenue_recognition_date's month, rest of months are 0. If the revenue_recognition_date is null, then $i is the current month.

$deferred_revenue($i) is the amount of deferred revenue to be recognized in month $i.

When the purchase date is before the first month of service, then $current_revenue=0, and $deferred_revenue($i)=$revenue($i) for 0<= $i <= $months_of_service - 1.

If the purchase date is in the starting month of service, then $current_revenue = $revenue(0), $deferred_revenue(0) = 0, and $deferred_revenue($i) = $revenue($i) for 0<$i<= $months_of_service - 1.

If the purchase date is after the first month of service (eg a fixed annual membership purchased several months into the year), then $current_revenue is the sum of $revenue($i) for all months up to and including the month of purchase, and deferred_revenue($i)=$revenue($i) for months following month of purchase.

$deferred_revenue_total is the sum of values in $deferred_revenue from zero to total months of service.

 

Amount calculations and rounding:
When dividing amounts into multiple payments, sometimes the division into equal payments is not possible without remainders. For example, 12 equal payments that sum to a $400.00 annual membership works out to $33.33 per month, plus 1/3 of a penny. 12 * 33.33 = $399.96, causing issues.Similarly, 12 equal payments that sum to an $800.00 annual payments works out to $66.67 per month with rounding, plus 1/3 of a penny. 12 * 66.67 = $800.04. The following approach will be taken to resolve this potential issue: calculate the best payment rounding to closest penny, then adjust the first payment so the full payment is accurate.
$typical_payment = ROUND(($total_payment / $num_payments), 2 decimal places accuracy for all currencies);
$first_payment = $typical_payment - ($total_payment - ($typical_payment * $num_payments));
66.67 - (800 - (66.67 * 12)) = 66.67 - (800 - 800.04) = 66.63
33.33 - (400 - (33.33 * 12)) = 33.33 - (400 - 399.96) = 33.37

A hook will be created allowing modification of the values in the $revenue and $deferred_revenue arrays after they have been calculated by the default process outline above and before they are used to insert values in the database.

 

Overpayments and Refunds

Overpayments

Payments are normally allocated to line items by the amount on the entity_financial_item linking the financial_trxn payment record with the line items associated with the contribution. When there is an overpayment, the line items end up all fully paid, and any overpayment amount is not allocated. When cancelling a line item or reducing the amount of a line item results in the contribution's total amount owing dropping below the total amount that has currently been paid, then the entity_financial_trxn linking to that line item is changed so that it is fully paid. Reduction in the amount owing never results in an entity_financial_trxn showing that a line item has been overpaid.

When

 

New contribution

Offline completed contribution ("base data flow")

Scenario: $150.00 donation paid by check

TableOperationNotesDeferred Revenue Transactions
civicrm_contributionInsert

(no change)

 
civicrm_line_itemInsert 1 per "purchased" price_field_valueSame as 4.2 except:  financial_type_id derived from price_field_value.financial_type_id 
civicrm_financial_itemInsert 1 per line_item
financial_account_id =  account with "Income Account is" relationship to financial type of line_item.
financial_account.id = 1 if using default 'Donations' financial type configuration
status = Paid (lookup in financial_item_status option group)
description = line_item.label
entity_table = civicrm_line_item
entity_id = id of the associated line_item

For deferred revenue line items:

Same as in Notes, except

civicrm_financial_item.financial_account_id = deferred revenue account id

civicrm_financial_trxnInsert

to_financial_account_id:
  If payment_instrument_id NOT NULL, retrieve linked financial account via civicrm_entity_financial_account
  If payment_instrument_id IS NULL, retrieve default asset financial account (where financial_account_type_id is 'Asset' and is_default = 1).
financial_account.id = 6 for default meta-data

from_financial_account_id = NULL

status = Completed (contribution_status option group ?? need to verify which option_group is used for financial transaction status)

is_payment=TRUE (for versions >=4.7)

in addition to Notes insertion,

If $current_revenue > 0

insert civicrm_financial_trxn record with from_account_id=deferred revenue account id, to_account_id=revenue account id, trxn_date = now(), amount = $current_revenue

endif

For each deferred revenue line item

 For $i = 0 to $months_of_service -1

if $deferred_revenue($i)>0

insert civicrm_financial_trxn record with from_account_id=deferred revenue account id, to_account_id=revenue account id, trxn_date = $deferred_date($i), amount = $deferred_revenue($i)

endif

endfor

endfor

civicrm_entity_financial_trxnInsert 1 per civicrm_financial_item

entity_table = civicrm_financial_item

entity_id = civicrm_financial_item.id

amount = civicrm_financial_item.amount

Link each civicrm_financial_trxn record posting deferred revenue to a revenue account to the related civicrm_financial_item record using a civicrm_entity_financial_trxn record
civicrm_entity_financial_trxnInsertamount = contribution.total_amount

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id
 

ci

Online completed contribution

For online contributions, the "Asset Account" is the organization's merchant account for the payment processor. Note that for pass-thru processors which deposit money directly to the organization's bank account, the administrator should configure that bank account as the asset account for that processor.  Modifications to base flow in BOLD face:

TableOperationNotes
civicrm_financial_trxnInsert

to_financial_account_id = retrieve payment processor's financial account via linked civicrm_entity_financial_account

from_financial_account_id = NULL

status = Completed (contribution_status option group)

is_payment=TRUE (for versions >=4.7)

 

Online or offline contribution with FEE

If processor has passed back a fee amount (or user has recorded a fee for backoffice contribution), record the fee_amount and net_amount in the contribution record, AND create an additional financial item (transfers fee amount to Expenses account). Create entity_financial_trxn linking that financial_item to the financial_trxn of the payment. Modifications to base flow in BOLD face:

TableOperationNotes
civicrm_contributionInsert

fee_amount = fee returned by processor / entered by user in form
net_amount = total_amount - fee_amount

civicrm_financial_itemInsert additional row for fee amountfinancial_account_id =  account with "Expense Account is" relationship to financial type of the contribution.

financial_account.id = 5 if using default 'Donations' financial type configuration

contact_id = domain owner contact id
amount = fee amount
status = Paid (lookup in financial_item_status option group)
description = 'Fee'
entity_table = civicrm_financial_trxn
entity_id = id of the civicrm_finanical_trxn (the payment)

civicrm_financial_trxnInsert additional row for fee amountto_financial_account_id = account with "Expense Account of" relationship to financial type of the contribution
financial_account.id = 5 if using default 'Donations' financial type configuration

from_financial_account_id = "Asset Account" associated with Payment Processor (online) or with Payment Instrument (back office form)

amount = fee_amount

status = Completed (contribution_status option group)

civicrm_entity_financial_trxnInsert additional row linking new financial_trxn to the civicrm_financial_item created for the fee

amount = fee amount
entity_table = civicrm_financial_item

entity_id = civicrm_financial_item.id (the 'fee' financial item)
civicrm_entity_financial_trxn

Insert - linking new (fee) financial_trxn to the original contribution

amount = fee amount

financial_trxn_id = id of new financial_trxn (the fee trxn)

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

 

Add PREMIUM to online or offline contribution

If user has configured a Financial Type for tracking premiums accounting, record an additional financial_trxn record transferring amount = to Actual Cost of Product (civicrm_product.cost) FROM the Premiums Inventory (Asset) account TO the Cost of Sales account. If no Financial Type is associated with the product, then no additional processing is done. Modifications to base flow in BOLD face:

 

TableOperationNotes
civicrm_financial_trxnInsert additional row to transfer funds reflecting the actual cost of the premium product.
to_financial_account_id = account with "Cost of Sales" relationship to financial type of the premium product

from_financial_account_id = account with "Premiums Inventory" relationship to financial type of the premium product

amount = actual cost of product (civicrm_product.cost)

status = Completed (contribution_status option group)

civicrm_entity_financial_trxnInsert - linking new (product cost) financial_trxn to the original contributin

amount = actual cost of product (civicrm_product.cost)

financial_trxn_id = id of new financial_trxn

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

 

Online contribution - Pending (incomplete transaction) or Failed

IPN payment processors processing a contribution do NOT create civicrm_financial_item, civicrm_financial_trxn, or civicrm_entity_financial_trxn records at the time the transaction is posted to the payment processor. They are only created at the time of the IPN call back.

In the case of a payment processor failure on either normal payment processor at the time of posting or an IPN call back failure, NO civicrm_financial_item, civicrm_financial_trxn, or civicrm_entity_financial_trxn records should be created.

Online pay-later contribution

For pay later transactions, we still record contribution, line_item(s), financial_item(s), AND a financial trxn. However the financial_item(s) status is 'Unpaid', and the TO account for the financial trxn is the "AR Account is" (accounts receivable) account. Modifications to base flow in BOLD face:

TableOperationNotesDeferred Revenue Transaction
civicrm_financial_itemInsert 1 per line_itemfinancial_account_id =  account with "Income Account is" relationship to financial type of line_item.

financial_account.id = 1 if using default 'Donations' financial type configuration

status = Unpaid (lookup in financial_item_status option group)
description = line_item.label
entity_table = civicrm_line_item

entity_id = id of the associated line_item

For deferred revenue line items:

If $current_revenue>0, insert civicrm_financial_item record as per Notes with civicrm_financial_item.amount = $current_revenue

endif

insert civicrm_financial_item with

civicrm_financial_item.amount = $deferred_revenue_total, civicrm_financial_item.financial_account_id = deferred revenue account id, status=unpaid

civicrm_financial_trxnInsert

to_financial_account_id = account with "Accounts Receivable Account is" relationship to the financial type of the contribution

from_financial_account_id = NULL

status = Completed (contribution_status option group)

in addition to Notes insertion,

For each deferred revenue line item

For $i = 0 to $months_of_service -1

if $deferred_revenue($i)>0

insert civicrm_financial_trxn record with from_account_id=deferred revenue account id, to_account_id=revenue account id, trxn_date = $deferred_date($i), amount = $deferred_revenue($i)

endif

endfor

endfor

Contribution with Sales Tax

The following table's specifications of changes to the 'base case' above assumes that for a particular base case contribution there is a certain amount of sales tax to be recorded for a particular financial account. See the notes column for how the financial_account is determined, and how the amount of sales tax is calculated.

TableOperationNotes
civicrm_financial_itemFor each line_item, for each related sales tax on that line_item, insert one record
entity_table='civicrm_line_item'
entity_id= id of the line item being taxed, NOT a line_item containing the tax to be applied to a different line_item
Pseudocode:
For each civicrm_line_item
  for each civicrm_entity_financial_account with entity_table='civicrm_financial_type' 
      and entity_id=civicrm_line_item.financial_type_id and account_relationship='Sales Tax is'
    civicrm_financial_item.financial_account_id = civicrm_entity_financial_account.financial_account_id
    if (civicrm_financial_item.financial_account_id>0) {
      civicrm_financial_item.amount = round( line_item.line_total * financial_account.tax_rate )
    }
    // allow the civicrm_financial_item.financial_account_id and civicrm_financial_item.amount to be overridden:
    call hook_preSalesTax passing the contribution, civicrm_financial_item and (for convenience) the line_item's civicrm_financial_account 
  endfor
endfor
civicrm_entity_financial_trxnInsert 1 per new civicrm_financial_item

entity_table = civicrm_financial_item

entity_id = civicrm_financial_item.id

amount = civicrm_financial_item.amount

civicrm_contribution

civicrm_financial_trxn

Existing insert operationsChange total_amount field to include sales taxes in total_amount

Extension: Online or Offline Contribution for Membership with Commission 

To facilitate documentation of financial bookkeeping in CiviCRM, extension authors are encouraged to add their own financial data flows here.

The native Membership Commission extension (originally spec'd in mid-2015 as biz.jmaconsulting.mcommission) records commissions earned by Account Representatives on Membership sales and renewals. It uses a custom 'Membership Commission Account is' account relationship from Financial Types associated with membership dues to financial accounts used to record membership commission expenses. The manner of recording these transactions is based on that for recording bank fees above.

If contribution is paying for a membership, and a Membership Commission Account relationship exists for a line item's financial type, then create an additional financial item (transfers commission amount to Commissions Expenses account) to record the automatically calculated or manually overridden commission. Create an entity_financial_trxn linking that financial_item to the financial_trxn of the payment. Modifications to base flow in BOLD face:

TableOperationNotes

Deferred Revenue Transactions

(to be spec'd before implemenation)

civicrm_contributionInsert

 

 
civicrm_financial_itemInsert additional row for membership commission amountfinancial_account_id =  account with "Membership Commission Account is" relationship to financial type of the contribution.

contact_id = domain owner contact id

amount = membership commission amount
status = Paid (lookup in financial_item_status option group)
description = 'Membership Commission'
entity_table = civicrm_financial_trxn
entity_id = id of the civicrm_finanical_trxn (the payment)

 
civicrm_financial_trxnInsert additional row for membership commission amountto_financial_account_id = account with "Membership Commission Account of" relationship to financial type of the contribution

from_financial_account_id = "Asset Account" associated with Payment Processor (online) or with Payment Instrument (back office form)

amount = membership commission amount

status = Completed (contribution_status option group)

 
civicrm_entity_financial_trxnInsert additional row linking new financial_trxn to the civicrm_financial_item created for the fee

amount = membership commission amount
entity_table = civicrm_financial_item

entity_id = civicrm_financial_item.id (the 'membership commission' financial item)
 
civicrm_entity_financial_trxn

Insert - linking new (fee) financial_trxn to the original contribution

amount = membership commission amount

financial_trxn_id = id of new financial_trxn (the membership commission trxn)

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

 

 

Update contribution

Change contribution amount (quick config / single line_item)

When user changes amount of a Pending-Pay Later or Completed contribution, record financial_item and financial_trxn records for the difference amount.  Record entity_financial_trxn records linking financial_trxn to financial_item and to original financial_trxn. After the updates, sum of line_items line_total == sum of financial_items amount == sum of financial_trxn total_amount (where from_account_id is null) == contribution total_amount.

NOTE: Amount field in Contribution form should be READ-ONLY for online contributions (this includes Pending Incomplete Transaction as well as Completed status contributions).

 

Table
Operation
Notes
Deferred Revenue Transactions
civicrm_contributionUpdatetotal_amount = New Amount
 
civicrm_line_itemUpdate

line_total =New Amount

 
civicrm_financial_itemInsert

amount = difference
Example: $100 contribution changed to $90, amount = -10

financial_account_id = same as original financial_item
status = in normal case this has been same original financial_item (i.e. if Unpaid, still Unpaid; if Paid, still Paid), but with partial payments now supported the status calculation are:

If total_owed >=0 then // not a refund

If total_paid >= total_owed, then

status = Paid

elseif total_paid == 0 then

status = Unpaid

else

status = Partially paid

/*

else // is a refund

// not yet supported

*/

endif

 

civicrm_financial_trxnInsert

amount = difference
Example: $100 contribution changed to $90, amount = -10

from_financial_account_id = null

Completed contribution:
to_financial_account_id = based on payment instrument

is_payment=TRUE (for versions >=4.7)

Pending Pay Later contribution:
to_financial_account_id = account with "Accounts Receivable Account is" relationship to the financial type of the contribution

is_payment=FALSE (for versions >=4.7, specified for clarity since this is the default value)

in addition to Notes insertion,

calculate current and deferred revenue allocation for difference amount using date of update, then insert civicrm_financial_trxn as per base case using these amounts

civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the "adjustment" civicrm_financial_item


amount = difference
Example: $100 contribution changed to $90, amount = -10

financial_trxn_id = id of new financial_trxn (the adjustment trxn)
entity_table = civicrm_financial_item
entity_id = civicrm_financial_item.id

Similarly, insert one linking each new financial_trxn record to the one it is adjusting (ie from current month $i to original month $i). When the passage of time means that the current_revenue difference transaction encompasses several months of original transactions, create one civicrm_entity_financial_trxn record for each of the original months' records affected.
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the original contribution

amount = difference
Example: $100 contribution changed to $90, amount = -10

financial_trxn_id = id of new financial_trxn (the adjustment trxn)

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

Similar to base case, link all new civicrm_financial_trxn records dealing with deferred revenue back to their related civicrm_financial_item records.

Change line_items and thus (generally) contribution amount (multiple line_items, id non-quick-config)

Line items may be added, updated, or 'deleted', affecting the contribution amount. To reduce complexity and improve testability and stability, multiple changes to line_items in the same call will be processed one line_item at a time. (The downside is that this produces more bookkeeping transactions for export.) 

Update line_item (multiple line_items, ie non-quick-config)

Same as Change contribution amount (quick config / single line_item).

Add line_item (multiple line_items, ie non-quick-config)

Similar to Change contribution amount (quick config / single line_item), except the civicrm_line_item is inserted rather than updated.

Table
Operation
Notes
Deferred Revenue Transactions
civicrm_contributionUpdatetotal_amount = New Amount (previous total_amount + civicrm_line_item.line_total)
 
civicrm_line_itemInsert

 

 
civicrm_financial_itemInsert

amount = civicrm_line_item.line_total

status = in normal case this has been same original financial_item (i.e. if Unpaid, still Unpaid; if Paid, still Paid), but with partial payments now supported the status calculation are:

If total_owed >=0 then // not a refund

If total_paid >= total_owed, then

status = Paid

elseif total_paid == 0 then

status = Unpaid

else

status = Partially paid

/*

else // is a refund

// not yet supported

*/

endif

 
civicrm_financial_trxnInsert

amount = civicrm_financial_item.amount

from_financial_account_id = null

Completed contribution:
to_financial_account_id = based on payment instrument

is_payment=TRUE (for versions >=4.7)

Pending Pay Later contribution:
to_financial_account_id = account with "Accounts Receivable Account is" relationship to the financial type of the contribution

is_payment=FALSE (for versions >=4.7, specified for clarity since this is the default value)

(same as base data flow)
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the civicrm_financial_item


amount = civicrm_financial_item.amount
Example: $100 contribution has $10 line_item added, amount = 10

financial_trxn_id = id of new financial_trxn (the adjustment trxn)
entity_table = civicrm_financial_item
entity_id = civicrm_financial_item.id

same as base date flow
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the original contribution

amount = difference
Example: $100 contribution changed to $90, amount = -10

financial_trxn_id = id of new financial_trxn (the adjustment trxn)

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

 

'Delete' line_item (multiple line_items, ie non-quick-config)

Same as Change contribution amount (quick config / single line_item), with the final amount for the line_item being 0. UI needs to avoid displaying these line_items.

Change Revenue Recognition Date

Some organizations defer the recognition of some revenue to accounting periods where matching  expenses are booked. civicrm_contribution.revenue_recognition_date stores the date when the revenue is to be recognized when this is different from the transaction creation date (ie civicrm_contribution.receive_date, which is when the contribution is created, not necessarily when it is paid). When the month the revenue is recognized changes, the following entries should be made. We want to reverse current bookkeeping entries, then create new deferred revenue ones. So process an update as though amount is changed to 0 for all line items. Then recreate line items using deferred revenue financial accounts. This will correctly handle case where the financial accounts have changed for a line item. The following illustrates a single line item case for simplicity.

The following is intended to be equivalent to updating contribution to 0 for each line item, and then updating to same amount for each line item and changing the revenue recognition date.

Table
Operation
Notes
Deferred Revenue Transactions
civicrm_contributionUpdateset revenue_recognition_date to new value 
civicrm_financial_itemInsert

create copy of existing civicrm_financial_item but with reversed amount

amount = -amount

Example: $100 line item, set to -$100

rest of fields stay same

 

civicrm_financial_trxnInsert

create copy of existing civicrm_financial_trxn but with reversed amount

amount = -amount

 
civicrm_entity_financial_trxnInsertsimilar to base case for update, linking new financial_item to new financial_trxn 
civicrm_entity_financial_trxnInsertsimilar to base case for update, linking new financial_trxn to contribution 
civicrm_financial_itemInsert Insert new financial_item similar to base case for deferred revenue
civicrm_financial_trxnInsert

 

Insert new financial_trxn similar to base case for deferred revenue

civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the "adjustment" civicrm_financial_item


 

Insert to connect new financial_item to new financial_trxn for deferred revenue account
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the original contribution

 

link back to contribution

Pay-later contribution received

When a user records payment received for pay later transactions, record a financial trxn for the payment (FROM account is the AR Account). Update status of associated financial_item(s) to Paid. Modifications to base flow in BOLD face:

TableOperationNotes
civicrm_contributionUpdate (may not be necessary)

status = Completed or Partially Paid

If amount of payment is equal to or greater than amount outstanding, then status should end up as Completed.

If amount of payment is less than amount outstanding, then status should end up as Partially Paid.

No update of civicrm_contribution is strictly necessary if status would not change (eg receiving an additional partial payment, receiving a payment on a completely paid contribution. Though in the latter case I would expect calling code to instead prevent user from making a payment.

civicrm_financial_itemUpdate all rows linked to the contribution being paid

status = Paid or Partially Paid (lookup in financial_item_status option group), depending on if the amount paid is equal to or greater than amount outstanding, or less, respectively.

civicrm_financial_trxnInsert

from_financial_account_id = account with "AR Account is" relationship to the financial type of the contribution

If payment_instrument_id NOT NULL, retrieve linked financial account via civicrm_entity_financial_account
If payment_instrument_id IS NULL, retrieve default asset financial account (where financial_account_type_id is 'Asset' and is_default = 1).
NB: currently, financial_account.id = 6 for default meta-data, but this should not be hard coded.

status = Completed (contribution_status option group)

is_payment=TRUE (for versions >=4.7)

civicrm_entity_financial_trxnInsert 1 row per financial_item linking new financial_trxn to the civicrm_financial_item(s) being paid

financial_trxn_id = id of new financial_trxn (the payment)
entity_table = civicrm_financial_item
entity_id = civicrm_financial_item.id

amount = civicrm_financial_item.amount

civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the contribution

financial_trxn_id = id of new financial_trxn (the payment)
amount = contribution.total_amount

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

 

Delete Premium

If user deletes a selected premium in while editing a contribution AND the user has configured a Financial Type for tracking premiums accounting: record an additional financial_trxn record transferring amount = to Actual Cost of Product (civicrm_product.cost) FROM the Cost of Sales account back TO the Premiums Inventory (Asset) account. If no Financial Type is associated with the product, then no additional processing is done. Modifications to base flow in BOLD face:

 

TableOperationNotes
civicrm_financial_trxnInsert additional row to transfer funds reflecting the actual cost of the premium product.

to_financial_account_id = account with "Premiums Inventory" relationship to financial type of the premium product

from_financial_account_id = account with "Cost of Sales" relationship to financial type of the premium product

amount = actual cost of product (civicrm_product.cost)

status = Completed (contribution_status option group)

civicrm_entity_financial_trxn

Insert - linking new (product cost) financial_trxn to the contribution

amount = actual cost of product (civicrm_product.cost)

financial_trxn_id = id of new financial_trxn

entity_table = civicrm_financial_trxn

entity_id = civicrm_contribution.id

 

Change Premium

If user changes a selected Premium while editing a contribution, AND the user has configured a Financial Type for tracking premiums accounting: follow steps above for Delete Premium followed by Add Premium. There will be 2 new financial_trxn records inserted.

 

Change Payment Instrument for a Partly Paid or Completed contribution

If user changes payment instrument: record a financial_trxn record transferring funds from the previously specified asset account to the asset account associated with the new payment instrument. Changing payment instrument for contributions in any other status should NOT trigger book-keeping entries.

TableOperationNotes
civicrm_financial_trxnInsert row to transfer funds between the old and new asset account

to_financial_account_id = retrieve linked financial account for new payment instrument via civicrm_entity_financial_account

from_financial_account_id = null

amount = contribution amount

status = Completed (contribution_status option group)

is_payment=TRUE (for versions >=4.7)

NB: When displaying Payments, there should be one row for original civicrm_financial_trxn with a positive amount, a second for the from_financial_account with a negative amount, and a third for the new to_financial_account. This shows original payment, its reversal, and the new payment all on the payments tab.

civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the contribution.

amount = contribution amount

financial_trxn_id = id of new financial_trxn

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

civicrm_entity_financial_trxnFor convenience, insert one row per line item to link financial item(s) for this financial_trxn

amount = line item mount

financial_trxn_id = id of new financial_trxn

entity_table = civicrm_financial_item

entity_id = civicrm_financial_item.id

 

Change fee amount / add fee to existing contribution

When user changes the bank or payment processor fee amount for an existing contribution (edit contribution or via api), record financial_item and financial_trxn records for the difference amount. Record entity_financial_trxn records linking financial_trxn to financial_item and to original financial_trxn.

Table
Operation
Notes
civicrm_contributionUpdatefee_amount = New Amount
civicrm_financial_itemInsert

amount = difference in fee amount (if no fee initially, will be entire fee amount)
Example: $1.50 fee changed to $2.50, amount = $1.00,
financial_account_id =  account with "Expense Account is" relationship to financial type of the contribution.

financial_account.id = 5 if using default 'Donations' financial type configuration

contact_id = domain owner contact id
status = Paid (lookup in financial_item_status option group)
description = 'Fee'
entity_table = civicrm_financial_trxn
entity_id = id of the civicrm_finanical_trxn (the fee adjustment)

civicrm_financial_trxnInsert

amount = difference in fee amount (if no fee initially, will be entire fee amount)
Example: $1.50 fee changed to $2.50, amount = $1.00

to_financial_account_id = account with "Expense Account of" relationship to financial type of the contribution
NB: currently, financial_account.id = 5 if using default 'Donations' financial type configuration, but don't hardcode this

from_financial_account_id = "Asset Account" associated with Payment Processor (online) or with Payment Instrument (back office form)

civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the contribution


amount = difference in fee amount (if no fee initially, will be entire fee amount)
Example: $1.50 fee changed to $2.50, amount = $1.00

financial_trxn_id = id of new financial_trxn (the adjustment trxn)
entity_table = civicrm_contribution
entity_id = civicrm_contribution.id


Change Contribution with Sales Tax

Table
Operation
Notes
civicrm_contributionUpdate

total_amount = New Amount (101.70)

Example: $100 purchase + 13% Harmonized Sales Tax (100.00 + 13.00) changed to $90 + 13% Harmonized Sales Tax (90.00 + 11.70)

civicrm_line_itemUpdate

line_total =New Amount (90.00)

civicrm_financial_item corresponding to base civicrm_line_itemInsertamount = difference (-10.00)
Example: $100 purchase changed to $90 = -10.00

financial_account_id = same as original financial_item
status = same as original financial_item (i.e. if Unpaid, still Unpaid; if Paid, still Paid)
civicrm_financial_item corresponding to each sales tax civicrm_financial_itemFor each line_item, for each related sales tax on that line_item, insert one record
Example: amount: -10.00 * 0.13 = -1.30, financial_account_id: HST
entity_table='civicrm_line_item'
entity_id= id of the line item being taxed, in other words, the line_item described two rows above in this table
Pseudocode:
For each civicrm_line_item
  for each civicrm_entity_financial_account with entity_table='civicrm_financial_type' and entity_id=civicrm_line_item.financial_type_id and account_relationship='Sales Tax is'
    civicrm_financial_item.financial_account_id = civicrm_entity_financial_account.financial_account_id
if (civicrm_financial_item.financial_account_id>0) {
      // calculate based on the difference amount of the item being taxed, ie the amount described in previous line in this table.
      civicrm_financial_item.amount = round( civicrm_financial_item_being_taxed.amount * financial_account.tax_rate )
    }
    // allow the civicrm_financial_item.financial_account_id and civicrm_financial_item.amount to be overridden:
    call hook_preSalesTax passing the contribution, civicrm_financial_item and (for convenience) the line_item's civicrm_financial_account 
  endfor
endfor
civicrm_financial_trxnInsert

amount = difference
Example: 113 - 101.70 = -11.30

from_financial_account_id = null

Completed contribution:
to_financial_account_id = based on payment instrument

is_payment=TRUE (for versions >=4.7)

Pending Pay Later contribution:
to_financial_account_id = account with "Accounts Receivable Account is" relationship to the financial type of the contribution

is_payment=FALSE (for versions >=4.7, noted for clarity since this is the default value for is_payment)

civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the "adjustment" civicrm_financial_item records


amount = difference
Example: $100 contribution changed to $90, amount = -10

financial_trxn_id = id of new financial_trxn (the adjustment trxn)
entity_table = civicrm_financial_item
entity_id = civicrm_financial_item.id (for each item being taxed and each of its taxes)

So one for -$10.00 to the base payment, and another for -$1.30 to the tax amount.

civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the original contribution

amount = difference
Example: $113 payment incl tax changed to $101.70 incl tax, amount = -$11.30

financial_trxn_id = id of new financial_trxn (the adjustment trxn)

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id


 

Change Check Number for completed contribution

If user changes check # for a completed contributiont: record a negative amount financial_trxn record with the previous check #, and a positive amount financial_trxn with the new check #. Changing check # for contributions in any other status should NOT trigger book-keeping entries.

Table
Operation
Notes
civicrm_contributionUpdatecheck_number = new value
civicrm_financial_trxnInsert

amount = minus contribution.total_amount

check_number = old value

to_financial_account_id = retrieve linked financial account for payment instrument via civicrm_entity_financial_account

is_payment=TRUE (for versions >=4.7)

civicrm_financial_trxnInsert

amount = contribution.total_amount

check_number = new value

to_financial_account_id = retrieve linked financial account for payment instrument via civicrm_entity_financial_account

is_payment=TRUE (for versions >=4.7)

civicrm_entity_financial_trxn

Insert  - linking both new financial_trxn to the contribution


amount = minus contribution.total_amount (1st adjustment)

financial_trxn_id = id of new financial_trxn (the 1st adjustment trxn)

entity_table = civicrm_contribution
entity_id = civicrm_contribution.id

civicrm_entity_financial_trxn

Insert  - linking both new financial_trxn to the contribution


amount = contribution.total_amount (2nd adjustment)

financial_trxn_id = id of new financial_trxn (the 2nd adjustment trxn)

entity_table = civicrm_contribution
entity_id = civicrm_contribution.id

 

Change contribution financial type (backoffice form)

Scenario: Change financial type for $100 contribution from Donation to Campaign Contribution.

If the "Income Account" of the new financial type is different from that of the original, we need to reverse the original income and add the new income. To keep things clear and using the same pattern, we create corresponding reversal and new financial_trxn records.

TableOperationNotesDeferred Revenue Transaction
civicrm_contributionUpdatefinancial_type_id = new id 
civicrm_financial_item #1

Only insert If new "Income Account" != original

  1. Reverse original contribution
    account_id = original (or more accurately, the previous) account_id
    amount = minus original amount (-$100 in this scenario)
    status = original status (NB: need to be able to handle reversed Pay Later amounts (that will never be paid) properly in reports)
      
If the financial account for a deferred revenue line item is changed, then post a reversal transaction for the 1 or two original (or more accurately, the previous) financial_item records (ie same transaction except with amount = minus original amount)
civicrm_financial_item #2

Only insert If new "Income Account" != original

  1. Create new contribution
    account_id = new Income account_id
    amount = original amount ($100 in this scenario)
    status = original (or more accurately, the previous) status
If the financial account for a deferred revenue line item is changed, then create a new 1 or two financial_item records like in base data flow
civicrm_financial_trxnInsert

amount = minus contribution.total_amount

to_financial_account_id = original (or more accurately, the previous) to_financial_account_id (NOT the linked financial account for payment instrument via civicrm_entity_financial_account)

if the contribution is partly paid or completed status, then is_payment=TRUE (for versions >=4.7)

 
civicrm_financial_trxnInsert

amount = contribution.total_amount

to_financial_account_id = retrieve linked financial account for payment instrument via civicrm_entity_financial_account or if payment_instrument is null then the default asset account

if the contribution is partly paid or completed status, then is_payment=TRUE (for versions >=4.7)

follow base data flow for insertion of additional civicrm_financial_trxn records for deferred revenue recognition
civicrm_entity_financial_trxnInsert 1 row per inserted financial_item

financial_trxn_id = id of financial_trxn #1 or #2 respectively
entity_table = civicrm_financial_item
entity_id = civicrm_financial_item.id #1 or #2 respectively

amount = civicrm_financial_item.amount #1 or #2 respectively

as per base data flow
civicrm_entity_financial_trxnInsert 1 row per inserted financial_trxn

financial_trxn_id = id of financial_trxn #1 or #2 respectively
entity_table = civicrm_contribution
entity_id = civicrm_contribution.id

amount = civicrm_financial_trxn.amount #1 or #2 respectively

as per base data flow

Extension: Change or add membership commission amount to existing contribution

The native Membership Commission extension (originally spec'd in mid-2015 as biz.jmaconsulting.mcommission) records commissions earned by Account Representatives on Membership sales and renewals. It uses a custom 'Membership Commission Account is' account relationship from Financial Types associated with membership dues to financial accounts used to record membership commission expenses. The manner of recording these transactions is based on that for recording bank fees above.

When user changes the membership commission amount for an existing contribution (edit contribution), record financial_item and financial_trxn records for the difference amount. Record entity_financial_trxn records linking financial_trxn to financial_item and to original financial_trxn.

Table
Operation
Notes
Deferred Revenue Transaction
civicrm_financial_itemInsert

amount = difference in membership commission amount (if none initially, will be entire membership commission amount)
Example: $1.50 fee changed to $2.50, amount = $1.00,
financial_account_id =  account with "Membership Commission Account is" relationship to financial type of the contribution.

contact_id = domain owner contact id

status = Paid (lookup in financial_item_status option group)
description = 'Membership Commission'
entity_table = civicrm_financial_trxn
entity_id = id of the civicrm_finanical_trxn (the fee adjustment)

(to be spec'd)
civicrm_financial_trxnInsert

amount = difference in fee amount (if none initially, will be entire membership commission amount)
Example: $1.50 fee changed to $2.50, amount = $1.00

to_financial_account_id = account with "Membership Commission Account of" relationship to financial type of the contribution

from_financial_account_id = "Asset Account" associated with Payment Processor (online) or with Payment Instrument (back office form)

 
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the contribution


amount = difference in membership commission amount (if none initially, will be entire membership commission amount)
Example: $1.50 fee changed to $2.50, amount = $1.00

financial_trxn_id = id of new financial_trxn (the adjustment trxn)
entity_table = civicrm_contribution
entity_id = civicrm_contribution.id

 

 

Refund OR Cancel a Completed Contribution (Directly via change status to Refunded or Cancelled)

This simplified workflow is used when an organization does not want to use accounts payables to indicate that a refund is owing, and then later pay that refund.

 

 
Operation
Notes
Deferred Revenue Transaction
civicrm_contributionUpdatestatus = Refunded OR Cancelled
 
civicrm_financial_itemInsert

amount = minus original amount
Example: $100 contribution cancelled, amount = -100

If the financial type for the line_item has a 'Credit/Contra Revenue Account is' relationship defined then

financial_account_id = credit/contra revenue account

else
financial_account_id = same as original financial_item

endif
status = Paid 

post a reversal record for each record inserted in base data flow, using Credit/Contra Revenue Account if it exists for the $current_revenue record if one was posted
civicrm_financial_trxnInsert

amount = minus original amount
to_financial_account_id = based on payment instrument (e.g. Deposit bank account using default meta data if payment instrument is check) or default asset account if payment instrument is null
from_financial_account_id  = NULL

status = Refunded OR Cancelled

NB: if the contribution is partly paid or completed status, then is_payment=TRUE (for versions >=4.7)

create a reversal transaction for each of the original civicrm_financial_trxn records by copying it and setting amount = - amount
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the "cancelling" civicrm_financial_item


amount = minus original amount

financial_trxn_id = id of new financial_trxn (the adjustment trxn)
entity_table = civicrm_financial_item
entity_id = civicrm_financial_item.id (the adjustment item)

create one per financial_item
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the original contribution

amount = minus original amount

financial_trxn_id = id of new financial_trxn (the adjustment trxn)

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

create one per new financial_trxn

Extension: Pending Refund (Prepare to refund a completed contribution indirectly via Accounts Payable)

This workflow for refunds is two step: first the refund is posted to accounts payables, then the accounts payable amount is paid. This section documents the records for the first step.

 
Operation
Notes
Deferred Revenue Transaction (NB: to be determined)
civicrm_contributionUpdatestatus = Pending refund
 
civicrm_financial_itemInsert

amount = current amount paid on line_item NB: NOT the negative of the amount! We're going to change how accounts are interpreted, rather than using a negative as in the simple refund workflow.

(select distinct c.id, eft1.id, eft2.id, eft2.amount, ft.* from civicrm_entity_financial_trxn eft1 INNER JOIN civicrm_financial_trxn ft ON eft1.financial_trxn_id=ft.id AND ft.is_payment=1 AND ft.to_financial_account_id IS NOT NULL inner join civicrm_contribution c on eft1.entity_id=c.id AND eft1.entity_table='civicrm_contribution' inner join civicrm_entity_financial_trxn eft2 ON eft2.entity_table='civicrm_financial_item' AND eft1.financial_trxn_id=eft2.financial_trxn_id where c.id=nnn; // nnn is contribution id)

Example: purchase of 1 $50 ticket and 1 $100 ticket, partially paid $75 so far, then amount for first line item is $25, amount for second is $50

If the financial type for the line_item has a 'Credit/Contra Revenue Account is' relationship defined then

financial_account_id = credit/contra revenue account

else
financial_account_id = same as original financial_item

endif
status = Refunded 

 
civicrm_financial_trxnInsert

amount = current amount paid on contribution (sum of all payments)
to_financial_account_id = NULL
from_financial_account_id  = the accounts payable account (default this in browser to default accounts payable account, and provide a )

status = Pending refund

is_payment=false

 
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the "refunding" civicrm_financial_item


amount = civicrm_financial_item.amount

financial_trxn_id = id of new financial_trxn (the adjustment trxn)
entity_table = civicrm_financial_item
entity_id = civicrm_financial_item.id (the adjustment item)

 
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the original contribution

amount = civicrm_financial_trxn.total_amount

financial_trxn_id = id of new financial_trxn (the adjustment trxn)

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

 

 

Extension: Process Pending Refund Payment (Record payment for Accounts Payable outstanding)

This workflow for refunds is two step: first the refund is posted to accounts payables, then the accounts payable amount is paid. This section documents the records for the second step. It is similar in some ways to recording receipt of a payment on a Pay Later contribution.

 
Operation
Notes
Deferred Revenue Transaction (NB: to be determined)
civicrm_contributionUpdatestatus = Refunded
 
civicrm_financial_trxnInsert

amount = current amount paid on contribution (sum of all payments)
to_financial_account_id = the accounts payable account (derived from record with to_financial_account_id=NULL for this contribution)
from_financial_account_id  = the Asset account specified in the browser (default to default asset account)

status = Refunded

is_payment=true

 
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the original contribution

amount = civicrm_financial_trxn.total_amount

financial_trxn_id = id of new financial_trxn (the adjustment trxn)

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

Cancel a Pending incomplete or Failed contribution (change status to Cancelled)

There should be no book-keeping entries for these contributions, so we only need to change contribution status to 'Cancelled'.

 

Cancel a Pending Pay Later contribution

 

 
Operation
Notes
Deferred Revenue Transaction
civicrm_contributionUpdatestatus = Cancelled
 
civicrm_financial_itemInsertamount = minus original amount
Example: $100 contribution cancelled, amount = -100

financial_account_id = same as original financial_item
status = same as original financial_item (i.e. if Unpaid, this item is also Unpaid )
create one per original / previous financial_item record, setting amount = - amount
civicrm_financial_trxnInsert

amount = minus original amount
from_financial_account_id =  account with "Accounts Receivable Account is" relationship to the financial type of the contribution
to_financial_account_id = NULL 

create one per original / previous financial_trxn record, setting amount = - amount
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the "cancelling" civicrm_financial_item


amount = minus original amount

financial_trxn_id = id of new financial_trxn (the adjustment trxn)
entity_table = civicrm_financial_item
entity_id = civicrm_financial_item.id (the adjustment item)

create one per new civicrm_financial_item linking new financial_trxn to new financial_items
civicrm_entity_financial_trxn

Insert - linking new financial_trxn to the original contribution

amount = original amount

financial_trxn_id = id of new financial_trxn (the adjustment trxn)

entity_table = civicrm_contribution

entity_id = civicrm_contribution.id

 

Extension: General Journal Entries

New General Journal Entry

TableOperationNotes
civicrm_financial_trxnInsert

from_financial_account_id = NULL;

to_financial_account_id = debit account

trxn_date = date entered for transaction (not date the transaction entered)

total_amount = amount entered

fee_amount = 0

net_amount = amount entered

currency = currency entered

is_payment = FALSE

trxn_id = NULL

trxn_result_code = NULL

status_id = 1 (Completed)

payment_processor_id = NULL

payment_instrument_id = NULL

check_number = NULL

civicrm_financial_itemInsert

created_date = now()

transaction_date = date entered for transaction

contact_id = contact id of user creating the journal entry (we can get the company's contact_id from the financial account's owner

description = description entered

amount = amount entered

currency = currency entered

financial_account_id = credit account entered

status_id = 4 (or whatever is found for new entry with name of 'Other' in option_value table for option_group financial_item_status (id=72))

entity_table = NULL (! we'll need to check that code that deals with this table can handle this)

entity_id = NULL (! we'll need to check that code that deals with this table can handle this)

civicrm_entity_financial_trxnInsert

entity_table = 'civicrm_financial_item'

entity_id = just inserted fi.id

financial_trxn_id = just inserted ft.id

amount = entered amount

currency = entered currency


Contribution status meanings

 

StatusMeaning
CancelledPayment no longer expected
FailedPayment Processor returned failure
CompletedPayment received
PendingPay Later Pending OR Pending Incomplete (IPN)
RefundedCompleted payment refunded to payor (this is a new status)
OverdueNot applicable to contributions. Suppress from contribution form
In ProgressNot applicable to contributions. Suppress from contribution form

Supported Status Transitions

The following table, indicates which status transitions are allowed, as a first step towards creating form rules to prevent invalid transition and to ensure that valid transitions are all specified, implemented, and tested.

TODO: update to separate Pending (Pay Later) treatment from Pending (Incomplete).

TODO: add Partially Paid to status table.

Status from on Rows / Status To on ColumnsCancelledFailedCompletedPending Pay LaterPending IncompletePending RefundRefundedChargebackPartially PaidPartially Refunded
CancelledAllowed Allowed   Allowed   
Failed Allowed        
CompletedAllowed AllowedAllowedAllowedAllowedAllowedAllowed Allowed
Pending Pay LaterAllowedAllowedAllowedAllowed      
Pending IncompleteAllowed         
Pending Refund          
RefundedAllowed Allowed   Allowed   
Chargeback (proposed CRM-17951 )       Allowed  
Partially Paid  Allowed    (patch to implement welcome)
Allowed 
Partially Refunded (proposed - patch welcome!!!)      Allowed  Allowed

 

For cancelled contributions, prevent changes to fields affecting book-keeping transactions

Fields which affect book-keeping should be set to read-only in the Edit Contribution form if the contribution status is Cancelled. (Amount, Payment Instrument, Check #, Financial Type, Fee/Net Amount).

 

Change any other contribution properties

No accounting record changes are needed.


Étiquette
  • Aucun
  1. Nov 25, 2014

    I believe there is an error in the "Cancel a Pending Pay Later contribution" section: the added financial_trnx should either have the accounts reversed from the original financial_trxn, or the amount, but not both...

     

    1. Mar 23, 2015

      JoeMurray dit :

      Thanks, Olaf. Just noting for others that this was fixed.

  2. Jun 12, 2015

    JoeMurray dit :

    Here are some questions and comments that I have just removed from the wiki page. They were put into the document but should have been comments, as we are trying to keep this page current with as-built specs.

    Pay-later contribution received
    NOTE: (bug?) in 4.5.3, linking the new financial_trxn to the financial_item (4th row in this table) does not seem to happen (the entity_financial_trxn is missing). It can still be found through its link to the contribution (and I think that's what Civi must be doing); is the additional link necessary? It may be if it matters for the financial data to not depend on the contribution..

    Change Payment Instrument for a Completed contribution
    NOTE: What if there are multiple payments for a completed contribution? What information does the Contribution edit page show? Is it supposed to change the information for all of the payments (make as many transfers as there are trxn's), even if they have different payment instruments? Would it make sense to do that even if they had the same instrument? I think having any of this with Contribution editing is confusing and a non-arbitrary way to solve this is to allow editing of (or transferring) individual transactions, showing clearly which transaction(s) an edit will affect, or allowing explicit choice of transaction. Perhaps an expanded version of the "view payments" link on the Participant view page that allows for editing. Note that there is currently no way to do this (or do partial payments/add payments) for a contribution that's not associated with an event.

    Change Check Number for completed contribution
    NOTE: Don't need to link the new financial trxn's to the financial_item?

    Change contribution financial type (backoffice form)

    NOTE: If income account is not different, only update the contribution, correct?


Creative Commons License
Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution-Share Alike 3.0 United States Licence.