<?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%2FInventory_Item</id>
	<title>References/Inventory Item - 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%2FInventory_Item"/>
	<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Inventory_Item&amp;action=history"/>
	<updated>2026-07-06T05:20:17Z</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/Inventory_Item&amp;diff=453&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/Inventory_Item&amp;diff=453&amp;oldid=prev"/>
		<updated>2026-07-06T04:17:33Z</updated>

		<summary type="html">&lt;p&gt;Automated edit (via update-page on MediaWiki MCP Server)&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 09:47, 6 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 182:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 182:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Read responses inline the full &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt; (with &amp;lt;code&amp;gt;product_knowledge&amp;lt;/code&amp;gt;) and &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; objects, not just their ids.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Read responses inline the full &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt; (with &amp;lt;code&amp;gt;product_knowledge&amp;lt;/code&amp;gt;) and &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; objects, not just their ids.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt; are &amp;lt;code&amp;gt;PROTECT&amp;lt;/code&amp;gt; foreign keys, so referenced products and locations can&#039;t be hard-deleted while stock rows exist.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt; are &amp;lt;code&amp;gt;PROTECT&amp;lt;/code&amp;gt; foreign keys, so referenced products and locations can&#039;t be hard-deleted while stock rows exist.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-deleted&quot;&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-deleted&quot;&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{Navbox supply}}&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{Related}}&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{Related}}&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://ohcnwiki.tellmey.fyi/index.php?title=References/Inventory_Item&amp;diff=177&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/Inventory_Item&amp;diff=177&amp;oldid=prev"/>
		<updated>2026-07-04T22:45:46Z</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=supply&lt;br /&gt;
