Epic EP-04 Kritik 03_warehouse erpbom-backend backend

03_warehouse — Ombor (qoldiq, FIFO partiya, kirim faktura, ko'chirish, qaytarish, set yig'ish)

Bajarildi
100% 45/45
Status:

Tavsif

Tizimning **qoldiq yadrosi**. Uch mantiqiy ombor turi (`raw` / `semi_finished` / `finished`), har org-node'da har turdan bittadan (max 3 ombor). Qoldiq ikki qatlamda: jamlangan `stock` (tez o'qish) + `stock_batches` (FIFO tannarx qatlamlari), ikkalasi doim bitta tranzaksiyada birga yangilanadi. Har o'zgarish `stock_movements` (**insert-only ledger**, grain 🅰️ = har FIFO qatlami alohida qator). Modul beradigan **oqimlar**: 1. **Kirim faktura** (`purchase_receipts`) — ta'minotchi tasdig'i bilan 5 holatli oqim (`draft → pending_supplier → confirmed` + `disputed` + `cancelled`), naqd/`term_days=0` da avto-confirm, shartnoma snapshot + `due_date`, valyuta konvertatsiyasi va freeze. 2. **Omborlararo ko'chirish** (`warehouse_transfers`) — ikki bosqichli (`draft → in_transit → received`), jo'natishda FIFO chiqim, qabulda qatlamlar **aynan o'sha tannarx** bilan qayta yaratiladi. 3. **Qaytarish** (`stock_returns`) va **utilizatsiya** (`stock_write_offs`) — `draft → confirmed`, `good`/`defective` condition bo'yicha. 4. **Ta'minotchiga qaytarish** (`supplier_returns`) — outbound FIFO chiqim + kredit narxi (`credit_unit_price`) va `fifo_cost_snapshot`. 5. **Set (Tovar2) yig'ish** (`set_assemblies`) — `semi_finished` komponentlaridan `finished` ga bir qadamli atomik operatsiya, bekori = teskari hujjat (`disassemble`). Backend'da to'liq data-model + FIFO yadro + REST API; web'da barcha hujjat va sozlama ekranlari; mobil ilovada *Hodim* rolining ombor oynalari va *Ta'minotchi* rolining kirim faktura tasdig'i.

Texnik ko'rsatma

Agent uchun

