From 797b7c8de71debd940a1dc3ac3437514551a652d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 16:00:13 +0000 Subject: [PATCH] docs: add supplier concept, reference, and flows Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../concepts/access-governance/supplier.mdx | 54 ++++++++ .../flows/access-governance/_category_.json | 5 + .../access-governance/add-a-supplier.mdx | 59 +++++++++ .../access-governance/update-a-supplier.mdx | 68 +++++++++++ .../references/access-governance/supplier.mdx | 115 ++++++++++++++++++ .../concepts/access-governance/supplier.mdx | 54 ++++++++ .../flows/access-governance/_category_.json | 5 + .../access-governance/add-a-supplier.mdx | 59 +++++++++ .../access-governance/update-a-supplier.mdx | 68 +++++++++++ .../references/access-governance/supplier.mdx | 115 ++++++++++++++++++ versioned_sidebars/version-3.0-sidebars.json | 16 ++- versioned_sidebars/version-3.1-sidebars.json | 11 +- 12 files changed, 626 insertions(+), 3 deletions(-) create mode 100644 versioned_docs/version-3.0/concepts/access-governance/supplier.mdx create mode 100644 versioned_docs/version-3.0/flows/access-governance/_category_.json create mode 100644 versioned_docs/version-3.0/flows/access-governance/add-a-supplier.mdx create mode 100644 versioned_docs/version-3.0/flows/access-governance/update-a-supplier.mdx create mode 100644 versioned_docs/version-3.0/references/access-governance/supplier.mdx create mode 100644 versioned_docs/version-3.1/concepts/access-governance/supplier.mdx create mode 100644 versioned_docs/version-3.1/flows/access-governance/_category_.json create mode 100644 versioned_docs/version-3.1/flows/access-governance/add-a-supplier.mdx create mode 100644 versioned_docs/version-3.1/flows/access-governance/update-a-supplier.mdx create mode 100644 versioned_docs/version-3.1/references/access-governance/supplier.mdx diff --git a/versioned_docs/version-3.0/concepts/access-governance/supplier.mdx b/versioned_docs/version-3.0/concepts/access-governance/supplier.mdx new file mode 100644 index 0000000..1e09274 --- /dev/null +++ b/versioned_docs/version-3.0/concepts/access-governance/supplier.mdx @@ -0,0 +1,54 @@ +--- +sidebar_position: 5 +--- + +# Supplier + +## Definition + +A **[supplier](https://build.fhir.org/organization.html)** in Care is an [organization](../access-governance/organization.mdx) that supplies products to your facilities. Care models a supplier as an organization of the type **Product Supplier**. You record a supplier one time, then select it on a request order or a delivery order. The supplier keeps the vendor name out of free text, so every order points to the same record. + +A supplier is not a facility, and it is not a location. A facility is a place where you give care. A supplier is an external party that sends products to that place. + +## Key Attributes + +| Components | What it captures | +| --- | --- | +| Name | The name of the supplier. Care shows this name in the supplier list and on each order. | +| Description | Short free text about the supplier. Use it for the trade name or the product range. | +| Organization type | The type of the organization. For a supplier, the type is **Product Supplier**. | + +### Flat list + +Suppliers do not form a tree. Care shows them as one flat list under **Admin**, sorted by name, with a search box above the list. Governance organizations form a hierarchy, but a supplier stands alone. + +### Visibility + +Every user of the deployment can see the supplier list. Care treats supplier records as shared reference data, in the same way as governance organizations. Only a user with organization create permission can add a supplier, and only a user with organization management permission can change one. + +### Use in the supply chain + +You select a supplier in two places: + +- On a [supply request](../supply/supply-request.mdx) order, to say which supplier you order the products from. +- On a [supply delivery](../supply/supply-delivery.mdx) order, to say which supplier sent the products. + +The supplier is optional on both. Care accepts only an organization of the type **Product Supplier** in these fields, and rejects any other organization. + +## Permissions + +Care gates suppliers with the organization permissions, because a supplier is an organization. + +| Permission | Description | System Roles | +| --- | --- | --- | +| `can_view_organization` | See suppliers in the supplier list and in the supplier selector | Facility Admin, Admin, Staff, Doctor, Administrator, Nurse, Volunteer, Pharmacist, Admin (role org), Manager (role org), Member (role org) | +| `can_create_organization` | Add a supplier | Admin | +| `can_manage_organization` | Change the name and the description of a supplier, and delete it | Admin, Admin (role org) | + +Care grants a role to a user inside an organization, and the role applies to every organization below it in the tree. + +## Related + +- Flow: [Add a supplier](../../flows/access-governance/add-a-supplier.mdx) · [Update a supplier](../../flows/access-governance/update-a-supplier.mdx) +- Concept: [Organization](../access-governance/organization.mdx) · [Supply request](../supply/supply-request.mdx) · [Supply delivery](../supply/supply-delivery.mdx) +- Reference: [Organization (technical)](../../references/access-governance/organization.mdx) diff --git a/versioned_docs/version-3.0/flows/access-governance/_category_.json b/versioned_docs/version-3.0/flows/access-governance/_category_.json new file mode 100644 index 0000000..84656e5 --- /dev/null +++ b/versioned_docs/version-3.0/flows/access-governance/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Access & Governance", + "position": 2, + "key": "access-governance-flows" +} diff --git a/versioned_docs/version-3.0/flows/access-governance/add-a-supplier.mdx b/versioned_docs/version-3.0/flows/access-governance/add-a-supplier.mdx new file mode 100644 index 0000000..7b0c474 --- /dev/null +++ b/versioned_docs/version-3.0/flows/access-governance/add-a-supplier.mdx @@ -0,0 +1,59 @@ +--- +sidebar_position: 1 +--- + +# How to add a supplier + +## Overview + +This flow describes how to add a [supplier](../../concepts/access-governance/supplier.mdx) in Care. After you add the supplier, you can select it on a request order and on a delivery order. + +## Pre-requisites + +- You have access to the **Admin** area of Care. +- The supplier is not in the supplier list already. Two suppliers cannot have the same name. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can View Organizations | See the supplier list. | +| Can Create Organizations | Add a supplier. | + +## Steps + +### 1. Open the supplier list + +Go to **Admin**. Select **Organizations** in the side menu, then select **Suppliers**. Care shows the list of suppliers with the description "Manage your product suppliers and vendor organizations". + +### 2. Open the supplier form + +Select **Add Organization**. Care opens the **Create Department/Team** panel. + +### 3. Enter the supplier details + +| Components | What it captures | +| --- | --- | +| Name | The name of the supplier. This field is mandatory. | +| Description | Short free text about the supplier. This field is optional. | + +### 4. Save the supplier + +Select **Create Organization**. Care closes the panel and shows the message "Organization created successfully". + +## Expected Outcome + +- Care adds the supplier to the supplier list. +- The supplier is available in the supplier selector on a request order and on a delivery order. + +## Related + +Concepts: + +- [Supplier](../../concepts/access-governance/supplier.mdx) +- [Organization](../../concepts/access-governance/organization.mdx) + +Flows: + +- [How to update a supplier](./update-a-supplier.mdx) diff --git a/versioned_docs/version-3.0/flows/access-governance/update-a-supplier.mdx b/versioned_docs/version-3.0/flows/access-governance/update-a-supplier.mdx new file mode 100644 index 0000000..5b12ae5 --- /dev/null +++ b/versioned_docs/version-3.0/flows/access-governance/update-a-supplier.mdx @@ -0,0 +1,68 @@ +--- +sidebar_position: 2 +--- + +# How to update a supplier + +## Overview + +This flow describes how to change the name or the description of a [supplier](../../concepts/access-governance/supplier.mdx) in Care. + +## Pre-requisites + +- The supplier is in the supplier list. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can View Organizations | See the supplier list. | +| Can Manage Organizations | Change the name and the description of a supplier. | + +## Steps + +### 1. Open the supplier list + +Go to **Admin**. Select **Organizations** in the side menu, then select **Suppliers**. + +### 2. Select the supplier + +Select the supplier in the list on the left. To find a supplier in a long list, enter part of the name in the search box above the list. Care shows the name and the description of the supplier on the right. + +:::note +On a small screen, Care shows a selector instead of the list. Use **Select Organization** to choose the supplier. +::: + +### 3. Open the supplier form + +Select **Edit**. Care opens the **Edit Department/Team** panel with the current values. + +### 4. Change the supplier details + +| Components | What it captures | +| --- | --- | +| Name | The name of the supplier. This field is mandatory. | +| Description | Short free text about the supplier. This field is optional. | + +Care keeps the save button inactive until you change a value. + +### 5. Save the supplier + +Select **Update Organization**. Care closes the panel and shows the message "Organizations updated successfully". + +## Expected Outcome + +- Care shows the new name and the new description of the supplier. +- Every order that points to the supplier shows the new name. + +## Related + +Concepts: + +- [Supplier](../../concepts/access-governance/supplier.mdx) +- [Organization](../../concepts/access-governance/organization.mdx) + +Flows: + +- [How to add a supplier](./add-a-supplier.mdx) diff --git a/versioned_docs/version-3.0/references/access-governance/supplier.mdx b/versioned_docs/version-3.0/references/access-governance/supplier.mdx new file mode 100644 index 0000000..d547d8a --- /dev/null +++ b/versioned_docs/version-3.0/references/access-governance/supplier.mdx @@ -0,0 +1,115 @@ +--- +sidebar_position: 6 +--- + +# Supplier + +Technical reference for the supplier organization in Care EMR. A supplier is not a separate Django model. Care stores it as an `Organization` row with `org_type = "product_supplier"`. See the concept [Supplier](../../concepts/access-governance/supplier.mdx). + +**Source:** +[`care/emr/models/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/organization.py) · +[`resources/organization/spec.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/organization/spec.py) · +[`api/viewsets/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/api/viewsets/organization.py) · +[`resources/inventory/supply_request/request_order.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/inventory/supply_request/request_order.py) · +[`resources/inventory/supply_delivery/delivery_order.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/inventory/supply_delivery/delivery_order.py) + +The storage layer is the `Organization` table. The `product_supplier` value of `org_type` is what makes a row a supplier, and the resource specs of the supply chain enforce that value. Read [Organization](./organization.mdx) for the full field list, the tree caches, and the save behaviour. + +## Models + +| Model | Purpose | +| --- | --- | +| `Organization` | Instance-wide organization. A row with `org_type = "product_supplier"` is a supplier | +| `OrganizationUser` | Membership row linking a `User` to an `Organization` with a `RoleModel` | + +`Organization` extends `OrganizationCommonBase`, which extends [`EMRBaseModel`](../foundation/base-model.mdx). + +## Discriminating field + +| Field | Type | Required | Value | Notes | +| --- | --- | --- | --- | --- | +| `org_type` | `CharField(255)` | yes | `product_supplier` | Free text in the database. Writes bind to `OrganizationTypeChoices` in `resources/organization/spec.py` | + +### `OrganizationTypeChoices` values + +| Value | Meaning | +| --- | --- | +| `team` | Working grouping of people | +| `govt` | Governance or governmental unit | +| `role` | User group, flat and managed by superadmins | +| `product_supplier` | Supplier of products for the supply chain | + +The frontend enum `OrgType` in `src/types/organization/organization.ts` adds an `other` member that the backend enum does not define. + +## Fields used for a supplier + +A supplier uses the common organization columns. The columns below are the ones the supplier screens write. + +| Field | Type | Required | Default | Notes | +| --- | --- | --- | --- | --- | +| `name` | `CharField(255)` | yes | — | Feeds `validate_uniqueness`. Names must be unique among siblings under the same root | +| `description` | `TextField` | no | `null` | The specs default it to `""` | +| `org_type` | `CharField(255)` | yes | — | `product_supplier` | +| `parent` | `FK → self` | no | `null` | The supplier screens create suppliers without a parent, so a supplier is a root organization | +| `active` | `BooleanField` | no | `True` | | +| `metadata` | `JSONField` | no | `{}` | Open key-value bag. The supplier form does not write it | + +## Resource specs (API schema) + +| Spec | Role | +| --- | --- | +| `OrganizationWriteSpec` | write · create. Adds `parent: UUID4 \| None` and validates that the parent exists | +| `OrganizationUpdateSpec` | write · update. Same base fields, no `parent` | +| `OrganizationReadSpec` | read · list. Adds `level_cache`, `system_generated`, `has_children`, and the nested `parent` JSON | +| `OrganizationRetrieveSpec` | read · detail | + +All four extend `OrganizationBaseSpec`, which carries `id`, `active`, `org_type`, `name`, `description`, and `metadata`. + +## Authorization + +`OrganizationViewSet` in `care/emr/api/viewsets/organization.py` gates every write. + +| Action | Check | Permission slug | +| --- | --- | --- | +| create | `authorize_create` → `can_create_organization_obj` | `can_create_organization` | +| update | `authorize_update` → `can_manage_organization_obj` | `can_manage_organization` | +| destroy | `authorize_destroy` → `can_manage_organization_obj` | `can_manage_organization` | +| list, retrieve | `get_accessible_organizations` | `can_view_organization` | + +Two behaviours are specific to the `product_supplier` type: + +- `authorize_create` and `authorize_update` block the `govt` and `role` types for a non-superuser, but not `product_supplier`. A user with organization create permission on the parent can therefore create a supplier. A root supplier still needs a superuser, because `authorize_create` rejects a create with no parent for every other user. +- `get_accessible_organizations` in `care/security/authorization/organization.py` adds `org_type__in=[govt, product_supplier]` to the accessible queryset. Every authenticated user can therefore list every supplier, without a membership. + +Permission definitions and their role lists are in [`care/security/permissions/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/permissions/organization.py). + +## Supply chain integration + +Two order models hold a nullable foreign key to `Organization`. + +```text +RequestOrder.supplier → Organization (null=True, blank=True, CASCADE) +DeliveryOrder.supplier → Organization (null=True, blank=True, CASCADE) +``` + +The write specs enforce the type, in two different ways: + +| Spec | File | Enforcement | +| --- | --- | --- | +| `SupplyRequestOrderWriteSpec` | `resources/inventory/supply_request/request_order.py` | Fetches the organization by `external_id`, then raises `ValidationError` when `org_type != "product_supplier"` | +| `SupplyDeliveryOrderWriteSpec` | `resources/inventory/supply_delivery/delivery_order.py` | Filters on `external_id` and `org_type="product_supplier"`, so a wrong type returns `404` | + +Both read specs serialize the supplier with `OrganizationReadSpec`. + +## API integration notes + +- Suppliers use the organization endpoints. Filter with `org_type=product_supplier` on `GET /api/v1/organization/`, and add `name` for a case-insensitive substring search. +- The frontend lists suppliers with `parent=""` and `limit=100`, so it shows root suppliers only. +- `level_cache`, `parent_cache`, `root_org`, `has_children`, and `cached_parent_json` are platform-maintained. Do not write them. +- OTP-authenticated patient sessions cannot read suppliers. `get_queryset` limits that mode to the `govt` type. + +## Related + +- Concept: [Supplier](../../concepts/access-governance/supplier.mdx) · [Organization](../../concepts/access-governance/organization.mdx) +- Reference: [Organization](./organization.mdx) · [Supply request](../supply/supply-request.mdx) · [Supply delivery](../supply/supply-delivery.mdx) +- Source: [`care/emr/models/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/organization.py) diff --git a/versioned_docs/version-3.1/concepts/access-governance/supplier.mdx b/versioned_docs/version-3.1/concepts/access-governance/supplier.mdx new file mode 100644 index 0000000..1e09274 --- /dev/null +++ b/versioned_docs/version-3.1/concepts/access-governance/supplier.mdx @@ -0,0 +1,54 @@ +--- +sidebar_position: 5 +--- + +# Supplier + +## Definition + +A **[supplier](https://build.fhir.org/organization.html)** in Care is an [organization](../access-governance/organization.mdx) that supplies products to your facilities. Care models a supplier as an organization of the type **Product Supplier**. You record a supplier one time, then select it on a request order or a delivery order. The supplier keeps the vendor name out of free text, so every order points to the same record. + +A supplier is not a facility, and it is not a location. A facility is a place where you give care. A supplier is an external party that sends products to that place. + +## Key Attributes + +| Components | What it captures | +| --- | --- | +| Name | The name of the supplier. Care shows this name in the supplier list and on each order. | +| Description | Short free text about the supplier. Use it for the trade name or the product range. | +| Organization type | The type of the organization. For a supplier, the type is **Product Supplier**. | + +### Flat list + +Suppliers do not form a tree. Care shows them as one flat list under **Admin**, sorted by name, with a search box above the list. Governance organizations form a hierarchy, but a supplier stands alone. + +### Visibility + +Every user of the deployment can see the supplier list. Care treats supplier records as shared reference data, in the same way as governance organizations. Only a user with organization create permission can add a supplier, and only a user with organization management permission can change one. + +### Use in the supply chain + +You select a supplier in two places: + +- On a [supply request](../supply/supply-request.mdx) order, to say which supplier you order the products from. +- On a [supply delivery](../supply/supply-delivery.mdx) order, to say which supplier sent the products. + +The supplier is optional on both. Care accepts only an organization of the type **Product Supplier** in these fields, and rejects any other organization. + +## Permissions + +Care gates suppliers with the organization permissions, because a supplier is an organization. + +| Permission | Description | System Roles | +| --- | --- | --- | +| `can_view_organization` | See suppliers in the supplier list and in the supplier selector | Facility Admin, Admin, Staff, Doctor, Administrator, Nurse, Volunteer, Pharmacist, Admin (role org), Manager (role org), Member (role org) | +| `can_create_organization` | Add a supplier | Admin | +| `can_manage_organization` | Change the name and the description of a supplier, and delete it | Admin, Admin (role org) | + +Care grants a role to a user inside an organization, and the role applies to every organization below it in the tree. + +## Related + +- Flow: [Add a supplier](../../flows/access-governance/add-a-supplier.mdx) · [Update a supplier](../../flows/access-governance/update-a-supplier.mdx) +- Concept: [Organization](../access-governance/organization.mdx) · [Supply request](../supply/supply-request.mdx) · [Supply delivery](../supply/supply-delivery.mdx) +- Reference: [Organization (technical)](../../references/access-governance/organization.mdx) diff --git a/versioned_docs/version-3.1/flows/access-governance/_category_.json b/versioned_docs/version-3.1/flows/access-governance/_category_.json new file mode 100644 index 0000000..84656e5 --- /dev/null +++ b/versioned_docs/version-3.1/flows/access-governance/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Access & Governance", + "position": 2, + "key": "access-governance-flows" +} diff --git a/versioned_docs/version-3.1/flows/access-governance/add-a-supplier.mdx b/versioned_docs/version-3.1/flows/access-governance/add-a-supplier.mdx new file mode 100644 index 0000000..7b0c474 --- /dev/null +++ b/versioned_docs/version-3.1/flows/access-governance/add-a-supplier.mdx @@ -0,0 +1,59 @@ +--- +sidebar_position: 1 +--- + +# How to add a supplier + +## Overview + +This flow describes how to add a [supplier](../../concepts/access-governance/supplier.mdx) in Care. After you add the supplier, you can select it on a request order and on a delivery order. + +## Pre-requisites + +- You have access to the **Admin** area of Care. +- The supplier is not in the supplier list already. Two suppliers cannot have the same name. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can View Organizations | See the supplier list. | +| Can Create Organizations | Add a supplier. | + +## Steps + +### 1. Open the supplier list + +Go to **Admin**. Select **Organizations** in the side menu, then select **Suppliers**. Care shows the list of suppliers with the description "Manage your product suppliers and vendor organizations". + +### 2. Open the supplier form + +Select **Add Organization**. Care opens the **Create Department/Team** panel. + +### 3. Enter the supplier details + +| Components | What it captures | +| --- | --- | +| Name | The name of the supplier. This field is mandatory. | +| Description | Short free text about the supplier. This field is optional. | + +### 4. Save the supplier + +Select **Create Organization**. Care closes the panel and shows the message "Organization created successfully". + +## Expected Outcome + +- Care adds the supplier to the supplier list. +- The supplier is available in the supplier selector on a request order and on a delivery order. + +## Related + +Concepts: + +- [Supplier](../../concepts/access-governance/supplier.mdx) +- [Organization](../../concepts/access-governance/organization.mdx) + +Flows: + +- [How to update a supplier](./update-a-supplier.mdx) diff --git a/versioned_docs/version-3.1/flows/access-governance/update-a-supplier.mdx b/versioned_docs/version-3.1/flows/access-governance/update-a-supplier.mdx new file mode 100644 index 0000000..5b12ae5 --- /dev/null +++ b/versioned_docs/version-3.1/flows/access-governance/update-a-supplier.mdx @@ -0,0 +1,68 @@ +--- +sidebar_position: 2 +--- + +# How to update a supplier + +## Overview + +This flow describes how to change the name or the description of a [supplier](../../concepts/access-governance/supplier.mdx) in Care. + +## Pre-requisites + +- The supplier is in the supplier list. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can View Organizations | See the supplier list. | +| Can Manage Organizations | Change the name and the description of a supplier. | + +## Steps + +### 1. Open the supplier list + +Go to **Admin**. Select **Organizations** in the side menu, then select **Suppliers**. + +### 2. Select the supplier + +Select the supplier in the list on the left. To find a supplier in a long list, enter part of the name in the search box above the list. Care shows the name and the description of the supplier on the right. + +:::note +On a small screen, Care shows a selector instead of the list. Use **Select Organization** to choose the supplier. +::: + +### 3. Open the supplier form + +Select **Edit**. Care opens the **Edit Department/Team** panel with the current values. + +### 4. Change the supplier details + +| Components | What it captures | +| --- | --- | +| Name | The name of the supplier. This field is mandatory. | +| Description | Short free text about the supplier. This field is optional. | + +Care keeps the save button inactive until you change a value. + +### 5. Save the supplier + +Select **Update Organization**. Care closes the panel and shows the message "Organizations updated successfully". + +## Expected Outcome + +- Care shows the new name and the new description of the supplier. +- Every order that points to the supplier shows the new name. + +## Related + +Concepts: + +- [Supplier](../../concepts/access-governance/supplier.mdx) +- [Organization](../../concepts/access-governance/organization.mdx) + +Flows: + +- [How to add a supplier](./add-a-supplier.mdx) diff --git a/versioned_docs/version-3.1/references/access-governance/supplier.mdx b/versioned_docs/version-3.1/references/access-governance/supplier.mdx new file mode 100644 index 0000000..d547d8a --- /dev/null +++ b/versioned_docs/version-3.1/references/access-governance/supplier.mdx @@ -0,0 +1,115 @@ +--- +sidebar_position: 6 +--- + +# Supplier + +Technical reference for the supplier organization in Care EMR. A supplier is not a separate Django model. Care stores it as an `Organization` row with `org_type = "product_supplier"`. See the concept [Supplier](../../concepts/access-governance/supplier.mdx). + +**Source:** +[`care/emr/models/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/organization.py) · +[`resources/organization/spec.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/organization/spec.py) · +[`api/viewsets/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/api/viewsets/organization.py) · +[`resources/inventory/supply_request/request_order.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/inventory/supply_request/request_order.py) · +[`resources/inventory/supply_delivery/delivery_order.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/inventory/supply_delivery/delivery_order.py) + +The storage layer is the `Organization` table. The `product_supplier` value of `org_type` is what makes a row a supplier, and the resource specs of the supply chain enforce that value. Read [Organization](./organization.mdx) for the full field list, the tree caches, and the save behaviour. + +## Models + +| Model | Purpose | +| --- | --- | +| `Organization` | Instance-wide organization. A row with `org_type = "product_supplier"` is a supplier | +| `OrganizationUser` | Membership row linking a `User` to an `Organization` with a `RoleModel` | + +`Organization` extends `OrganizationCommonBase`, which extends [`EMRBaseModel`](../foundation/base-model.mdx). + +## Discriminating field + +| Field | Type | Required | Value | Notes | +| --- | --- | --- | --- | --- | +| `org_type` | `CharField(255)` | yes | `product_supplier` | Free text in the database. Writes bind to `OrganizationTypeChoices` in `resources/organization/spec.py` | + +### `OrganizationTypeChoices` values + +| Value | Meaning | +| --- | --- | +| `team` | Working grouping of people | +| `govt` | Governance or governmental unit | +| `role` | User group, flat and managed by superadmins | +| `product_supplier` | Supplier of products for the supply chain | + +The frontend enum `OrgType` in `src/types/organization/organization.ts` adds an `other` member that the backend enum does not define. + +## Fields used for a supplier + +A supplier uses the common organization columns. The columns below are the ones the supplier screens write. + +| Field | Type | Required | Default | Notes | +| --- | --- | --- | --- | --- | +| `name` | `CharField(255)` | yes | — | Feeds `validate_uniqueness`. Names must be unique among siblings under the same root | +| `description` | `TextField` | no | `null` | The specs default it to `""` | +| `org_type` | `CharField(255)` | yes | — | `product_supplier` | +| `parent` | `FK → self` | no | `null` | The supplier screens create suppliers without a parent, so a supplier is a root organization | +| `active` | `BooleanField` | no | `True` | | +| `metadata` | `JSONField` | no | `{}` | Open key-value bag. The supplier form does not write it | + +## Resource specs (API schema) + +| Spec | Role | +| --- | --- | +| `OrganizationWriteSpec` | write · create. Adds `parent: UUID4 \| None` and validates that the parent exists | +| `OrganizationUpdateSpec` | write · update. Same base fields, no `parent` | +| `OrganizationReadSpec` | read · list. Adds `level_cache`, `system_generated`, `has_children`, and the nested `parent` JSON | +| `OrganizationRetrieveSpec` | read · detail | + +All four extend `OrganizationBaseSpec`, which carries `id`, `active`, `org_type`, `name`, `description`, and `metadata`. + +## Authorization + +`OrganizationViewSet` in `care/emr/api/viewsets/organization.py` gates every write. + +| Action | Check | Permission slug | +| --- | --- | --- | +| create | `authorize_create` → `can_create_organization_obj` | `can_create_organization` | +| update | `authorize_update` → `can_manage_organization_obj` | `can_manage_organization` | +| destroy | `authorize_destroy` → `can_manage_organization_obj` | `can_manage_organization` | +| list, retrieve | `get_accessible_organizations` | `can_view_organization` | + +Two behaviours are specific to the `product_supplier` type: + +- `authorize_create` and `authorize_update` block the `govt` and `role` types for a non-superuser, but not `product_supplier`. A user with organization create permission on the parent can therefore create a supplier. A root supplier still needs a superuser, because `authorize_create` rejects a create with no parent for every other user. +- `get_accessible_organizations` in `care/security/authorization/organization.py` adds `org_type__in=[govt, product_supplier]` to the accessible queryset. Every authenticated user can therefore list every supplier, without a membership. + +Permission definitions and their role lists are in [`care/security/permissions/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/permissions/organization.py). + +## Supply chain integration + +Two order models hold a nullable foreign key to `Organization`. + +```text +RequestOrder.supplier → Organization (null=True, blank=True, CASCADE) +DeliveryOrder.supplier → Organization (null=True, blank=True, CASCADE) +``` + +The write specs enforce the type, in two different ways: + +| Spec | File | Enforcement | +| --- | --- | --- | +| `SupplyRequestOrderWriteSpec` | `resources/inventory/supply_request/request_order.py` | Fetches the organization by `external_id`, then raises `ValidationError` when `org_type != "product_supplier"` | +| `SupplyDeliveryOrderWriteSpec` | `resources/inventory/supply_delivery/delivery_order.py` | Filters on `external_id` and `org_type="product_supplier"`, so a wrong type returns `404` | + +Both read specs serialize the supplier with `OrganizationReadSpec`. + +## API integration notes + +- Suppliers use the organization endpoints. Filter with `org_type=product_supplier` on `GET /api/v1/organization/`, and add `name` for a case-insensitive substring search. +- The frontend lists suppliers with `parent=""` and `limit=100`, so it shows root suppliers only. +- `level_cache`, `parent_cache`, `root_org`, `has_children`, and `cached_parent_json` are platform-maintained. Do not write them. +- OTP-authenticated patient sessions cannot read suppliers. `get_queryset` limits that mode to the `govt` type. + +## Related + +- Concept: [Supplier](../../concepts/access-governance/supplier.mdx) · [Organization](../../concepts/access-governance/organization.mdx) +- Reference: [Organization](./organization.mdx) · [Supply request](../supply/supply-request.mdx) · [Supply delivery](../supply/supply-delivery.mdx) +- Source: [`care/emr/models/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/organization.py) diff --git a/versioned_sidebars/version-3.0-sidebars.json b/versioned_sidebars/version-3.0-sidebars.json index d253abe..9ad132f 100644 --- a/versioned_sidebars/version-3.0-sidebars.json +++ b/versioned_sidebars/version-3.0-sidebars.json @@ -21,7 +21,19 @@ "type": "category", "label": "Clinical", "key": "clinical-flows", - "items": ["flows/clinical/create-patient", "flows/clinical/manage-encounter-care-team"] + "items": [ + "flows/clinical/create-patient", + "flows/clinical/manage-encounter-care-team" + ] + }, + { + "type": "category", + "label": "Access & Governance", + "key": "access-governance-flows", + "items": [ + "flows/access-governance/add-a-supplier", + "flows/access-governance/update-a-supplier" + ] } ] }, @@ -37,4 +49,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/versioned_sidebars/version-3.1-sidebars.json b/versioned_sidebars/version-3.1-sidebars.json index ffc66fb..cd054b7 100644 --- a/versioned_sidebars/version-3.1-sidebars.json +++ b/versioned_sidebars/version-3.1-sidebars.json @@ -40,6 +40,15 @@ }, "flows/clinical/manage-encounter-care-team" ] + }, + { + "type": "category", + "label": "Access & Governance", + "key": "access-governance-flows", + "items": [ + "flows/access-governance/add-a-supplier", + "flows/access-governance/update-a-supplier" + ] } ] }, @@ -55,4 +64,4 @@ ] } ] -} +} \ No newline at end of file