+
    `Øj>  ã                   óv   € ^ RI Ht ^ RIHt ^ RIHtHtHt ^ RIH	t	 ^ RI
H
t
Ht ^ RIHt ^ RIt ! R R	4      tR# )
é    ©ÚAsyncSession)Úselect)ÚRmInventoryÚRmInventoryLogÚRmConsumptionLog©ÚDecimal)ÚdatetimeÚdate)ÚcastNc                   óœ   a € ] tR t^
t o RtV 3R lR ltV 3R lR ltRV 3R lR lltRV 3R	 lR
 lltV 3R lR lt	RV 3R lR llt
RtV tR# )ÚInventoryServicea  
Core business logic layer for Inventory Management.
Purpose: Centralizes all stock movement operations (Consumptions, Transfers, GRNs).
Guarantees ACID compliance, prevents negative stock, and ensures an immutable ledger
trail is created for every stock change.
c                ó    <€ V ^8„  d   QhRS[ /# )é   Údbr   )ÚformatÚ__classdict__s   "€Ú?/var/www/html/audi_dev/backend/app/modules/inventory/service.pyÚ__annotate__ÚInventoryService.__annotate__   s   ø€ ÷ ñ ™<ñ ó    c                ó   € Wn         R # ©N©r   )Úselfr   s   &&r   Ú__init__ÚInventoryService.__init__   s   € ØŽr   c                óT   <€ V ^8„  d   QhRS[ P                  RS[ P                  RS[/# )r   Úrm_idÚstore_idÚreturn)ÚuuidÚUUIDr
   )r   r   s   "€r   r   r      s/   ø€ ÷ Iñ I¡t§y¡yð I¹D¿I¹Ið IÉ'ñ Ir   c              ƒ  óh  "  € V P                   P                  \        \        4      P	                  \        P
                  V8H  \        P                  V8H  4      P                  4       4      G Rj  x€L
 pVP                  4       pV'       d   \        \        VP                  4      # \        R4      #  LA5i)zÌ
Fetch the current stock quantity for an item in a specific store.
Purpose: Uses a database ROW LOCK (`with_for_update`) to prevent race conditions 
when checking balances during concurrent transactions.
Nú0.0)r   Úexecuter   r   Úwherer    r!   Úwith_for_updateÚscalar_one_or_noner   r
   Úcurrent_qty)r   r    r!   ÚresultÚinvs   &&&  r   Úget_balanceÚInventoryService.get_balance   sˆ   é € ð —w‘w—‘Ü”;Ó×%Ñ%Ü×!Ñ! UÑ*Ü×$Ñ$¨Ñ0ó÷ ‰oÓó	
÷ 
ˆð ×'Ñ'Ó)ˆß14Œt”G˜SŸ_™_Ó-ÐH¼'À%».ÐHñ
ùs   ‚A,B2Á.B0Á/B2Â&B2Nc          
      ó`   <€ V ^8„  d   QhRS[ P                  RS[ P                  RS[RS[RS[/# )r   r    r!   ÚqtyÚtransaction_typer"   )r#   r$   r
   Ústr)r   r   s   "€r   r   r   #   s?   ø€ ÷ 7ñ 7Ù—Y‘Yð7Ù*.¯)©)ð7Ù:Að7áð7ñ 
ñ	7r   c              ƒ  óR  "  € V P                   P                  \        \        4      P	                  \        P
                  V8H  \        P                  V8H  4      P                  4       4      G Rj  x€L
 pVP                  4       p	V	'       d   \        \        V	P                  4      M
\        R4      p
W£,           pV^ 8  d   \        RV
 R\        V4       24      hV	'       d"   W¹n        \        P                  ! 4       V	n        M<\        WV\        P                  ! 4       R7      p	V P                   P#                  V	4       V P                   P#                  \%        WVVV
VVVV\        P                  ! 4       R7
      4       V P                   P'                  4       G Rj  x€L
  V#  EL4 L	5i)a  
The low-level stock posting engine. All stock movements must route through here.
Purpose: 
1. Safely adjusts stock quantities.
2. Enforces stock validation rules (e.g., no negative stock).
3. Writes an immutable audit trail to the `RmInventoryLog` table (The Ledger).
Nr&   zInsufficient stock. Available: z, Requested: )r    r!   r+   Úlast_updated)
r    r!   r2   r1   Úbalance_beforeÚbalance_afterÚreference_typeÚreference_idÚremarksÚ
created_at)r   r'   r   r   r(   r    r!   r)   r*   r   r
   r+   Ú
ValueErrorÚabsr   Úutcnowr5   Úaddr   Úflush)r   r    r!   r1   r2   r8   r9   r:   r,   r-   r6   r7   s   &&&&&&&&    r   Úpost_transactionÚ!InventoryService.post_transaction#   sT  é € ð —w‘w—‘Ü”;Óß‰U”;×$Ñ$ eÑ+¬[×-AÑ-AÀ8Ñ-KÓLß‰_Óó
÷ 
ˆð
 ×'Ñ'Ó)ˆç;>œœg s§¡Ô7ÄGÈEÃNˆØ'Õ-ˆð ˜1ÔÜØ1°.Ð1AÀÌsÐSVËxÈjÐYóð ÷
 Ø+ŒOÜ'ŸšÓ0ˆCÕäØØ)Ü%Ÿ_š_Ó.ôˆCð
 �G‰G�K‰K˜Ôð 	�‰�‰”NØØ-ØØ)Ø'Ø)Ø%ØÜ—’Ó(ô

