<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://ohcnwiki.tellmey.fyi/index.php?action=history&amp;feed=atom&amp;title=References%2FFacility_Config</id>
	<title>References/Facility Config - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://ohcnwiki.tellmey.fyi/index.php?action=history&amp;feed=atom&amp;title=References%2FFacility_Config"/>
	<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Facility_Config&amp;action=history"/>
	<updated>2026-07-06T05:18:56Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.4</generator>
	<entry>
		<id>https://ohcnwiki.tellmey.fyi/index.php?title=References/Facility_Config&amp;diff=397&amp;oldid=prev</id>
		<title>Admin: Automated edit (via update-page on MediaWiki MCP Server)</title>
		<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Facility_Config&amp;diff=397&amp;oldid=prev"/>
		<updated>2026-07-06T04:02:02Z</updated>

		<summary type="html">&lt;p&gt;Automated edit (via update-page on MediaWiki MCP Server)&lt;/p&gt;
&lt;a href=&quot;https://ohcnwiki.tellmey.fyi/index.php?title=References/Facility_Config&amp;amp;diff=397&amp;amp;oldid=157&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://ohcnwiki.tellmey.fyi/index.php?title=References/Facility_Config&amp;diff=157&amp;oldid=prev</id>
		<title>Admin: OHC identity seed</title>
		<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Facility_Config&amp;diff=157&amp;oldid=prev"/>
		<updated>2026-07-04T22:45:00Z</updated>

		<summary type="html">&lt;p&gt;OHC identity seed&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Doc header&lt;br /&gt;
