Contract Module

Concepts

Contract

This documents the contract that binds the policyHolder (e.g. employer) to pay the contributions and binds the insurance to provide coverage for the agreed benefit packages for the policyholder insuree.
Before every period, a Contract (list of contributions terms) will be generated based on the policy holder insuree information provided by the policy holder (default param, contract dates, CPB).
(Optional) Once generated the policy holder could update the contract (refresh list of employees and change insuree parameters).
Once submitted by the policy holder and approved by scheme admin the contributions part of the contract will be created and be eligible for payment, a trusted user could create directly an approved contract through the API.

Disclaimer for contract outside formal sector

Even if on the data structure level the contract should be usable for direct contracting (without policyholder), this work focuses on the formal sector work that means that the team will deliver a solution that work with the formal sector but may not directly usable for direct contracting

Payment and policy update

Policy holder will make a single payment per contract (list of contributions of his insuree)
The payment will be linked to all the contributions which are related to the contract.
Depending on the configuration of openIMIS, the policy validity will be adapted based on the contribution plan and benefit plan rules (i.e., the insureepolicy will be created) based on the creation of the contribution or reception of the payment.

Business Processes

The process bellow will respect the location scope of the users, meaning that to add a policyholder for a region the scheme clerk must have access to that very region.
First the contract will need to be created and approved the payment on a contract will update the status of the contract and the underlying policies
Use cases

 

Three dots menu

(…) means actions for selected item in the list (cf HF claims)

the three dots menu will apply either to all selected line OR to all records filtered, once an option is selected a confirmation popup will precise the action and how many instance are concerned, the mutation result will show how many entity “update“ were successful and failed

  •  

  • Create invoice

Contract

Web application

  • (TBC, could work with scheduler)UC3-1: Add bulk "contract": Policy holder List > select policyholder(s) (or for all the PH part of the search result) > generate bulk contract (…) > enter the date on which the contract must be created if not already covered by previous contract.

  • UC3-10: add “Contract“: Contract search > “Add“ contract > fill the details on the contract page (draft) >save (mandatory fields required) > the insuree from the PH are imported with default calculation params

  • UC3-2: Add "contract" from PH: Policy holder List > Select a Policy Holder > Contract list> Generate contract (the insuree from the PH are imported with default calculation params) > fill the details on the contract page (draft)

  • UC3-11: Access to contract via contract search: Contract search > select contract

  • UC3-12: Access to a contract via PolicyHolder :Policy holder List > Select a Policy Holder > Contract list > Select contract

  • UC3-3: Update contract details: edit button on contract selected >update the details on the contract page (updatable fields will depend on the state) > save

  • UC3-3.1: add contractDetail : update contract > click on add ContractDetail (show Ph insuree) > enter the details in the popup > save

  • UC3-3.2: Update contractDetails: update contract > click the edit button of the ContractDetail (show Ph insuree)> confirm in the delete conf popup

  • UC3-3.3: Dupdate delete contract detail: update contract > click the delete button of the ContractDetail (show Ph insuree)> confirm in the delete conf popup

  • UC3-4: Submit (“sign PH)) "contract": contract selected >open contract > Submit/sign contract > conf popup

  • (TBC)UC3-5: Approve (“sign Insurance“) "Contract" bulk: Select contract(s) > Approve contract (…)(only for submitted contract) > conf pop up with the number of contract impacted

  • UC3-13: Approve (“sign Insurance“) "Contract": Select contract > open contract > contract Approved (only for submitted contract) > conf popup

  • UC3-13.1: see contribution details: "Contract": Select contract > open contract > open contribution details tab

  • UC3-6: Counter "Contract": Select contract > open contract > Counter contract / reject (only for submitted contract) > conf popup

  • UC3-7: Amend "contract": Select contract > open contract > Generate Amendment > confirmation with Amendment number > add details (if it is about a new employee, they should be added before on the employee list)

  • UC3-X: Delete"contract": Contract list > click on the delete button> conf popup (only available for contract in updatable or approvable status)

  • UCP-1: Create invoice via PolicyHolder :Policy holder List > tree dots menu ( > select contract(s)) > create invoice


