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 JLN Process - Accounts receivable
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
field | type | comment |
HistoryBusinessModel fields | ||
subject | json | referenceActor { "label":"", "code":"", "type": "contribution/contract/funding", "id":"UUID", "address":{"text":"",...} } |
recipient | json | referenceSource { "label":"", "code":"", "type": "Insuree/PH/payer/User", "id":"UUID", "address":{"text":"",...} } |
code | str | or reference for the insurance |
code_rcp | str | or reference for the recipient |
code_ext | str | if required for external system integration such as payment systems |
date_due | date | date on which the payment is due |
date_invoice | date | Date of the “invoice“ |
*dateValidFrom | date | invoice covering service/item from |
*dateValidTo | date | invoice covering service/item to |
date_payed | date | Date on which the payment was actually documented as Done |
amount_discount | float | total of the detail discount |
amount_net | float | Total without tax |
tax_analysis | json | tax details { "lines": [ {"label":"", "rate":"", "base":"", "amount":""}] … ], "total":"" } |
amount_total | float | total net + tax total |
status | int | ENUM: draft, validated, payed, cancelled, deleted |
currency_rcp_code | str | currency of the recipient (if different) |
currency_code | str | currency of insurance |
note | bigttext | |
terms | bigttext | conditions |
invoiceLineItems
to document the content for the Invoice
field | type | comment |
HistoryBusinessModel fields | ||
code | str | reference |
invoiceId | UUID | reference to invoice |
description | str | |
details | json | depend of the type, TBD |
ledger_account | int | from specific payment module |
quantity | float | |
unit_price | type | |
discount | float | to document difference between the std price and the price to be paid, useful for relative pricing |
tax_rate | Calculation uuid | Calculation to calculate the tax |
tax_analysis | json | tax details { "lines": [ {"label":"", "rate":"", "base":"", "amount":""}] … ], "total":"" } |
amount_total | float | net +tax |
amount_net | qty * unitprice - discount |
InvoicePayments
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 |
code_ext | str | payment reference |
label | str | label of the payment |
code_rcp | str | Reference from the payment system / bank |
invoiceId | UUID | reference to invoice |
code_receipt | str | receipt number |
amount_payed | float | Amount that need to be matched against business items (fees might be added if there were removed before reaching the system) |
fees | float | |
amount_received | float | Amount that is received (may include or not the fees) |
date_payment | date |
invoiceEvents
this table will log the event relating to the invoice
field | type | comment |
HistoryModel fields |
| |
invoiceId | UUID | reference to invoice |
type | int | (Message / Status / Warning / Payment / Payment error) module configuation |
data | json | Payload linked to type (TODO) |
[out of scope] invoicedocuments
This should be managed by a document management module
Integration points:
Services
invoicePaymentRefRecieved
invoicePaymentRejected
invoicePaymentRecieved
invoicePaymentRefunded
invoiceCreate (called on save)
invoiceUpdate (called on save)
invoiceDelete
invoiceItemCreate
invoiceItemUpdate
invoiceItemDelete
invoiceAmend
invoiceValidateItems
invoiceMatchItems
invoiceCreationFromCalculation (will send a signal)
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 “recipient” 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
Contribution:
the grouping will be done per Head of family, therefore such invoice will have only 1 detail.
Registration on signals from other module(existing or not):
contributionCreatedinvoiceCreationFromCalculation
Converters
informal sector
1 invoice per policy, with 1 invoiceLineItem, dependants might be documented in the details invoiceItemLine
Invoice:
field | type | comment |
subject | json | referenceSource { "label":Product-lable "code":product-code, "type": "Contribution", "id":"UUID", } |
recipient | json | referenceActor { "label":Insuree-name, "code":CHFID, "type": "Insuree", "id":"UUID", "address":{"text":"",...} } |
code | str | IV-[PRODUCT code]-CHFID |
date_due | date | policy effective date |
date_invoice | date | Date of the enrolment |
*dateValidFrom | date | validFrom: policy effective date |
*dateValidTo | date | validTo: policy expiry date |
amount_discount | float | total of the detail discount |
amount_net | float | Total without tax |
tax_analysis | json | null |
amount_total | float | total net |
status | int | validated |
currency_rcp_code | str | default-curency |
currency_code | str | default-curency-code |
note | bigttext | |
terms | bigttext |
InvoiceItem
field | type | comment |
HistoryBusinessModel fields | validFrom: Policy efective date validTo:Policy exiry date | |
code | str | PRODUCT-code |
description | str | PRODUCT-label |
details | json | Dependant otherName, name, gender, age, relation to insuree |
ledger_account | int | Product premium accounting code |
quantity | float | 1 |
unit_price | type | BASE Policy Value |
discount | float | renewal discount … |
tax_rate | Calculation uuid | null |
tax_analysis | json | null |
amount_total | float | net +tax |
amount_net | qty * unitprice - discount |
Contract:
the invoice of a contract will match the contract value and details.
Registration on signals from other module(existing or not)
contractApprovedinvoiceCreationFromCalculation
Converters:
Invoice
field | type | comment |
subject | json | referenceSource { "label":contract-label "code":contract-code, "type": "Contract", "id":"UUID", } |
recipient | json | referenceActor { "label":ph-name, "code":ph-code, "type": "Policyholder", "id":"UUID", "address":{"text":"",...} } |
code | str | IV-[contract code] |
date_due | date | contract-payment-due |
date_invoice | date | Date of the contract approved |
*dateValidFrom | date | validFrom: contract validFrom |
*dateValidTo | date | validTo:contract validTo |
amount_discount | float | total of the detail discount |
amount_net | float | Total without tax |
tax_analysis | json | null |
amount_total | float | total net |
status | int | validated |
currency_rcp_code | str | default-curency |
currency_code | str | default-curency-code |
note | bigttext | |
terms | bigttext |
invoiceItem
field | type | comment |
HistoryBusinessModel fields | validFrom: contractDetails validFrom validTo:contract contractDetails validTo | |
code | str | Product-code |
description | str | product-desc |
details | json | Dependant otherName, name, gender, age, relation to insuree |
ledger_account | int | Product premium accounting code |
quantity | float | 1 |
unit_price | type | contractdetail Value |
discount | float | |
tax_rate | Calculation uuid | null |
tax_analysis | json | null |
amount_total | float | net |
amount_net | qty * unitprice - discount |
[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:
Insurance clerk generates informal sector insurance invoice per head of family for a given time period
Insurance clerk generates formal sector insurance invoice per Policyholder for a given time period
Insurance clerk display the invoice with details
Insurance clerk add a payment on the invoice
Insurance clerk print the invoice
Insurance clerk delete an invoice (this won’t delete the generating Item)
[should have] access invoice via FHIR invoice resource. (read only)
out of scope
Insurance clerk generates a funding invoice (new) for a product/pool
Insurance clerk generates a funding invoice (old) for a product/pool
Policy activated based on invoice payment
Front end
The front end will have the same layout as the contract
Search page
search criteria
type for invoice
recipients (NTH: Ideally contribution from the specific payment module based on type)
code
date_invoice
amount_total
status
search result
type for invoice
recipients (NTH: display only the recipient attached )
code
date_invoice
amount_total
status
No add new button , All invoice MUST be generated using specific payment module
3 dots menu to generate invoice: show date from/date To
it will call invoiceCreationFromCalculation service
card page
general information
All schema fields but UUID
if not payed:
Delete button
if payed show no button
tabs
invoiceLines
read only, All invoice MUST be generated using specific payment module
search filters on All schema fields but UUID
colunm to show All schema fields but UUID
invoicePayment
search filters on All schema fields but UUID
Add Payment button near the search (see add contract insuree)
colunm to show All schema fields but UUID
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
Add Comment button near the search (see add contract insuree) modal popup with a text field
colunm to show All schema fields but UUID
Account receivable, using the same structure as account receivable, when associated to the contract might also replace the “contribution/premium“