|type=reference&lt;br /&gt;
|domain=facility&lt;br /&gt;
|title=Facility Config&lt;br /&gt;
|order=2&lt;br /&gt;
|introduced=3.0&lt;br /&gt;
|model=FacilityConfig&lt;br /&gt;
|reference=References/Base models &amp;amp;amp; conventions&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Holds one facility&amp;#039;s billing configuration: a discount-code catalog, discount component definitions, a discount-stacking rule, and the invoice-number template. The Django model &amp;lt;code&amp;gt;FacilityMonetoryConfig&amp;lt;/code&amp;gt; stores all of it, but three fields are plain &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt;s whose shape, enums, and validation live in the Pydantic specs that drive the API. Both layers are documented here.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sources:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* Model: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/models/facility_config.py &amp;lt;code&amp;gt;care/emr/models/facility_config.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* Spec: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/facility/spec.py &amp;lt;code&amp;gt;care/emr/resources/facility/spec.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* Monetary types: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/common/monetary_component.py &amp;lt;code&amp;gt;care/emr/resources/common/monetary_component.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* Coding: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/common/coding.py &amp;lt;code&amp;gt;care/emr/resources/common/coding.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* Expression evaluator: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/invoice/default_expression_evaluator.py &amp;lt;code&amp;gt;care/emr/resources/invoice/default_expression_evaluator.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* API viewset: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/api/viewsets/facility.py &amp;lt;code&amp;gt;care/emr/api/viewsets/facility.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
== Models ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityMonetoryConfig&amp;lt;/code&amp;gt;&lt;br /&gt;
| Per-facility billing config: facility-scoped discount codes, discount monetary component definitions, a discount-stacking rule, and the invoice-number expression&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacilityMonetoryConfig&amp;lt;/code&amp;gt; extends [[References/Base models &amp;amp;amp; conventions|&amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt;]], so it inherits &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;created_date&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;modified_date&amp;lt;/code&amp;gt;, soft-delete via &amp;lt;code&amp;gt;deleted&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;created_by&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;updated_by&amp;lt;/code&amp;gt;, and the &amp;lt;code&amp;gt;history&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt; JSON fields.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;code&amp;gt;FacilityMonetoryConfig&amp;lt;/code&amp;gt; fields ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=FacilityConfig|section=FacilityMonetoryConfig fields|name=facility|type=OneToOneField → Facility|notes=yes}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=FacilityMonetoryConfig fields|name=discount_codes|type=JSONField → list[Coding]|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=FacilityMonetoryConfig fields|name=discount_monetary_components|type=JSONField → list[MonetaryComponentDefinition]|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=FacilityMonetoryConfig fields|name=discount_configuration|type=JSONField → DiscountConfiguration | null|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=FacilityMonetoryConfig fields|name=invoice_number_expression|type=CharField(1000)|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;code&amp;gt;discount_codes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;discount_monetary_components&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;discount_configuration&amp;lt;/code&amp;gt; are declared as plain &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt;s. The database accepts any JSON — their structure is enforced only at the API layer by the Pydantic specs below.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
== JSON field shapes ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Coding&amp;lt;/code&amp;gt; shape ===&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;code&amp;gt;discount_codes[]&amp;lt;/code&amp;gt; entry is a &amp;lt;code&amp;gt;Coding&amp;lt;/code&amp;gt; object (&amp;lt;code&amp;gt;model_config = extra=&amp;amp;quot;forbid&amp;amp;quot;&amp;lt;/code&amp;gt;, so unknown keys are rejected).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Required&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=FacilityConfig|section=Coding shape|name=system|type=str | null|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=Coding shape|name=version|type=str | null|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=Coding shape|name=code|type=str|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=Coding shape|name=display|type=str | null|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;MonetaryComponentDefinition&amp;lt;/code&amp;gt; shape ===&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;code&amp;gt;discount_monetary_components[]&amp;lt;/code&amp;gt; entry subclasses &amp;lt;code&amp;gt;MonetaryComponent&amp;lt;/code&amp;gt; and adds &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt;. Definition mode overrides or disables the base duplicate-code and amount-or-factor checks, but rejects a &amp;lt;code&amp;gt;base&amp;lt;/code&amp;gt;-typed component outright.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=title|type=str|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=monetary_component_type|type=MonetaryComponentType enum|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=code|type=Coding | null|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=factor|type=Decimal | null|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=amount|type=Decimal | null|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=tax_included_amount|type=Decimal | null|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=global_component|type=bool|notes=no}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=conditions|type=list[EvaluatorConditionSpec]|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;EvaluatorConditionSpec&amp;lt;/code&amp;gt; (each &amp;lt;code&amp;gt;conditions[]&amp;lt;/code&amp;gt; entry):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Required&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=metric|type=str|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=operation|type=str|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=MonetaryComponentDefinition shape|name=value|type=dict | str|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;DiscountConfiguration&amp;lt;/code&amp;gt; shape ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;discount_configuration&amp;lt;/code&amp;gt; object.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Required&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=FacilityConfig|section=DiscountConfiguration shape|name=max_applicable|type=int (ge=0)|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=DiscountConfiguration shape|name=applicability_order|type=DiscountApplicability enum|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Enum values ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;MonetaryComponentType&amp;lt;/code&amp;gt; values ===&lt;br /&gt;
&lt;br /&gt;
From &amp;lt;code&amp;gt;care/emr/resources/common/monetary_component.py&amp;lt;/code&amp;gt;. String enum.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Value&lt;br /&gt;
! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;base&amp;lt;/code&amp;gt;&lt;br /&gt;
| Base price (not allowed in a &amp;lt;code&amp;gt;MonetaryComponentDefinition&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;surcharge&amp;lt;/code&amp;gt;&lt;br /&gt;
| Additional charge&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;discount&amp;lt;/code&amp;gt;&lt;br /&gt;
| Discount line item&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;tax&amp;lt;/code&amp;gt;&lt;br /&gt;
| Tax line item&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;informational&amp;lt;/code&amp;gt;&lt;br /&gt;
| Informational-only component&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;DiscountApplicability&amp;lt;/code&amp;gt; values ===&lt;br /&gt;
&lt;br /&gt;
From &amp;lt;code&amp;gt;care/emr/resources/common/monetary_component.py&amp;lt;/code&amp;gt;. String enum.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Value&lt;br /&gt;
! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;total_asc&amp;lt;/code&amp;gt;&lt;br /&gt;
| Apply discounts in ascending order of total&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;total_desc&amp;lt;/code&amp;gt;&lt;br /&gt;
| Apply discounts in descending order of total&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Resource specs (API schema) ==&lt;br /&gt;
&lt;br /&gt;
These Pydantic specs build on [[References/Base models &amp;amp;amp; conventions|&amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt;]] (&amp;lt;code&amp;gt;serialize&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt;, the &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;perform_extra_deserialization&amp;lt;/code&amp;gt; hooks, &amp;lt;code&amp;gt;__model__&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;__exclude__&amp;lt;/code&amp;gt;) and define how monetary config is written and read. There is no standard CRUD endpoint for it — writes go through dedicated facility detail actions, and reads come back inside the facility retrieve payload.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Spec&lt;br /&gt;
! Role&lt;br /&gt;
! Bound to&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityMonetaryCodeSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · set monetary config&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityMonetoryConfig&amp;lt;/code&amp;gt;&lt;br /&gt;
| Validates and persists &amp;lt;code&amp;gt;discount_codes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;discount_monetary_components&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;discount_configuration&amp;lt;/code&amp;gt; in one payload. &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt;d onto the get-or-created config row&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityInvoiceExpressionSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · set invoice expression&lt;br /&gt;
| (plain &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt;)&lt;br /&gt;
| Single field &amp;lt;code&amp;gt;invoice_number_expression&amp;lt;/code&amp;gt;; validated by dry-run before save&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityRetrieveSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · facility detail&lt;br /&gt;
| &amp;lt;code&amp;gt;Facility&amp;lt;/code&amp;gt;&lt;br /&gt;
| Surfaces the facility&amp;#039;s monetary config plus instance-level catalogs in &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;MonetaryComponentDefinition&amp;lt;/code&amp;gt;&lt;br /&gt;
| nested (write)&lt;br /&gt;
| —&lt;br /&gt;
| Shape of each &amp;lt;code&amp;gt;discount_monetary_components[]&amp;lt;/code&amp;gt; entry&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DiscountConfiguration&amp;lt;/code&amp;gt;&lt;br /&gt;
| nested (write)&lt;br /&gt;
| —&lt;br /&gt;
| Shape of &amp;lt;code&amp;gt;discount_configuration&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Coding&amp;lt;/code&amp;gt;&lt;br /&gt;
| nested (write)&lt;br /&gt;
| —&lt;br /&gt;
| Shape of each &amp;lt;code&amp;gt;discount_codes[]&amp;lt;/code&amp;gt; entry&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;FacilityMonetaryCodeSpec&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;__model__ = FacilityMonetoryConfig&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;__exclude__ = []&amp;lt;/code&amp;gt;. Write schema for the &amp;lt;code&amp;gt;set_monetary_config&amp;lt;/code&amp;gt; action.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=FacilityConfig|section=FacilityMonetaryCodeSpec|name=discount_codes|type=list[Coding]|notes=Facility-defined codes}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=FacilityMonetaryCodeSpec|name=discount_monetary_components|type=list[MonetaryComponentDefinition]|notes=Selectable discount definitions}}&lt;br /&gt;
{{Field|model=FacilityConfig|section=FacilityMonetaryCodeSpec|name=discount_configuration|type=DiscountConfiguration | null|notes=Stacking rule}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Model validators run on write:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Count limits&amp;#039;&amp;#039;&amp;#039; — &amp;lt;code&amp;gt;discount_codes&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;discount_monetary_components&amp;lt;/code&amp;gt; must each hold fewer than 100 entries (&amp;lt;code&amp;gt;DISCOUNT_CODE_COUNT_LIMIT&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;DISCOUNT_MONETARY_COMPONENT_COUNT_LIMIT = 100&amp;lt;/code&amp;gt;; the check rejects &amp;lt;code&amp;gt;&amp;amp;gt;= 100&amp;lt;/code&amp;gt;).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;No duplicate codes&amp;#039;&amp;#039;&amp;#039; — &amp;lt;code&amp;gt;code&amp;lt;/code&amp;gt; values within &amp;lt;code&amp;gt;discount_codes&amp;lt;/code&amp;gt; must be unique.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;No redefining system codes&amp;#039;&amp;#039;&amp;#039; — a facility code may not reuse a &amp;lt;code&amp;gt;[code, system]&amp;lt;/code&amp;gt; pair already in instance &amp;lt;code&amp;gt;settings.DISCOUNT_CODES&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;All component codes must be defined&amp;#039;&amp;#039;&amp;#039; — every &amp;lt;code&amp;gt;discount_monetary_components[i].code&amp;lt;/code&amp;gt; (when present) must match a &amp;lt;code&amp;gt;[code, system]&amp;lt;/code&amp;gt; pair from either &amp;lt;code&amp;gt;settings.DISCOUNT_CODES&amp;lt;/code&amp;gt; (instance) or the facility&amp;#039;s &amp;lt;code&amp;gt;discount_codes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;FacilityInvoiceExpressionSpec&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Plain &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt;, not an &amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt;. Write schema for the &amp;lt;code&amp;gt;set_invoice_expression&amp;lt;/code&amp;gt; action.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=FacilityConfig|section=FacilityInvoiceExpressionSpec|name=invoice_number_expression|type=str|notes=Validated via &amp;lt;code&amp;gt;evaluate_invoice_dummy_expression(v)&amp;lt;/code&amp;gt;; any exception raises &amp;lt;code&amp;gt;&amp;amp;quot;Invalid Expression&amp;amp;quot;&amp;lt;/code&amp;gt;. An empty value skips validation}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The dry-run context supplies &amp;lt;code&amp;gt;invoice_count=1234&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;current_year_yyyy=2025&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;current_year_yy=25&amp;lt;/code&amp;gt;. At runtime, &amp;lt;code&amp;gt;evaluate_invoice_identifier_default_expression(facility)&amp;lt;/code&amp;gt; evaluates the stored expression against the live invoice count and current year.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;FacilityRetrieveSpec&amp;lt;/code&amp;gt; (read path) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacilityRetrieveSpec&amp;lt;/code&amp;gt; (extends &amp;lt;code&amp;gt;FacilityReadSpec&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;FacilityPermissionsMixin&amp;lt;/code&amp;gt;) injects the monetary config into the facility detail response from &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt;, calling &amp;lt;code&amp;gt;FacilityMonetoryConfig.get_monetory_config(obj.id)&amp;lt;/code&amp;gt; (get-or-create). The monetary-config-derived fields on the read payload:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Source&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;invoice_number_expression&amp;lt;/code&amp;gt;&lt;br /&gt;
| config row&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;discount_codes&amp;lt;/code&amp;gt;&lt;br /&gt;
| config row (&amp;lt;code&amp;gt;list[dict]&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;discount_monetary_components&amp;lt;/code&amp;gt;&lt;br /&gt;
| config row (&amp;lt;code&amp;gt;list[dict]&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;discount_configuration&amp;lt;/code&amp;gt;&lt;br /&gt;
| config row (&amp;lt;code&amp;gt;dict | null&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;instance_discount_codes&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;settings.DISCOUNT_CODES&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;instance_discount_monetary_components&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;settings.DISCOUNT_MONETARY_COMPONENT_DEFINITIONS&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;instance_tax_codes&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;settings.TAX_CODES&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;instance_tax_monetary_components&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;settings.TAX_MONETARY_COMPONENT_DEFINITIONS&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;instance_informational_codes&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;settings.INFORMATIONAL_MONETARY_CODES&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;flags&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;obj.get_facility_flags()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;patient_instance_identifier_configs&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;PatientIdentifierConfigCache.get_instance_config()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;patient_facility_identifier_configs&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;PatientIdentifierConfigCache.get_facility_config(obj.id)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Facility codes layer on top of instance-level catalogs. The read payload returns both the facility&amp;#039;s own &amp;lt;code&amp;gt;discount_*&amp;lt;/code&amp;gt; fields and the &amp;lt;code&amp;gt;instance_*&amp;lt;/code&amp;gt; settings-derived catalogs, while write-time validation stops a facility from redefining instance codes.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
== API integration ==&lt;br /&gt;
&lt;br /&gt;
Both writes are detail actions on the facility viewset and require update authorization on the facility.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Action&lt;br /&gt;
! Method&lt;br /&gt;
! Request spec&lt;br /&gt;
! Behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;set_monetary_config&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;POST&amp;lt;/code&amp;gt; (detail)&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityMonetaryCodeSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;model_validate&amp;lt;/code&amp;gt; with context &amp;lt;code&amp;gt;{is_update: True, object: &amp;amp;lt;config&amp;amp;gt;}&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt; onto the get-or-created config, set &amp;lt;code&amp;gt;updated_by&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt;. Returns the facility retrieve payload&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;set_invoice_expression&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;POST&amp;lt;/code&amp;gt; (detail)&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityInvoiceExpressionSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| Sets &amp;lt;code&amp;gt;invoice_number_expression&amp;lt;/code&amp;gt; on the get-or-created config, sets &amp;lt;code&amp;gt;updated_by&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt;. Returns the facility retrieve payload&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Invoice number expression ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;invoice_number_expression&amp;lt;/code&amp;gt; is a string template evaluated by &amp;lt;code&amp;gt;care.emr.utils.expression_evaluator.evaluate_expression&amp;lt;/code&amp;gt;. It can reference:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable&lt;br /&gt;
! Source&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;invoice_count&amp;lt;/code&amp;gt;&lt;br /&gt;
| count of &amp;lt;code&amp;gt;Invoice&amp;lt;/code&amp;gt; rows for the facility&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;current_year_yyyy&amp;lt;/code&amp;gt;&lt;br /&gt;
| four-digit current year&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;current_year_yy&amp;lt;/code&amp;gt;&lt;br /&gt;
| two-digit current year (&amp;lt;code&amp;gt;year % 100&amp;lt;/code&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;/empty expression evaluates to &amp;lt;code&amp;gt;&amp;amp;quot;&amp;amp;quot;&amp;lt;/code&amp;gt;, producing no number.&lt;br /&gt;
&lt;br /&gt;
== Methods &amp;amp;amp; save behaviour ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacilityMonetoryConfig&amp;lt;/code&amp;gt; caches derived data in the Django cache and rebuilds it on every write.&lt;br /&gt;
&lt;br /&gt;
=== Cache keys ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key&lt;br /&gt;
! Built by&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;facility:{facility_id}:monetory_component&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;get_monetory_component_cache_key(facility_id)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;facility:{facility_id}:discount_configuration&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;get_discount_configuration_cache_key(facility_id)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Class methods ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;get_monetory_config(facility_id)&amp;lt;/code&amp;gt; — returns the facility&amp;#039;s config, creating an empty one if none exists. This get-or-create entry point backs both write actions and the retrieve serializer.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_component_key(component)&amp;lt;/code&amp;gt; — derives a component&amp;#039;s lookup key as &amp;lt;code&amp;gt;code.system + &amp;amp;quot;/&amp;amp;quot; + code.code&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;calculate_monetory_components(components)&amp;lt;/code&amp;gt; — folds a component list into a dict keyed by &amp;lt;code&amp;gt;get_component_key&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_monetory_component(facility_id)&amp;lt;/code&amp;gt; — returns the cached component dict, computing it from &amp;lt;code&amp;gt;discount_monetary_components&amp;lt;/code&amp;gt; and caching it on a miss.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_discount_configuration(facility_id)&amp;lt;/code&amp;gt; — returns the cached &amp;lt;code&amp;gt;discount_configuration&amp;lt;/code&amp;gt; (default &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;), caching it on a miss.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt; side effects ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt; deletes both cache keys for the facility before calling &amp;lt;code&amp;gt;super().save()&amp;lt;/code&amp;gt;. The next call to &amp;lt;code&amp;gt;get_monetory_component()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;get_discount_configuration()&amp;lt;/code&amp;gt; recomputes from the persisted row, so the cache invalidates on write and rebuilds lazily on the next read.&lt;br /&gt;
&lt;br /&gt;
== API integration notes ==&lt;br /&gt;
&lt;br /&gt;
* One config exists per facility. Read or auto-create it through &amp;lt;code&amp;gt;get_monetory_config(facility_id)&amp;lt;/code&amp;gt; rather than querying the table directly — the &amp;lt;code&amp;gt;set_monetary_config&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;set_invoice_expression&amp;lt;/code&amp;gt; actions and &amp;lt;code&amp;gt;FacilityRetrieveSpec&amp;lt;/code&amp;gt; all route through this get-or-create.&lt;br /&gt;
* &amp;lt;code&amp;gt;discount_codes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;discount_monetary_components&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;discount_configuration&amp;lt;/code&amp;gt; are opaque &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt;s at the DB layer; their shape and validation come from &amp;lt;code&amp;gt;FacilityMonetaryCodeSpec&amp;lt;/code&amp;gt; and the nested &amp;lt;code&amp;gt;Coding&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;MonetaryComponentDefinition&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;DiscountConfiguration&amp;lt;/code&amp;gt; specs.&lt;br /&gt;
* Monetary components are keyed by a FHIR-style &amp;lt;code&amp;gt;code.system&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;code.code&amp;lt;/code&amp;gt; pair (&amp;lt;code&amp;gt;get_component_key&amp;lt;/code&amp;gt;); match on that derived key.&lt;br /&gt;
* &amp;lt;code&amp;gt;get_monetory_component()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;get_discount_configuration()&amp;lt;/code&amp;gt; results are cache-backed and platform-maintained. Don&amp;#039;t write to the cache keys directly — write the model and let &amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt; invalidate them.&lt;br /&gt;
&lt;br /&gt;
{{Related}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>