Files
AbelBirdNest-Stock/docs/purchase-realization-design.md

4.9 KiB

Purchase Realization Design

Tujuan

Menyediakan model data dan alur kalkulasi untuk melacak satu purchase dari:

  • pembelian awal
  • receipt menjadi lot
  • washing
  • regrade / mix / split
  • regular sale
  • consignment
  • office buyout

sampai status akhir purchase dapat dinyatakan CLOSED dan laba/rugi agent dapat dihitung final.

Prinsip

  • Purchase Analysis tetap dipakai sebagai snapshot awal pembelian.
  • Purchase Realization dipakai sebagai hasil aktual setelah barang bergerak dan terjual.
  • Setiap lot harus bisa dilacak asal purchase-nya, termasuk jika hasil mix atau regrade.
  • Setiap event yang memengaruhi qty atau nilai harus menulis jurnal realization.

Model Baru

lot_purchase_allocations

Menyimpan komposisi asal purchase untuk setiap lot.

Contoh:

  • Lot LOT-A berasal 100% dari purchase P-1
  • Lot LOT-B hasil mix dari P-1 40% dan P-2 60%

Maka LOT-B memiliki 2 allocation rows.

Kolom penting:

  • lot_id
  • purchase_id
  • purchase_line_id
  • source_type
  • source_ref_id
  • qty_allocated
  • cost_total_allocated
  • unit_cost_snapshot
  • agent_id_snapshot
  • profit_share_scheme_id_snapshot

purchase_realization_entries

Ledger event yang memengaruhi hasil akhir purchase.

Kolom penting:

  • purchase_id
  • lot_id
  • allocation_id
  • event_type
  • reference_type
  • reference_id
  • occurred_at
  • qty_in
  • qty_out
  • qty_shrinkage
  • amount_cost
  • amount_revenue
  • amount_expense
  • amount_profit
  • agent_share_percent_snapshot
  • agent_amount

Event type awal yang direkomendasikan:

  • OPENING_COST
  • WASHING_COST
  • WASHING_SHRINKAGE
  • TRANSFORMATION_SHRINKAGE
  • SALE_REVENUE
  • SALE_RETURN
  • SALE_SHRINKAGE
  • CONSIGNMENT_REVENUE
  • CONSIGNMENT_RETURN
  • CONSIGNMENT_SHRINKAGE
  • OFFICE_BUYOUT_REVENUE
  • OFFICE_BUYOUT_TRANSFER_OUT
  • STOCK_ADJUSTMENT_LOSS
  • STOCK_ADJUSTMENT_GAIN
  • MANUAL_ADJUSTMENT

purchase_realization_summaries

Cache summary per purchase untuk kebutuhan UI dan closing.

Kolom penting:

  • status
  • qty_opening
  • qty_remaining
  • qty_sold
  • qty_returned
  • qty_shrinkage
  • cost_opening_total
  • cost_additional_total
  • revenue_total
  • profit_loss_total
  • agent_share_percent
  • agent_profit_total
  • closed_at

Status yang direkomendasikan:

  • OPEN
  • PARTIAL
  • READY_TO_CLOSE
  • CLOSED

Aturan Alokasi

Purchase submit

  • Buat lot seperti implementasi saat ini.
  • Buat 1 allocation row per lot:
    • source_type = PURCHASE
    • qty_allocated = lot.original_qty
    • cost_total_allocated = qty * unit_cost
  • Buat 1 realization entry:
    • event_type = OPENING_COST

Washing selesai

  • Allocation lot tidak berubah.
  • Jika ada biaya cuci, tulis WASHING_COST.
  • Jika ada susut, tulis WASHING_SHRINKAGE.
  • Semua entry dibagi ke purchase asal berdasarkan allocation aktif lot tersebut.

Transformation / regrade / mix

  • Baca allocation dari semua source lots.
  • Bentuk allocation baru pada output lots dengan distribusi proporsional terhadap qty / cost input.
  • Jika ada processing loss, buat TRANSFORMATION_SHRINKAGE.
  • Output lot mewarisi allocation campuran dari input.

Regular sale close

  • Baca allocation lot pada line yang dijual.
  • Revenue aktual dibagi ke purchase asal sesuai allocation.
  • Tulis:
    • SALE_REVENUE
    • SALE_RETURN
    • SALE_SHRINKAGE

Consignment close

  • Perlakuan sama seperti regular sale, tetapi sumber event adalah consignment line.

Office buyout

Untuk purchase lama:

  • Tulis OFFICE_BUYOUT_REVENUE
  • qty_out sebesar qty yang dibeli kantor
  • amount_revenue = qty * buyout_unit_price

Untuk lot baru hasil buyout:

  • Buat allocation baru yang menunjuk purchase buyout / jalur kantor
  • Setelah itu hasil jual berikutnya tidak lagi menjadi hak agent lama

Rumus Summary

  • cost_opening_total = total opening cost
  • cost_additional_total = washing cost + biaya tambahan + adjustment
  • revenue_total = sale + consignment + office buyout
  • profit_loss_total = revenue_total - cost_opening_total - cost_additional_total
  • agent_profit_total = akumulasi agent_amount atau fallback profit_loss_total * share_agent / 100

Rule Closing Purchase

Purchase dapat CLOSED jika seluruh qty asal purchase sudah terselesaikan menjadi salah satu:

  • terjual
  • susut
  • dibuyout kantor
  • habis masuk transformasi dan seluruh descendant lots-nya selesai

Artinya closing harus melihat seluruh lineage lot, bukan hanya lot awal purchase.

Scope Implementasi Bertahap

Tahap 1

  • Tambah schema baru
  • Isi allocation + opening realization saat purchase submit
  • Tambah summary recalculation dasar

Tahap 2

  • Integrasi office buyout
  • Integrasi washing cost dan shrinkage

Tahap 3

  • Integrasi transformation / mix / regrade allocation propagation

Tahap 4

  • Integrasi regular sale dan consignment revenue realization

Tahap 5

  • UI Purchase Realization
  • closing otomatis

Tahap 6

  • JIT sale, jika nanti ingin ditautkan ke lineage purchase