Backend

  • UC3-8: send payment notification by email

  • UC3-9: send update required (from ask update) notification by email

  • UC3-14: (TBC replace UC3-1) create contract based on CPB periodicity / “renew-replace contract”

  • UC3-15: once approved (contract):

    • Check if there is a valid policy for the insure covered by the contract (+ grace period), if not then it will create such policy with the normal duration and a status "contracted."

    • matching contribution need to be created linked to the policie(s)

    • it the overall amount is > 0 ; create the related payment (payment status 3),

      • if there is an amendment with a null or negative amount and without payment, add the policy of that amendment to the payment


Payment

The new policy state "contracted" indicate that the insuree policy doesn't have the same dates as the policy because it is renewable contract payment that defines the validity of the insureepolicy
on payment, a script will:

  1. retrieve the policies attached the “paid“ contribution (payment is for a contribution)

  2. check that total payment for each contribution match the contribution value

  3. Create or update the policyinsure up to the end of the grace period, two insurees policies could be created if two policies are required to cover the contract period.

Web application

  • UC4-1(Nice to have): add payment for several contract > contract(s) selected > create payment (…) > enter value > save > confirmation giving the contract status

  • UC4-7(should have): add payment for a single contract selected > open contract page >create payment > enter value > save > confirmation giving the contract status

  • UC4-2(Nice to have): update payment: Policy holder List > Select a Policy Holder > payment list > Select payment > update value > save > confirmation giving the contract status

  • UC4-3(should have): delete payment: Policy holder List > Select a Policy Holder > payment list > Select payment > delete payment > confirmation giving the contract status

Back end

  • UC4-6: assign a credit note to contract: On contract approval, if there is a credit note not assigned to a contract, it will be assigned to the newly approved contract as a payment.

  • UC5-1: When a full payment is received for a contract, the policy of the policyholder insuree part of the contact will be renewed if needed

  • UC5-2: When a full payment is received for a contract, the insureepolicy of the policyholder insuree part of the contact will be activated

 

Back end module Details design

Entities

Contract (Contribution Collection)(HistoryBusinessModel)

  • Code (varchar (64) )*

  • PolicyHolderUUID (fk policyHolder)

  • AmountNotified (float)

    • Upon Automatic creation

  • AmountRectified (float)

    • Manual update from the policy holder, saved on submit

  • AmountDue (float)

    • Value approved by the Scheme admins

  • DateApproved (datetime)

  • DatePaymentDue (date)

  • State (ConfigEnum:ContractState)

  • PayementReference(varchar 256)

  • Amendment ( int 0 for the contract)*

Communications on the contract will be saved on the jsonExt fields with that structure:

{“comments”:[{“From”:”Portal/webapp”, “user“:<userid>, “date“:<datetime>,”msg”<message> }]}

A special filter should be available on the queryset to retrieve all contract that have the the “amount between 2 values following that logic (should be usable by FE):

  • the BE will look for any contract that have either of amountDue, amountRectified or AmountNotified between those two amounts

Entity ContractDetails (input) - under Contract (HistoryModel)

  • ContractUUID (fk Contract)*

  • insureeeID (fk_insuree)*

  • PolicyHolderInsureeUUID (fk PolicyHolderInsuree)

  • ContributionPlanBundleUUID:Version(fk ContributionPlanBundle)*

  • Json_ext (json fields part of HistoryModel)

    • PolicyHolderInsuree parameters

Entity ContractContributionPlanDetails (output) - under ContractDetails (HistoryBusinessModel)

  • ContributionPlanUUID (fk_contributionPlan)*

  • PolicyID (fk_policy)*

  • ContractDetailsUUID (fk_contractdetails)*

  • ContributionId (fk_contribution)

ContributionPlan parameters will be stored in the json_ext part of the HistoryModel

Payment table already exist tblPayment. in scope in BS migration (TBC)

