Account receivable - [outbound] invoices

This page documents the change that will be performed in the scope of the payment layer project to make openIMIS ready for interfacing with an payment and accounting system

Glossary:

Account receivable : JLN term https://openimis.atlassian.net/wiki/spaces/OP/pages/1089503342

Account payable: JLN term Accounts payable 

outbound invoice, aka invoice: invoice that openIMIS send to some other third parties

inbound invoice, aka bill: invoice that openIMIS recieves from some other third parties

outbound payment, aka bill payment: payment that openIMIS send to some other third parties Payment to providers

inbound payment aka invoice payment: payment that openIMIS recieves from some other third parties like Premium collection and Funding

Models:

The concept is to use a widely use format as base. inspiration can form FHIR invoice and SAGE API Invoices. openIMIS is not an accounting system therefore generating books and ledger is not in the project scope but invoice are a good representation for the account receivable mentioned above. To bring flexibility, a JSON fields was added to the invoice line in case a structured details is required.

The link with the Source and actor won’t be in a form a database foreign keys because those could be from different table.

invoices

Nice to have: editable if not payed or validated

field

type

comment

HistoryBusinessModel fields

 

 

subject_type

str

1 contribution/contract/funding --> Drop down

subject_id

uuid/int ?

https://stackoverflow.com/questions/33528098/django-model-one-foreign-key-to-many-tables Picker based on drop down ? (multiple picker displayed based drop down ? )

thirdparty_type

str

1 Familly/PH/payer/User/Insuree --> Drop down

thirdparty_id

uuid/int ?

https://stackoverflow.com/questions/33528098/django-model-one-foreign-key-to-many-tables Picker based on drop down ? (multiple picker displayed based drop down ? )

(nice to have)related_invoice_id

uuid

link to invoices

 code

 str 

or reference for the insurance (editable)

 code_tp

 str 

or reference for the thirdparty (editable)

 code_ext

 str 

if required for external system integration such as payment systems (editable)

 date_due

 date 

date on which the payment is due (editable)

 date_invoice

 date 

Date of the “invoice“ (date of today but editable)

 *dateValidFrom

 date 

invoice covering service/item from (editable)

 *dateValidTo

 date 

invoice covering service/item to (editable)

 date_payed

 date 

Date on which the payment was actually documented as Done (editable)

 amount_discount

 float 

total of the detail discount (calculated be)

 amount_net

 float 

Total without tax (calculated be)

 tax_analysis

 json 

 

1 2 3 4 5 6 7 8 (calculated be) tax details { "lines": [ {"code":"", "label":"", "rate":"", "base":"", "amount":""}] … ], "total":"" }

 amount_total

 float 

total net + tax total (calculated be)

 status

 int 

ENUM: draft, validated, payed, cancelled, deleted (editable ), amended, suspended

 currency_tp_code

 str 

currency of the third_party (if different) (hidden)

 currency_code

 str 

currency of insurance (calculated be) (hidden)

 note

 bigttext 

(editable)

 terms

 bigttext 

conditions (editable)

payment_reference

 str 

 

invoiceLineItems

to document the content for the Invoice (editable if invoice not payed or validated)

field

type

comment

HistoryBusinessModel fields

 

 

code

 str 

reference (editable)

line_type (displayed as a link/fe-contribution: List of Modules claims, Contract details, Policies)

 

policy, contribution --> Drop down

line_id

 

 

invoiceId

UUID

reference to invoice (hidden)

description

 str 

(editable)

details (UI displayed or hoover above description tooltip)

 json 

depend of the type, TBD (editable as text) if not json wrap it in {'text':DATA} ← quote must be escaped

ledger_account

 str

from specific payment module (editable)

quantity

 float 

(editable)

unit_price

 type 

(editable)

discount

 float 

percentage of discount

deduction

float

to document difference between the std price and the price to be paid, useful for relative pricing (editable)

 tax_rate

 Calculation uuid 

Calculation to calculate the tax (picker, rule type: tax, subtype *)