|title=Inventory Item&lt;br /&gt;
|order=3&lt;br /&gt;
|introduced=3.0&lt;br /&gt;
|model=InventoryItem&lt;br /&gt;
|reference=References/Base models &amp;amp;amp; conventions&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;InventoryItem&amp;lt;/code&amp;gt; records how much of one [[References/Product|&amp;lt;code&amp;gt;Product&amp;lt;/code&amp;gt;]] is on hand at one [[References/Location|facility location]]. Deliveries move product in, dispenses move it out, and the server recomputes the balance into &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt;. You never create these rows — the server does, and the only field a client can write is &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, such as marking a line &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt; when stock is damaged or pulled from circulation.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Source:&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/inventory_item.py &amp;lt;code&amp;gt;care/emr/models/inventory_item.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/inventory/inventory_item/spec.py &amp;lt;code&amp;gt;care/emr/resources/inventory/inventory_item/spec.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* Helpers: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/inventory/inventory_item/create_inventory_item.py &amp;lt;code&amp;gt;create_inventory_item.py&amp;lt;/code&amp;gt;], [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/inventory/inventory_item/sync_inventory_item.py &amp;lt;code&amp;gt;sync_inventory_item.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
The Django model is storage. The Pydantic resource specs (&amp;lt;code&amp;gt;care/emr/resources/inventory/inventory_item/&amp;lt;/code&amp;gt;) define the &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; enum and the read schema, inlining the &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; objects that the model holds only as foreign keys.&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;InventoryItem&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stock of one product at one location, with its current net quantity&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;InventoryItem&amp;lt;/code&amp;gt; extends &amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt;, the shared Care EMR base providing &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, audit fields, and soft-delete semantics. See [[References/Base models &amp;amp;amp; conventions|Base model]].&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;code&amp;gt;InventoryItem&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=InventoryItem|section=InventoryItem fields|name=location|type=FK → FacilityLocation|notes=yes}}&lt;br /&gt;
{{Field|model=InventoryItem|section=InventoryItem fields|name=product|type=FK → Product|notes=yes}}&lt;br /&gt;
{{Field|model=InventoryItem|section=InventoryItem fields|name=status|type=CharField(255)|notes=yes}}&lt;br /&gt;
{{Field|model=InventoryItem|section=InventoryItem fields|name=net_content|type=DecimalField|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;(location, product)&amp;lt;/code&amp;gt; pair is unique — one inventory item per product per location — enforced in &amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt; (see [[#methods--save-behaviour|Methods &amp;amp;amp; save behaviour]]).&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;InventoryItemStatusOptions&amp;lt;/code&amp;gt; values ===&lt;br /&gt;
&lt;br /&gt;
Defined in [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/inventory/inventory_item/spec.py &amp;lt;code&amp;gt;spec.py&amp;lt;/code&amp;gt;]. The spec accepts only these three values; the model field itself stays an open &amp;lt;code&amp;gt;CharField&amp;lt;/code&amp;gt;:&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;active&amp;lt;/code&amp;gt;&lt;br /&gt;
| Live and dispensable. Set when the server auto-creates a row.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;&lt;br /&gt;
| No longer dispensed — damaged stock, or another hold.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entered_in_error&amp;lt;/code&amp;gt;&lt;br /&gt;
| Record created in error.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Related models ==&lt;br /&gt;
&lt;br /&gt;
Two foreign keys anchor the row; two transactional sources set its quantity:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;location → FK FacilityLocation (PROTECT)&lt;br /&gt;
product  → FK Product (PROTECT)&lt;br /&gt;
&lt;br /&gt;
drives net_content (read in sync_inventory_item):&lt;br /&gt;
  SupplyDelivery       (incoming completed, outgoing in-progress/completed)&lt;br /&gt;
  MedicationDispense   (dispensed-out, excluding cancelled statuses)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Both foreign keys are &amp;lt;code&amp;gt;on_delete=PROTECT&amp;lt;/code&amp;gt;: a location or product can&amp;#039;t be hard-deleted while an inventory row references it. The records that move &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt; live in [[References/Supply Delivery]] and [[References/Medication Dispense]].&lt;br /&gt;
&lt;br /&gt;
== Resource specs (API schema) ==&lt;br /&gt;
&lt;br /&gt;
All specs extend &amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;care/emr/resources/base.py&amp;lt;/code&amp;gt;), which supplies &amp;lt;code&amp;gt;serialize&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt; and the &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt; hook that inlines the nested &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; objects.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Spec class&lt;br /&gt;
! Role&lt;br /&gt;
! Fields exposed&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;BaseInventoryItemSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| shared&lt;br /&gt;
| &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;__model__ = InventoryItem&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;__exclude__ = []&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; typed as &amp;lt;code&amp;gt;InventoryItemStatusOptions&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;InventoryItemWriteSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write&lt;br /&gt;
| &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;&lt;br /&gt;
| Inherits &amp;lt;code&amp;gt;BaseInventoryItemSpec&amp;lt;/code&amp;gt; unchanged. Only &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; is client-writable; &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt; are server-maintained.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;InventoryItemReadSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · list&lt;br /&gt;
| &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt;&lt;br /&gt;
| See serialization below.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;InventoryItemRetrieveSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · detail&lt;br /&gt;
| same as &amp;lt;code&amp;gt;InventoryItemReadSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| A &amp;lt;code&amp;gt;pass&amp;lt;/code&amp;gt; subclass — identical shape to the list spec.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Read serialization (&amp;lt;code&amp;gt;InventoryItemReadSpec.perform_extra_serialization&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Serialized shape&lt;br /&gt;
! Source&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;UUID4&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;obj.external_id&amp;lt;/code&amp;gt; — the public id, not the internal pk.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Decimal&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;max_digits=20&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;decimal_places=0&amp;lt;/code&amp;gt; on the read field)&lt;br /&gt;
| model &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt;&lt;br /&gt;
| nested &amp;lt;code&amp;gt;dict&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;ProductReadSpec.serialize(obj.product).to_json()&amp;lt;/code&amp;gt; — carries nested &amp;lt;code&amp;gt;product_knowledge&amp;lt;/code&amp;gt; and optional &amp;lt;code&amp;gt;charge_item_definition&amp;lt;/code&amp;gt;. See [[References/Product]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt;&lt;br /&gt;
| nested &amp;lt;code&amp;gt;dict&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityLocationListSpec.serialize(obj.location).to_json()&amp;lt;/code&amp;gt; — carries &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mode&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;has_children&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;system_availability_status&amp;lt;/code&amp;gt;, and optional &amp;lt;code&amp;gt;current_encounter&amp;lt;/code&amp;gt;. See [[References/Location]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; (typed &amp;lt;code&amp;gt;InventoryItemStatusOptions&amp;lt;/code&amp;gt;) carries through from &amp;lt;code&amp;gt;BaseInventoryItemSpec&amp;lt;/code&amp;gt;. There is no &amp;lt;code&amp;gt;CreateSpec&amp;lt;/code&amp;gt;; rows are never created through a client write path.&lt;br /&gt;
&lt;br /&gt;
== Methods &amp;amp;amp; save behaviour ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
On creation only (when &amp;lt;code&amp;gt;self.id&amp;lt;/code&amp;gt; is unset), &amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt; enforces the &amp;lt;code&amp;gt;(location, product)&amp;lt;/code&amp;gt; uniqueness:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;if creating and InventoryItem with same (location, product) exists:&lt;br /&gt;
    raise ValueError(&amp;quot;Inventory item already exists&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* The check runs only for new rows; updates to an existing item skip it.&lt;br /&gt;
* A violation raises a plain &amp;lt;code&amp;gt;ValueError&amp;lt;/code&amp;gt;, not a database &amp;lt;code&amp;gt;IntegrityError&amp;lt;/code&amp;gt;, so callers creating items through the ORM must handle it.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;create_inventory_item(product, location)&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Helper in [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/inventory/inventory_item/create_inventory_item.py &amp;lt;code&amp;gt;create_inventory_item.py&amp;lt;/code&amp;gt;]. Idempotent get-or-create:&lt;br /&gt;
&lt;br /&gt;
* Returns the existing &amp;lt;code&amp;gt;(product, location)&amp;lt;/code&amp;gt; row if one exists.&lt;br /&gt;
* Otherwise creates one with &amp;lt;code&amp;gt;status=active&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net_content=0&amp;lt;/code&amp;gt;, and saves it.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;sync_inventory_item()&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Helper in [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/inventory/inventory_item/sync_inventory_item.py &amp;lt;code&amp;gt;sync_inventory_item.py&amp;lt;/code&amp;gt;], the source of truth for &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt;. Holding &amp;lt;code&amp;gt;InventoryLock(product, location)&amp;lt;/code&amp;gt;, it recomputes the balance from the transactional records and writes it back:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;net_content =&lt;br /&gt;
    Σ incoming completed deliveries  (SupplyDelivery.status == completed,&lt;br /&gt;
                                      order.destination == location,&lt;br /&gt;
                                      supplied_inventory_item.product == product)&lt;br /&gt;
  - Σ outgoing in-progress + completed deliveries&lt;br /&gt;
                                     (SupplyDelivery.order.origin is not null,&lt;br /&gt;
                                      supplied_inventory_item == this item,&lt;br /&gt;
                                      status in {in_progress, completed})&lt;br /&gt;
  - Σ dispenses                      (MedicationDispense.item == this item,&lt;br /&gt;
                                      excluding cancelled statuses)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If no row exists for &amp;lt;code&amp;gt;(product, location)&amp;lt;/code&amp;gt;, one is auto-created (&amp;lt;code&amp;gt;status=active&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net_content=0&amp;lt;/code&amp;gt;) before computing.&lt;br /&gt;
* &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt; is the aggregate sum of &amp;lt;code&amp;gt;supplied_item_quantity&amp;lt;/code&amp;gt; / dispense &amp;lt;code&amp;gt;quantity&amp;lt;/code&amp;gt;, and can be negative.&lt;br /&gt;
* Runs whenever a delivery completes or a dispense changes, so the balance stays current.&lt;br /&gt;
&lt;br /&gt;
== API integration notes ==&lt;br /&gt;
&lt;br /&gt;
* Rows are server-maintained: they come from &amp;lt;code&amp;gt;create_inventory_item&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;sync_inventory_item&amp;lt;/code&amp;gt;, never a direct client create. The only meaningful client write is &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; (for example, setting &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;).&lt;br /&gt;
* One row exists per &amp;lt;code&amp;gt;(location, product)&amp;lt;/code&amp;gt; pair. &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt; is adjusted on that row, not by inserting duplicates.&lt;br /&gt;
* Don&amp;#039;t patch &amp;lt;code&amp;gt;net_content&amp;lt;/code&amp;gt; directly — &amp;lt;code&amp;gt;sync_inventory_item&amp;lt;/code&amp;gt; recomputes it under an &amp;lt;code&amp;gt;InventoryLock&amp;lt;/code&amp;gt;, and the next sync overwrites your value.&lt;br /&gt;
* Read responses inline the full &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt; (with &amp;lt;code&amp;gt;product_knowledge&amp;lt;/code&amp;gt;) and &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; objects, not just their ids.&lt;br /&gt;
* &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt; are &amp;lt;code&amp;gt;PROTECT&amp;lt;/code&amp;gt; foreign keys, so referenced products and locations can&amp;#039;t be hard-deleted while stock rows exist.&lt;br /&gt;
&lt;br /&gt;
{{Related}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>