https://github.com/openimis/openimis-be-payment_py

Payment status

-1 Error when saving Intent to pay (see RejectedReason)
0 Intent to pay saved without errors
1 Control Number request sent
2 Control Number request sent
3 Control Number received without error
-3 Error related to Control Number request or Payment confirmation (should have different values per post)
4 Received Payment
5 Payment matched

RejectedReason

2 Insurance number missing Not valid insurance or missing product code
3 Invalid Officer Code Not valid enrolment officer code
4 Missing product or Product does not exists Not valid insurance or missing product code
4 Wrong match of Enrollment Officer agaists Product Enrolment officer code and insurance product code are not compatible
5 The family doesn't contain this product for renewal Beneficiary has no policy of specified insurance product for renewal
5 Proxy family can not renew Beneficiary has no policy of specified insurance product for renewal
7 Insurance number not existing in system Insuree not enrolled and prior enrollment mandatory

Authorities

To manage the group insurance several authorities will be added, the existing authorities have a "*" :

  • PolicyHolderContract the Prefix will be 1521

    • Search → 152101

    • Create → 152102

    • Update → 152103

    • Delete → 152104

    • Renew → 152106

    • Submit → 152107

    • Approve/ask for change → 152108

    • Amend (create amendment) → 152109

  • Payment, Prefix will be 1014 ( * existing in core)

    • Search → 101401*

    • Create/Submit → 101402*

    • Update → 101403*

    • Delete → 101404*

    • Approve/Validate → 101408

(*) ContractDetails don’t have rights anymore because they inherit from contract

Services

  • create

    • run service updateFromPHInsuree

    • NotifiedAmount = ContractValuation(false)

    • Contract state will become “Draft”

  • edit/update

    • check rights for contract / amendments

    • check status

      • if in “draft”/ “request for information“ / “counter“ only the code cannot be changed,

      • if in “Negotiable” changes are possible only with the authority “Approve/ask for change”

  • delete

    • check rights

    • block deleting contract not in Updateable or Approvable state

  • submit

    • check right

    • RectifiedAmount = ContractValuation(false)

    • send signal

    • Contract state will become “Negotiable”

  • approved

    • check rights (Approve/ask for change)

    • send signal

    • RectifiedAmount = ContractValuation(true)

    • Contract state will become “Executable”

    • createContribution

    • createcontractPayment

  • counter

    • check right (Approve/ask for change)

    • Contract state will become “counter”,

  • renew

    • create a new contract that follow the existing active contract (if not yet existing)

      • Date to (the previous contract) became date From of the new contract (TBC if we need to add 1 day)

      • Date To of the new contract is calculated by DateFrom new contract + “Duration in month of previous contract“

      •  

  • amend

    • check rights

    • create a new “amendment“ contract from the last amendement

    • increment Amendment of 1 (i.e. 1st amendment will have 1, 2nd: 2 … )

    • change status of the previous contract/amendement to 6 “addendum“ (Nice to have: 4 and 6 when addendum approved)

    • NotifiedAmount = ContractValuation(false)

    • Amendement state will become “Draft”

  • ContractValuation(bool save)

    • create the ContractContributionPlanDetails based on the ContractDetails (nice to have: if periodicity of the contribution plan is smaller that the contract datevalidFrom-datevalidTo then create enough ContractContributionPlanDetails to cover for the contract duration)

      • if the save param is true

        • use GetContributionLength to get the dateValidFrom DateValidTo of ContractContributionPlanDetails

        • createCCPDetails

      • if amendement: Contract value = value of the contributionplandetails - amount already payed for that contract (contract in state 7-8)

    • return the total amount

  • createCCPDetails

    • Check if there is a policy to cover from the dateValidFrom DateValidTo

      • if none: create one using the duration from the product with the status “contracted“ 32

      • if there is one that cover the full duration: use it

      • if there is one that does NOT cover the full duration: create a new policy to cover the missing part and split the ContractContributionPlanDetails and linked to the matching policies (dates of ContractContributionPlanDetails ) must be within policy dates.

    • create the matching CCPDetail (C: contract, P: policy CCPD Contract contributionplanDetails)

      • 1 policy: CCPD.DateVaildFrom = C.DateVaildFrom CCPD.DateVaildTo = C.DateVaildFrom + Duration

      • 2 policies:

        • CCPD1.DateVaildFrom = C.DateVaildFrom & CCPD.DateVaildTo = p1.expiry_date / P2.startdate

        • CCPD2.DateVaildFrom = p1.expiry_date / P2.startdate & CCPD2.DateVaildTo = C.DateVaildFrom + Duration

  • createContribution

    • create the contributions (from openimis-be-contribuiton_py) based on the ContractContributionPlanDetails

  • createcontractPayment

    • create a payment that cover all contributions related to the contract

  • updateFromPHInsuree

    • if PH is set, Update the ContractDetails based on the PHInsuree

  • getNegativeAmountAmendement (creditnote)

    • look for approved contract (amendement) for that PH that have a negative AmountDue

  • activateContractedPolicies (listen to payment signal)

    • NICE TO HAVE: this function will call a function for the contributionplan to retrieve the list of dependant that need to be covered by the contact (in addition to the insuree )

    • Activate the policy related to the contract (create policy insuree for the contract period + grace period)

    • Contract state will become “effective”,

    • change status to 7 - Effective

  • TerminateContract

    • previous contract of the (DateValidTo) will become “terminated“

  • PHInsureToCDetatils

    • Takes a PHinsuree as input and a contractDetails as output where the insuree and the CPB from the PH insureee will be used

    • This is likely to be called by the mutation to create details from front end when the PH is set

  • createInvoice

    • will try to run convert the ContractContributionPlanDetails of the contract to invoice lines

    • will save the invoice and the converted lines

 