Majburiy o'qish: erp/docs/modules/03_warehouse.md (to'liq — bu eng katta modul, 1576 qator), erp/docs/00_CROSS_CUTTING.md (**A** valyuta + `exchange_rates`, **B** precision/yaxlitlash, **C** FIFO, **D** ombor turlari, **H** soft-delete, **J** org-model, **K** nomlash, **L** RBAC, **O** notes/more, **P** scoping, **Q** ko'p qatorli qulf tartibi), .claude/skills/coding/java-spring-coder/SKILL.md (backend), .claude/skills/coding/vuejs-coder/SKILL.md (web), .claude/skills/coding/flutter-coder/SKILL.md (mobil), .claude/skills/coding/postgresql/SKILL.md, .claude/skills/coding/swagger/SKILL.md (T00 uchun). 🔴 SCOPING (§3, CROSS_CUTTING P): `organization_id` ustuni **FAQAT** `warehouses`, `purchase_receipts`, `stock_returns`, `stock_write_offs`, `supplier_returns`, `set_assemblies` da bor (node-lokal — org-node ajratadi). `stock`, `stock_batches`, `stock_movements`, `warehouse_transfers`, `warehouse_variant_settings` va barcha `*_lines` da `organization_id` **YO'Q va QO'SHILMAYDI** (§2.4 dagi ongli qaror). Org kesimi `warehouse_id → warehouses.organization_id` join'i orqali. `tenant_id` hech qayerda yo'q (AR-1). 🔴 QIYMAT MANBAI — `total_cost` / `remaining_cost` (qoida 42, FP-21): `unit_cost` **hosila/ko'rsatkich**. FIFO chiqimda qiymat proporsional ajratiladi: `chiqim_qiymati = round(remaining_cost × (chiqim_qty / qty_remaining), 2)`, so'ng `remaining_cost -= chiqim_qiymati`; **oxirgi** chiqim (`qty_remaining` 0 ga tushganda) qolgan **butun** `remaining_cost` ni oladi. Invariant: partiya bo'yicha `Σ stock_movements.total_cost = stock_batches.total_cost` (tiyingacha aniq). `qty × unit_cost` bilan hisoblash — **XATO**, testda ushlanadi. 🔴 QULF TARTIBI (CROSS_CUTTING Q, §3 p.8): bir necha `stock` qatoriga tegadigan HAR amalda qulflar qat'iy `(warehouse_id, product_variant_id, condition) ASC` tartibida olinadi; mavjud bo'lmagan qator uchun `pg_advisory_xact_lock` ham ayni shu ketma-ketlikda; `SET LOCAL lock_timeout = '3s'`; `40P01`/`55P03` da **2 martagacha** retry, so'ng `409 stock_busy`. Faqat `product_variant_id` bo'yicha tartiblash **yetarli emas** (bitta tranzaksiya ikki omborga tegishi mumkin). 🔴 PRECISION (qoida 30, CROSS_CUTTING B): miqdorlar — `numeric(18,4)`; pul **qiymat manbalari** (`total_cost`, `remaining_cost`, `stock_movements.total_cost`, `line_cost`, narxlar, `unit_cost_foreign`) — `numeric(18,2)`; **istisno** `stock_batches.unit_cost` — `numeric(18,4)` (hosila ko'rsatkich); `exchange_rates.rate` — `numeric(18,6)`. Flyway: yangi migratsiya **`V15`** dan boshlanadi (mavjud oxirgisi — V14). Bitta `public` schema. Enum'lar — **native ENUM emas**, `varchar(20)` + CHECK (V12 naqshi). Fon jarayonlari (§3 p.7): Spring `@Scheduled` job, **bir marta** yuradi va idempotent (AR-12). Bu epicda faqat **sverka job** (a) yoziladi; (b) kam qoldiq skaneri va (c) hisobot agregatsiyasi qamrovdan tashqarida. Stock posting **hech qachon** outbox'ga chiqmaydi — u sinxron-atomik, foydalanuvchi tranzaksiyasi ichida (§10).

Qabul mezonlari (DoD)

0 / 9 bajarildi

  • docs/modules/03_warehouse.md §12 dagi AC lar (kirim, ta'minotchi tasdiq oqimi, ta'minotchiga qaytarish, FIFO/invariant, ko'chirish, condition/qaytarish/utilizatsiya, reorder ro'yxati, arxiv, konkurent lock, RBAC, AC-set-1…5) mos test bilan qoplangan — QAMROVDAN TASHQARI deb belgilanganlaridan boshqasi

  • `stock`, `stock_batches`, `stock_movements`, `warehouse_transfers`, `warehouse_variant_settings` va barcha `*_lines` jadvallarida `organization_id` / `tenant_id` ustuni yo'q (information_schema testi)

  • Har himoyalangan endpoint mavjud katalog rule'i bilan `@RequirePermission` qilingan (`permitAll` grep 0); huquq katalogiga YANGI qator qo'shilmagan (V3 / R__permissions seed diff bo'sh)

  • FIFO qiymat invarianti: har partiya uchun `Σ stock_movements.total_cost = stock_batches.total_cost` tiyingacha aniq (yaxlitlash qoldig'i oxirgi chiqimga yopishadi — qoida 42 testi)

  • Qoldiq invarianti: `stock.qty_on_hand ≡ SUM(stock_batches.qty_remaining)` har warehouse×variant×condition uchun; sverka job buzilish topmaydi

  • `stock_movements` insert-only — kodda shu jadvalga UPDATE/DELETE yo'q (grep 0)

  • openapi drift toza (T00 muzlatgan kontrakt bilan)

  • erpbom-web ekranlari Prism mock (:4010) ga qarshi ishlaydi

  • erpbom-mobile *Hodim* va *Ta'minotchi* rollari mock'ka qarshi ishlaydi

Ichki ishlar

16 ta

Izoh qoldirish

Tarix

12 yozuv

  • ⇄

    system statusni o'zgartirdi Ishlanyapti → Bajarildi

    Bolalardan avtomatik hisoblandi

  • ⇄

    system statusni o'zgartirdi Bajarildi → Ishlanyapti

    Bolalardan avtomatik hisoblandi

  • 💬

    finalize-ep-04 izoh qoldirdi

    FINALIZE DRIFT (EP-04, implementatsiya<->kontrakt). Muzlatilgan kontraktda (openapi/v1/warehouse.yaml) e'lon qilingan 2 operatsiya kodda YO'Q: - GET /api/v1/set-assemblies (yaml 2103-qator) - GET /api/v1/set-assemblies/{id} (yaml 2279-qator) DALIL: springdoc /v3/api-docs (HEAD c884b47 dan qurilgan ilova) da bu yo'llar yo'q; SetAssemblyController da faqat 3 ta @PostMapping bor (preview/create/reverse). SABAB: SetAssemblyController izohi (37-qator) "Ro'yxat/kartochka (GET) — T07 ning boshqa bargasida shu klassga qo'shiladi" deydi, lekin bunday barg board'da HECH QACHON yaratilmagan (T07 = S01..S03, hammasi done). Ya'ni kamchilik backlog qamrovida, bu bargning bajarilishida emas. TA'SIRI: erpbom-web SetAssemblyListView va SetAssemblyDetailView shu ikki endpointni chaqiradi (src/modules/warehouse/api/set-assemblies.api.ts:82 va :92) — real backend'da 404 bo'ladi. NEGA SEZILMAGAN: prism mock (:4010) muzlatilgan kontraktni serve qilib turgan edi; finalize paytida o'chirildi. TUZATISH KODDA (kontrakt muzlatilgan, unga TEGILMAYDI): GET ro'yxat + kartochka uchun yangi barg ochilsin. NATIJA: erpbom-backend PUSH QILINMADI, PR ochilmadi.

  • ⇄

    system statusni o'zgartirdi Ishlanyapti → Bajarildi

    Bolalardan avtomatik hisoblandi

  • ⇄

    system statusni o'zgartirdi Bajarildi → Ishlanyapti

    Bolalardan avtomatik hisoblandi

  • ⇄

    system statusni o'zgartirdi Ishlanyapti → Bajarildi

    Bolalardan avtomatik hisoblandi

  • ⇄

    system statusni o'zgartirdi Backlog → Ishlanyapti

    Bolalardan avtomatik hisoblandi

  • 🔗

    pm-agent bog'liqlik qo'shdi

    → EP-03

  • 🔗

    pm-agent bog'liqlik qo'shdi

    → EP-02

  • 🔗

    pm-agent bog'liqlik qo'shdi

    → EP-09

  • 🔗

    pm-agent bog'liqlik qo'shdi

    → EP-01

  • ✦

    pm-agent yaratdi

    03_warehouse — Ombor (qoldiq, FIFO partiya, kirim faktura, ko'chirish, qaytarish, set yig'ish)

Ma'lumot

Agent
—
Olingan
—
Boshlandi
20.08.2026 08:55
Tugadi
21.08.2026 12:32
Baho
186 soat
Spec
erp/docs/modules/03_warehouse.md
Branch
—
Commit
—

Bog'liqliklar

Agent uchun

Bu ishni AI agent quyidagicha oladi:

curl -s -X POST https://pmboard.ferp.uz/api/items/EP-04/claim \
  -H "X-Agent: backend-dev-1"

Tugatgach:

curl -s -X POST https://pmboard.ferp.uz/api/items/EP-04/status \
  -H "X-Agent: backend-dev-1" \
  -H "Content-Type: application/json" \
  -d '{"status":"review","note":"..."}'