tax_analysis(hoover above amount_total tooltip)

json

1 2 3 4 5 6 7 8 calculated be with rules, show only after saving, not displayed during line update, hid old value tax details { "lines": [ {"code":"", "label":"", "rate":"", "base":"", "amount":""}] … ], "total":"" }

amount_total

float

net +tax (calculated be, updated fe after saving line) :calculated from service, based on invoiceitem

amount_net

 

unit_price*quantity*(1-discount)-deduction (calculated be/, updated fe after saving line)

InvoicePayments

(editable if invoice not in status payed)

To document the payment done on the invoice. out of scope: a payment done for 2 invoice, to support such scenario an “generalPayment“ table need to be created, this table will have sub table with relationships to invoicePayments, once the reconciliation between the different invoice will be done.

field

type

comment

HistoryModel fields

 

 

Status

int

Accepted / Rejected/refunded/cancelled (editable)

code_ext

str

payment reference (editable)

label

str

label of the payment (editable)

code_tp

str

Reference from the payment system / bank (editable)

invoiceId

UUID

reference to invoice (hidden)

code_receipt

 str 

receipt number (editable)

amount_payed

 float

Amount that need to be matched against business items (fees might be added if there were removed before reaching the system) (editable)

fees

 float

(editable)

amount_received

float

Amount that is received (may include or not the fees) (editable)

date_payment

date

(editable)

payment_origin

 

String

invoiceEvents

Read only for all but can add new message

this table will log the event relating to the invoice

Nice to have : addup (only on graphQL querries) mutation logs/history in the event

field

type

comment

HistoryModel fields

 

 

invoiceId

UUID

reference to invoice

type

int

(Message / Status / Warning / Payment / Payment error) module configuration

message

str

for status __(“Status change to %s“))

[out of scope] invoicedocuments

This should be managed by a document management module

Integration points:

Services

  • invoicePaymentRefRecieved (payment_reference)

  • invoiceEventPaymentRejected (msg) msg to event

  • invoicePaymentRecieved(msg, InvoicePayments) → can update the status to payed (also include rejected payment), only last amendment can be payed

  • invoicePaymentRefunded(InvoicePayments)→ can update the status to suspended (warning the busienss service to be update via signal)

  • invoicePaymentCanceled(InvoicePayments)

  • invoiceCreate (called on save)

  • invoiceUpdate (called on save)

  • invoiceDelete

  • invoiceTaxCalculation() calculate tax details by merging the result of invoiceItemTaxCalculation

  • invoiceItemCreate

  • invoiceItemUpdate

  • invoiceItemDelete

  • invoiceItemTaxCalculation calculate tax details base on the tax_rate rule

  • nice-to-have invoiceAmend → create new empty invoice and put current idea in “related_invoice“ and set status to amended

  • invoiceValidateItems → check that we have a business item attached to the invoice are in the right status/ right price: just send a signal, handle by calculation rule, add event if issues

  • invoiceMatchItems → check that we have a business item attached to the invoice (check if the subject_type / id is not empty and point to a valid database object, check line_id/type if no subject_id)

invoice Payment specific modules (Calculation rules)

those calculation rules modules structure

  • models: none

  • services: 1 per signal listened

  • converters: one converter from another openIMIS object to invoice

  • parameters: on for the “thirdparty” and “subject“ on the invoice

    • change might be required in the calculation module to save it in dedicated fields instead of json_ext OR we move those in the json ext fields

    • support search on those parameters

Listening to other modules signal are strikethrough because during the migration not all update will happens through modular therefore such trigger will complexity the invoice creation processes

https://openimis.atlassian.net/wiki/spaces/OP/pages/3089039361

 



 

[out of scope]Claim Co-paiment:

Registration on signals from other module(existing or not)

  • claimSubmitted

  • invoiceCreationFromCalculation

Converters:

[out of scope] - (Product payment module)Funding:

Registration on signals from other module(existing or not)

  • Funding created / updated

  • Contribution created / updated (for Funding families)

  • invoiceCreationFromCalculation