Signal

ApprovedContract

  • Use Django Email to send payment notificaiton (it means that the setting in code should use Env var for the EMAIL settings)

  • Use text from configuration using django LANGUAGE CODE

 

Config

"ContractState":[

{

"value":"1",
"label":{
"fr":"Demande d'information",
"en":"Request for information"

}
}, {

"value":"2",
"label":{
"fr":"Brouillon",
"en":"Draft"

}
}, {

"value":"3",
"label":{
"fr":"Offre",
"en":"offer"

}
}, {

"value":"4",
"label":{
"fr":"En negociation",
"en":"Negotiable"

}
}, {

"value":"5",
"label":{
"fr":"Apprové",
"en":"executable"

}
}, {

"value":"6",
"label":{
"fr":"addendum",
"en":"addendum"

}
}, {

"value":"7",
"label":{
"fr":"En cours",
"en":"effective"

}
}, {

"value":"8",
"label":{
"fr":"Appliqué",
"en":"executed"

}
}, {

"value":"9",
"label":{
"fr":"Suspendu",
"en":"Disputed"

}
}, {

"value":"10",
"label":{
"fr":"Terminé",
"en":"terminated"

}

, {

"value":"11",
"label":{
"fr":"révision demandé",
"en":"counter"

}
}

}

“updatable”:[1,2,11] (that corresponds to “draft”, “request for information“ and “counter”),

“Approvable”:[4] (that corresponds to “negotiable“)

“payment_notification“:{“en“:”Dear <CONTACT-NAME>\n The contract<CONTRACT-CODE> - <CONTRACT-NAME> was approved\n Please proceed to the payment of <CONTRACT-DUEAMOUNT> with the reference <CONTRACT-PAYMENT-REFERENCE>\n Best regards ” , “fr“:”Monsieur, Madame <CONTACT-NAME>\n le contract<CONTRACT-CODE> - <CONTRACT-NAME> à été apprové\n Veuillez faire un paiement de <CONTRACT-DUEAMOUNT> avec la référence <CONTRACT-PAYMENT-REFERENCE>\n Meilleurs Salutations ”}

“counter_notification“:{“en“:”Dear <CONTACT-NAME>\n The contract<CONTRACT-CODE> - <CONTRACT-NAME> was counter\n Please proceed recheck the information and correct the issues, in case of questions please check contact us\n Best regards ” , “fr“:”Monsieur, Madame <CONTACT-NAME>\n le contract<CONTRACT-CODE> - <CONTRACT-NAME> à été contré, veuillez verifier les information saisie, en cas de question veuillez nous contacter\n Meilleurs Salutations ”}

Front end detail design

  • below or above Policy Holders menu entry

  • use ReceiptIcon from Material UI library

Contract search page

search options

it will be possible to search on:

  • code (varchar, Icontains lookup)

  • PolicyHolder

  • (nice to have) Insuree

  • AmountFrom - AmountTo (float)

    • Search in the 3 amounts

  • DatePaymentDue (date, datePaymentDue lookup)

  • State (ConfigEnum:ContractState)

  • PaymentReference (string, Icontains lookup)

    • used for reconciliation between IMIS and bank account statement: if you have a reference on the wire transfer and on IMIS you can know what this payment concerns

  • Amendment (int, min = 0, max is not specified)

    • int = 0 for the contract, int > 0 for an amendment

  • DateValidFrom

  • DateValidTo

  • Show deleted checkbox

  • search button

  • reset search button

search results column

  • Code

  • state

  • amount ( if not null amountDue else if not null amountRectified else AmountNotified )

    • Nice to have: hoover 3 amounts

  • Payment due date

    • Nice to have: hoover: PayementReference

  • dateValidFrom

  • dateValidTo

  • Amendement

  • update, delete button

… 3dot menu above the result table with action on single/multi select of contract (if no contract selected, the options applies to all contract from the search result)

  • approve contract (confirmation box with the number of contract to be approved)

  • counter contract (confirmation box with the number of contract to be countered)

  • (nice to have): renew contract

  • (nice to have): Add payment

  • (nice to have): Activate policy

Material UI “add” to add a new contract (redirect to new contract page)

Contract card

the contract card will have the same layout as the PH page: a general information section and 3 tabs

General information

  • Code (varchar (64) )

  • PolicyHolderUUID (fk policyHolder)

  • AmountNotified (float)

  • AmountRectified (float)

  • AmountDue (float)

  • DateApproved (datetime) READ ONLY

  • DatePaymentDue (date ) READ ONLY, NICE TO HAVE update possible only with the approve/counter authority

  • State (ConfigEnum:ContractState, 2 (which corresponds to Draft) by default, read-only)

  • PayementReference(varchar 256)

  • Amendment (0 by default, read-only)*

  • DateValidFrom

  • DateValidTo

Material UI will have different function

  • Save if there is changed

  • if no changes

    • Submit from a “draft”/ “request for information“ / “counter” contract

    • Approve/Counter (reject as sub-option) for “Negotiable” contract

    • Amend(NTH: renew as sub-option) for other status but “terminated“

on contract amend (for contract not terminated, not Negociable nor updatable state )

Code, PH, DateValidFrom cannot be changed

NICE TO HAVE: text box that will be save a comment json_ext

  • {“comments”:[{“From”:”Portal/webapp”, “user“:<userid>, “date“:<datetime>,”msg”<message> }]}

on contract creation

Code, DateValidFrom and DateValidTo is mandatory

Nice to have:

  • with update/create authority,

    • Date payment due READ ONLY

  • with the authority “Approve/ask for change”

    • Editable

on contract update

PH Can be set but not edited once saved.

  • with update authority,

    • in updatable state only DateValidFrom and DateValidTo cannot be changed,

    • no changes possible in other status

  • with the authority “Approve/ask for change”

    • in updatable state all can be changed,

    • in “Approvable” changes are possible only Code, DateValidFrom and DateValidTo cannot be changed,

NICE TO HAVE: text box that will be save a comment json_ext

  • {“comments”:[{“From”:”Portal/webapp”, “user“:<userid>, “date“:<datetime>,”msg”<message> }]}

on contract submission

at least 1 contract detail must be present

on contract counter

NICE TO HAVE: text box that will be save a comment json_ext

  • {“comments”:[{“From”:”Portal/webapp”, “user“:<userid>, “date“:<datetime>,”msg”<message> }]}

on contract create invoice

Show how many invoice were created

Contract details tab

search criteria / filter

  • insuree picker (with sort option ASC/DESC)

    • Limited to PHInsuree

    • Nice to have : not limited to PHinsuree if PH not set

  • CBP picker (with sort option ASC/DESC)

    • Limited to PHCPB

    • Nice to have : not limited to PHCPB if PH not set

  • Apply search button

  • reset search button

  • Create new Contract Details button (top right) enabled only if

    • with Update authority, updatable state

    • with Approve authority, updatable and approvable state

will show the contract details

  • insuree picker readonly

  • CPB picker readonly

  • calculation parameters

  • Edit and Delete buttons enabled only if

    • with Update authority, updatable state

    • with Approve authority, updatable and approvable state

on add contract details

a popup will be display with (mandatory fields marked with *):

  • if PH is set (must have)

    • PHInsuree picker (Insuree, same fields as the Insuree picker) *

    • CPB not editable per the user, auto update form Pinsuree (unless this can be add on the PH insuree picker)

  • if PH is not set (nice to have)

    • CPB picker restricted to the PHCPB if PH define on the contract *

    • Insuree picker restricted to the PHinsuree if PH define on the contract *

  • calculation parameters (Mandatory fields will be managed by the calculation contribution)

  • Save button

The relationship with the contract is not displayed because implicit

on delete contract details

confirmation popup

on edit contract details

  • only calculation parameters could be updated

confirmation popup

Contract contributiondetails tab

this that is readonly, availabable only in state NOT approvable or updatable

search criteria / filter

  • insuree picker (with sort option ASC/DESC)

  • CPB picker (with sort option ASC/DESC)

  • CP picker (with sort option ASC/DESC)

  • Product (with sort option ASC/DESC)

  • Search button

  • reset search button

will show the contract details

  • insuree picker readonly

  • CP picker readonly

  • calculation param

(Nice to have)Contract payment tab

Will display the payments that concern contribution linked to CCPD

the material UI button can create a payment for the remaining amount not covered by the payment.

Insureepolicy tab

Will dispaly the list of insuree impacted by the contract (as primary insuree or dependant)

Search criteria

Insuree (search box popup with name .. )

Result page

read only lines

columns

  • insuree label (as defined by insuree contribution)

  • Nice to have: start_date, effective_date, expiry_date

INSUREEPOLICY_SEARCH perms = 101500

NICE TO HAVE: Contract comment tab

Will dispaly the comments entered on the contact, comment are saved as a list in the json_ext

  • {“comments”:[{“From”:”Portal/webapp”, “user“:<userid>, “date“:<datetime>,”msg”<message> }]}

a input box will be available at the bottom of the list to add a new comment

Contract Tab on PolicyHolder

should display only Contracts, which have this particular Policy Holder assigned

search options

it will be possible to search on:

  • code (varchar icontain, istart)

  • AmountFrom - AmountTo (float)

    • Search in the 3 amounts

  • DatePaymentDue (date)

  • State (ConfigEnum:ContractState)

  • PayementReference(string)

  • Amendment ( int 0 for the contract)

  • DateValidFrom

  • DateValidTo

  • Show deleted checkbox

  • search button

  • reset search button

search results column

  • Code

  • state

  • amount ( if not null amountDue else if not null amountRectified else AmountNotified )

    • Nice to have: hoover 3 amounts

  • Payment due date

    • Nice to have: hoover: PayementReference

  • dateValidFrom

  • dateValidTo

  • Amendement

  • update, delete and button

… 3dot menu above the result table with action on single/multi select of contract (if no contract selected, the options applies to all contract from the search result)

  • approve contract (confirmation box with the number of contract to be approved)

  • (nice to have: renew contract)

  • Create invoice

Material UI “add” to add a new contract (redirect to new contract page)