ô 
	ð �g‰g�m‰m‹o×ÐØÐòU
ñR 	ùs2   ‚A,F'Á.F"Á/F'ÂAF'Ã!B:F'ÆF%ÆF'Æ%F'c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r   r1   Úconsumed_date)r
   r   )r   r   s   "€r   r   r   \   s   ø€ ÷ ñ Ù$+ðáñr   c              ƒ  óê   "  € V P                  WV) RRVR7      G Rj  x€L
 pV P                  P                  \        WVRVWVR7      4       V P                  P	                  4       G Rj  x€L
  V#  LQ L5i)zÀ
Record the consumption of raw materials (usage in manufacturing/production).
Purpose: Deducts stock (posts a negative transaction) and creates a specific
consumption log entry for reporting.
ÚCONSUMPTIONÚMANUAL)r2   r8   r:   N)r    r!   Úqty_usedÚconsumption_typerD   Údescriptionr:   )rA   r   r?   r   r@   )r   r    r!   r1   rD   rJ   r:   Únew_balances   &&&&&&& r   ÚconsumeÚInventoryService.consume\   s~   é € ð !×1Ñ1Ø˜c˜TØ*Ø#Øð	 2ó 
÷ 
ˆð 	�‰�‰Ô$ØØ¨8Ø'Ø#ô	
ô 	ð �g‰g�m‰m‹o×ÐØÐñ
ñ 	ùs"   ‚A3�A/žA
A3Á(A1Á)A3Á1A3c                ó    <€ V ^8„  d   QhRS[ /# )r   Úaccepted_qtyr	   )r   r   s   "€r   r   r   v   s   ø€ ÷ 
ñ 
Ù-4ñ
r   c           	   ƒ  óJ   "  € V P                  WVRRVR7      G Rj  x€L
 #  L5i)z·
Post inventory from a Goods Receipt Note (GRN).
Purpose: Called by the Procurement module when vendor shipments arrive.
Credits (adds) the accepted quantity to the designated store.
ÚGRN_RECEIPTÚGRN)r2   r8   r9   N)rA   )r   r    r!   rO   Úgrn_ids   &&&&&r   Úgrn_postÚInventoryService.grn_postv   s6   é € ð ×*Ñ*Ø˜\Ø*Ø ¨vð +ó 
÷ 
ð 	
ñ 
ùs   ‚#œ!�#c                ó    <€ V ^8„  d   QhRS[ /# )r   r1   r	   )r   r   s   "€r   r   r   „   s   ø€ ÷ eñ eÙ6=ñer   c              ƒ  óz  "  € \        \        V4      \        V4      .4      pV^ ,          \        V4      8X  d>   V P                  WV) RVR7      G Rj  x€L
  V P                  WVRVR7      G Rj  x€L
  R# V P                  WVRVR7      G Rj  x€L
  V P                  WV) RVR7      G Rj  x€L
  R#  L` LE L( L5i)a$  
Move inventory between two internal stores.
Purpose: Posts a deduction from the source store and an addition to the 
destination store in a single transaction. Utilizes a deterministic locking
order (sorting store IDs) to completely eliminate database deadlocks during
concurrent transfers.
ÚTRANSFER_OUT)r:   NÚTRANSFER_IN)Úsortedr3   rA   )r   r    Úfrom_store_idÚto_store_idr1   r:   Úidss   &&&&&& r   ÚtransferÚInventoryService.transfer„   s¼   é € ô ”c˜-Ó(¬#¨kÓ*:Ð;Ó<ˆØˆq�6”S˜Ó'Ô'Ø×'Ñ'¨¸s¸dÀNÐ\cÐ'Ód×dÐdØ×'Ñ'¨¸CÀÐX_Ð'Ó`×`Ò`à×'Ñ'¨¸CÀÐX_Ð'Ó`×`Ð`Ø×'Ñ'¨¸s¸dÀNÐ\cÐ'Ód×dÒdñ	 eÙ`á`ÙdùsH   ‚AB;ÁB3ÁB;Á/B5Á0B;ÂB7ÂB;Â,B9Â-B;Â5B;Â7B;Â9B;r   )NNN)NNr   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r.   rA   rL   rT   r^   Ú__static_attributes__Ú__classdictcell__)r   s   @r   r   r   
   sQ   ø‡ € ñ÷ð ÷Ið I÷7ò 7÷rò ÷4
ð 
÷e÷ eð er   r   )Úsqlalchemy.ext.asyncior   Ú
sqlalchemyr   Úapp.models.rm_modelsr   r   r   Údecimalr
   r   r   Útypingr   r#   r   © r   r   Ú<module>rm      s+   ðå /Ý ß NÑ NÝ ß #Ý Û ÷Keó Ker   