converters:

new funding:

Too soon the new funding structure is not defined

funding contribution (legacy)

see contribution converter in Bill

[out of scope] new  signals are use to trigger action in another module:

  • [one signal per service]

  • invoiceValidated (all invoiceItemMatched and invoiceItemAmountValidated)

  • invoiceFullyPaid

  • invoicePaymentRefRequested

Create a FHIR interface for the accounting systems (change FHIR_R4 ?)

Here the FHIR ressource to be used:

https://www.hl7.org/fhir/invoice.html

Acceptance criteria:

  1. Scheduled task will generates informal sector insurance invoice per head of family for a given time period

  2. Insurance clerk generates formal sector insurance invoice per contract

  3. Insurance clerk display the invoice with details

  4. Insurance clerk add a payment on the invoice

  5. Insurance clerk print the invoice

  6. Insurance clerk delete an invoice (this won’t delete the generating Item)

  7. [should have] access invoice via FHIR invoice resource. (read only

out of scope

  1. Insurance clerk generates a funding invoice (new) for a product/pool

  2. Insurance clerk generates a funding invoice (old) for a product/pool

  3. Policy activated based on invoice payment

Permissions

Invoice (also for invoice Item) Prefix will be 1551

  • Search → 155101

  • Create → 155102

  • Update → 155103

  • Delete → 155104

  • Amend (create amendment) → 155109

Invoice Payment prefix will be 1552

  • Search → 155201

  • Create → 155202

  • Update → 155203

  • Delete → 155204

  • Refund→ 155206

Invoice event, prefix will be 1553

  • Search → 155301

  • Create → 155302 (out of scope)

  • Update → 155303(out of scope)

  • Delete → 155304(out of scope)

  • CreateMessage → 155306

  • DeleteMyMessage → 155307

  • DeleteAllMessage → 155308

Front end

The front end will have the same layout as the contract

Contribution

Invoice should add a choice in the contract three dots menu : create invoice

Search page

search criteria

  • type for invoice

  • third party(NTH: Ideally contribution from the specific payment module based on type)

  • code

  • date_invoice

  • amount_total

  • status

search result

  • type for invoice

  • third party(NTH: display only the recipient attached )

  • code

  • date_invoice

  • amount_total

  • status

No add new button , All invoice MUST be generated using other module like “contract.createInvoice“ or BatchRun …

only delete button if status not payed and edit button (to open the invoice as double click)

 

card page

general information

subject_type /

subject_id

 

Subjet

thirdparty_type/ thirdparty_id

Recipient(invoice)/Sender(Bill)

(nice to have)related_invoice_id

related invoice “Picker with code“

 code

code

 code_tp

Code recipient (resp. sender)

 code_ext

Code external system

 date_due

 date due

 date_invoice

  date invoice

 *dateValidFrom

 from

 *dateValidTo

to

 date_payed

 date payed

 amount_discount

discount

 amount_net

net

 tax_analysis

tax (just show total)

 amount_total

 Total

 status

 status

 currency_tp_code

 currency recipient (resp sender)

 currency_code

 currency

 note

 note 

 terms

 terms

payment_reference

 payment reference

if not payed:

  • Delete button

if payed show no button but the

Should have Print as it is for the claim

tabs

invoiceLines

read only, All invoice MUST be generated using specific payment module

search filters on All bold schema fields

colunm to show All bold schema fields

invoicePayment

search filters on All bold schema fields

  • Add Payment button near the search (see add contract insuree)

column to show All bold schema fields

  • on each line:

    • delete payment

    • edit payment (modal popup), all fields but UUID can be modified

invoiceEvent

search filters on All schema fields but UUID , icontain for message

  • Add Comment button near the search (see add contract insuree) modal popup with a text field

must: message readonly once created: nice-to-have: user can change only his own message

colunm to show All bold schema fields

 

Account receivable, using the same structure as account receivable, when associated to the contract might also replace the “contribution/premium“