ERPNext v16 - Sales (Versi BMP)
Modul Sales di BMP punya karakter yang sangat berbeda dari modul Selling generik: 99% penjualan adalah Finished Good parfum melalui marketplace (Tokopedia, Shopee, TikTok Shop) dengan pola rekap harian CSV, bukan penjualan B2B berbasis Quotation. Maka kita memangkas seluruh mesin "jualan yang belum terjadi" (Quotation, CRM, Sales Partner) dan memusatkan modul ini pada tiga hal: pencatatan penjualan yang sudah terjadi, traceability batch ke customer/channel (CPKB), dan penanganan retur tanpa drama (komplain aroma = urusan CS, bukan investigasi QC).
Peta dokumen:

Chapter 0 - Struktur & Cross-check
-
- Grup struktur ↔ doctype utama (erpnext/selling/doctype/)

0.2 Empat jalur penjualan
Seperti Purchase punya 4 jalur pembelian, Sales BMP punya 4 jalur dengan perilaku berbeda:

0.3 Kesimpulan struktur
Jantung modul ini bukan "membantu sales menjual" - penjualan sudah terjadi di marketplace sebelum BMP tahu. Jantungnya adalah mencatat yang sudah terjadi dengan jujur: rekap masuk sebagai SO konsolidasi, barang keluar via DN dengan batch yang benar (COGS akurat + traceability CPKB), revenue diakui via SI, dan settlement marketplace menutup piutang channel. Definisi "FG layak jual" diwarisi dari Manufacturing: batch berstatus Accepted (QC lulus) + lokasi FG Store - satu gerbang tunggal yang dijaga sistem.
Chapter A - Masters & Parties
Mesin apa: kamus "kepada siapa kita menjual" - dengan keputusan paling tidak biasa di seluruh BMP: customer B2C tidak dicatat satu per satu. Untuk marketplace, "customer" adalah channel-nya (Tokopedia, Shopee, TikTok Shop); detail pembeli individu hidup di sisi marketplace dan sengaja tidak masuk BMP (privasi, Chinese Wall, dan memang tidak dibutuhkan oleh model rekap).
Perilaku per doctype:
- Customer (erpnext/selling/doctype/customer/) - Redefinisi Domain: Customer = Channel / Titik Jual.
Di BMP, "Customer" bukanlah individu pembeli akhir. Data pribadi pembeli (nama, alamat, no HP) hidup di luar BMP (aplikasi CRM terpisah / Excel Admin Sales) dan sengaja tidak masuk BMP - ini keputusan arsitektural, bukan kelalaian. BMP mencatat bisnisnya (agregasi per channel), bukan meniru database marketplace.
Customer di BMP adalah Entitas Channel Distribusi. Jumlah record Customer di database sangat sedikit (< 10 di awal) dan merepresentasikan titik penjualan:
- CUST-SHOPEE (Channel Shopee)
- CUST-TOKOPEDIA (Channel Tokopedia)
- CUST-TIKTOK (Channel TikTok Shop)
- CUST-TOKOA (Retail Toko A)
- CUST-DISTB (Distributor B, bila nanti ada)
Atribut & Linkage Kunci:
- Default Sales Person (PIC): Setiap record Customer wajib di-link ke satu Sales Person yang bertindak sebagai Admin Sales / PIC channel tersebut (misal: Customer "Channel Shopee" di-link ke Sales Person "Budi - Admin Sales Shopee"). Ini menjamin bahwa setiap rekap penjualan atau retur yang di-import atas nama channel tersebut otomatis melekat pada laporan kinerja PIC yang benar.
- Customer Group: Disederhanakan menjadi 3 grup utama: Marketplace (Shopee, Tokopedia, TikTok), Retail Fisik (Toko A), Distributor B2B (Dist B). Grup ini menentukan default fee config (fee marketplace vs diskon grosir) dan Template Pajak (PPN Keluaran).
- Default Currency: Selalu IDR.
- Prinsip desain final BMP: Customer adalah representasi tunggal dari channel distribusi. Tidak ada lapisan tambahan (Territory, Area, Region). Satu Customer = satu Channel = satu titik konsolidasi revenue & settlement.
- Customer Group - tree; tiga warga utama: Marketplace / Retail Fisik / Distributor B2B. Fungsi ganda persis Item Group di Stock: pengelompok UI + pewaris default (price list, template pajak, akun piutang) saat Customer baru dibuat - pola copy-on-create yang sama (dan edge case yang sama: mengubah default group tidak menyentuh customer lama).
- Channel (Territory) - DIBUANG / DI-HIDE dari UI BMP.
Di ERPNext generik, Territory adalah sumbu geografis terpisah dari Customer. Di BMP, prinsip desain final adalah Customer = Channel, sehingga Territory menjadi redundant. Fungsi "sumbu analisis per channel" sudah diambil alih sepenuhnya oleh entitas Customer itu sendiri.
Implementasi teknis: Di codebase ERPNext, Territory mungkin tetap ada sebagai field required untuk backward compatibility dengan laporan native. Di BMP, kita set default otomatis Territory = nama Customer saat Customer dibuat, dan field ini di-hide dari form UI. User tidak perlu memilih/mengelola Territory terpisah. Semua laporan (Sales Analytics, AR Aging, Gross Profit) menggunakan Customer sebagai sumbu utama.
- Sales Person - bukan mesin komisi, melainkan accountability input: siapa Sales Admin yang menginput rekap channel hari itu. Child sales_team di SO membawa sales person (komisi % di-hide - skema komisi di luar BMP ⚠️). Ini menjawab pertanyaan audit internal: "rekap Selasa siapa yang masukin?"
Lintas domain:
- default_price_list membaca Price List & Item Price (Stock Chapter A) - BMP memakai 1 price list ("Harga Dasar - IDR"); variasi harga per channel (marketplace vs grosir) ditangani Fee Components - diskon grosir = komponen fee negatif, konsisten Data Model v1.5 (mengikat).
- Akun piutang default + template PPN Keluaran dari Accounting (Customer Group → default account; Sales Taxes Template Chapter D Accounting).
- DN membaca ketersediaan batch FG (Stock/Manufacturing): hanya batch Accepted di FG Store yang muncul di selector - gerbang "FG layak jual".
- SO menjadi sumber permintaan Production Plan (Manufacturing Chapter C) untuk jalur distributor/B2B; permintaan marketplace dibaca sebagai forecast dari riwayat rekap.
Edge case:
- PII pembeli masuk BMP = pelanggaran desain (privasi + Chinese Wall IT + beban tanpa manfaat). Data pembeli individual (nama, alamat, no HP) wajib hidup di luar BMP (aplikasi CRM terpisah / Excel Admin Sales). Alamat pengiriman fisik untuk DN hidup di proses fulfilment marketplace/ekspedisi, bukan di dokumen BMP. BMP hanya menerima rekap agregat.
- Customer channel ganda per marketplace (mis. dua akun Shopee) = revenue terpecah dan settlement tidak bisa direkonsiliasi; aturan: satu record per channel, sub-akun menjadi referensi di baris SO.
- Customer disabled tapi punya SO terbuka = DN/SI lanjutan terblokir; disable wajib didahului penyelesaian order terbuka (pola yang sama dengan Supplier di Purchase).
- Mengubah default di Customer Group tidak menyentuh customer lama (copy-on-create) - admin bingung "kenapa price list customer ini tidak ikut berubah?" - echo edge case Item Group.
- Fee di transaksi adalah snapshot (sales_order_fees): mengubah master kemudian tidak menulis ulang sejarah - laporan per channel konsisten dengan kondisi saat transaksi terjadi.
Delta v16 (subset register): payment schedule due date dinamis mengalir SO→SI; presisi conversion_factor 9 desimal menyentuh baris transaksi (relevan bila ada penjualan dengan satuan alternatif ⚠️); perbaikan permission/validasi minor di sekitar selling ⚠️.
Catatan scope BMP:
- Adopsi penuh: Customer (= Channel, entitas utama), Customer Group (3 grup: Marketplace / Retail Fisik / Distributor B2B), Sales Person sebagai accountability input. Territory di-hide dari UI (redundant dengan Customer = Channel).
- Keputusan desain BMP: customer B2C = channel - PII pembeli tidak masuk BMP; AR per channel = settlement marketplace yang belum diterima. Ini keputusan arsitektural, bukan kelalaian: BMP mencatat bisnisnya, marketplace mencatat pembelinya.
- Tolak: Quotation, Lead/Opportunity/Campaign (CRM), Sales Partner - tidak ada pipeline penjualan dalam model marketplace; reseller hidup di sistem mereka sendiri.
- Hide & pantau: Product Bundle - angkat menjadi adopsi bila bisnis mulai menjual hampers/paket (ledakan komponen bundle saat DN sudah didukung mesin).
Chapter A tertutup. Masters Sales berdiri dengan keputusan terbesarnya: customer B2C adalah channel, bukan orang.
Chapter B - Siklus Transaksi (SO Rekap CSV, DN, SI, Retur, Scrap Sale)
Mesin apa: lalu lintas penjualan yang sudah terjadi - bukan membantu menjual, melainkan mencatat dengan jujur apa yang marketplace sudah transaksikan. Tulang punggungnya adalah satu pola khas BMP: rekap harian CSV → SO konsolidasi per channel per hari (cermin pola POS Closing Entry di Accounting Chapter B: satu dokumen konsolidasi, bukan ratusan invoice kecil membanjiri ledger). Di atas tulang punggung itu, DN memindahkan fisik dengan batch yang benar, SI mengakui revenue, dan settlement marketplace menutup piutang channel.
B.1 Siklus dominan: Marketplace B2C dengan Rekap Agregat Harian
BMP tidak menerima data per-order individual dari marketplace. BMP menerima rekap agregat yang sudah diproses oleh Admin Sales (PIC channel) di Excel: agregasi Produk × Sales Person × Periode. Ini keputusan arsitektural untuk menjaga BMP tetap ringan, PII pembeli terisolasi di luar BMP, dan jumlah baris di database tetap kecil.

Perilaku per doctype:
- Sales Order (erpnext/selling/doctype/sales_order/) - titik masuk rekap agregat.
- Satu SO konsolidasi per Customer (= per Channel) per periode rekap (mis. SO-SHOPEE-2026-W32 untuk rekap minggu ke-32 oleh Admin Sales Budi). Bukan per-order marketplace. Ini keputusan arsitektural: ledger tidak kebanjiran ratusan SO kecil, persis logika POS Closing Entry mengonsolidasikan invoice kasir.
- Tiap baris SO = satu Produk yang terjual oleh PIC channel dalam satu periode. Referensi: Produk × Sales Person × Periode.
- Data Import dengan dedup idempoten: kunci unik = kombinasi (Customer, Item, Posting Date). konsisten Data Model v1.5 (mengikat). Sales Person tidak masuk kunci dedup: channel yang sama tetap 1 baris rekap per hari meski PIC berganti; sales_person_id dicatat sebagai snapshot atribut (siapa bertanggung jawab saat input), bukan bagian dari uniqueness.
- customer = customer channel (SHOPEE/TOKOPEDIA/TIKTOK-SHOP dari Chapter A); sales_team = Sales Admin PIC yang menginput rekap (accountability).
- Submit SO = reservasi stok opsional (Stock Reservation Entry, Stock Chapter B) - relevan saat flash sale multi-channel untuk mencegah oversell.
- Delivery Note (milik Stock Chapter B; perilaku jual di sini) - momen fisik keluar.
- Gerbang "FG layak jual" dijaga di sini: selector batch pada baris DN hanya menampilkan batch berstatus Accepted (QC lulus) yang berlokasi di FG Store. FG yang belum lulus QC atau masih di Quarantine tidak akan pernah muncul sebagai pilihan - satu gerbang tunggal yang diwarisi dari Manufacturing Chapter B.
- Submit = SLE out + GL perpetual: debit COGS, kredit Stock-in-Hand - momen biaya diakui, dan karena COGS membawa hasil roll-up Manufacturing, laba kotor per botol di sini sudah jujur.
- Batch yang terpilih tercatat di baris DN → bahan baku Batch-wise Sales History (Chapter D) untuk traceability CPKB: "batch B-001 terkirim ke channel mana saja".
- Untuk marketplace, DN dibuat saat barang dikemas & diserahkan ke ekspedisi (bukan saat order masuk) - memisahkan "terjual" (SO) dari "terkirim" (DN).
- Sales Invoice (milik Accounting Chapter B; perilaku jual di sini) - momen revenue diakui.
- Revenue diakui GROSS: SI mencatat nilai penjualan penuh (debit AR channel, kredit Revenue + PPN Keluaran). Komisi/fee marketplace tidak dipotong dari revenue, melainkan dicatat sebagai beban terpisah (keputusan akuntansi penting - lihat Lintas domain & Edge case).
- update_stock tersedia untuk jalur retail fisik sederhana (satu dokumen), tapi untuk jalur marketplace DN tetap terpisah (akuntabilitas gudang).
- is_return = credit note untuk retur (dibahas di B.3).
- Settlement & Payment Entry Receive (milik Accounting Chapter C) - momen uang cair.
- Marketplace mencairkan netto (gross − komisi) beberapa hari kemudian.
- Payment Entry Receive sebesar netto terhadap SI, dengan child deductions menampung selisih komisi marketplace ke akun beban Marketplace Fee. Hasilnya: SI lunas, AR channel nol, fee tercatat sebagai beban - semua dalam satu dokumen pembayaran, tanpa JE manual.
- AR per channel = "berapa settlement yang belum kita terima" - angka yang paling hidup untuk cash-flow UMKM marketplace.
B.2 Tiga jalur lainnya (varian dari tulang punggung)
- Retail fisik (CUST-TOKOA) Melewatkan SO. Satu dokumen Sales Invoice dengan flag update_stock mengakui revenue + COGS + stok keluar sekaligus (billing+delivery satu kertas - favorit UMKM untuk volume toko yang terkendali). Tanpa settlement terpisah; pembayaran langsung via Mode of Payment (tunai/QRIS). Jejak fisik tercatat di edge case Chapter D #2 - diterima sebagai trade-off.
- Distributor B2B (CUST-DISTB) Rantai lengkap SO → DN → SI. Harga grosir = harga dasar − fee DISCOUNT-GROSIR (Fee Components). Payment Terms Template men-generate Payment Schedule (termin 30/60 hari); AR aging per termin. Satu-satunya jalur yang SO-nya menjadi sumber permintaan Production Plan (Manufacturing Chapter C) - bukan forecast dari rekap.
- Scrap / Tester / Decant Item non-FG (tester, decant, retur turun grade) dijual lewat SI jalur sederhana tanpa selector batch Accepted. Reason code turun grade berasal dari alur retur (B.3). Revenue diakui sama, tanpa kewajiban traceability batch CPKB (karena bukan FG reguler). allow_zero_valuation_rate di Selling Settings hanya relevan di jalur ini.
B.3 Retur dua rasa (cross-cutting, di level agregat)
Ini penerjamahan langsung dari domain insight "komplain parfum = subjektif, bukan bahaya". Karena data pembeli individual tidak masuk BMP, retur dicatat di level agregat: "Admin Sales Shopee mencatat 2 unit EDP Rose 100ml diretur periode ini." Tidak perlu referensi order-id individual di BMP (itu urusan Excel/marketplace).

Aturan main: reason code wajib dipilih saat retur - tanpa dia, analitik retur buta dan kedua rasa ini tercampur (yang subjektif terlihat seperti masalah kualitas, yang objektif terkubur sebagai "tidak cocok").
Lintas domain
- Stock (Chapter B & D): DN menulis SLE out + COGS; gerbang batch Accepted + FG Store; Stock Reservation mencegah oversell multi-channel.
- Manufacturing (Chapter B): definisi "FG layak jual" (batch Accepted + FG Store) diwarisi; batch inheritance (FG = Bulk) membuat traceability CPKB nyambung sampai ke lot RM.
- Accounting (Chapter B & C): SI menulis GL revenue + AR; Payment Entry Receive menutup piutang via deductions (fee marketplace); PPN Keluaran dari Sales Taxes Template.
- Quality: hanya tersentuh oleh retur objektif (investigasi batch + Non Conformance) - sengaja tidak oleh retur subjektif.
- Revenue GROSS + fee sebagai beban adalah keputusan akuntansi: mencerminkan volume penjualan sesungguhnya dan menjaga laba kotor per botol jujur; fee marketplace masuk beban operasional, bukan pengurang revenue.
Edge case
- Double-import rekap CSV = revenue ganda. Mitigasi: dedup idempoten by kombinasi (Customer, Item, Posting Date) - kunci yang sama dengan Sales Order section 1.c; Sales Person = snapshot atribut, bukan bagian kunci (mencegah baris ganda saat PIC berganti di tengah periode).
- Retur tanpa referensi order-id individual di BMP = by design, bukan kekurangan. BMP mencatat agregat, bukan per-order. Referensi order-id individual hidup di Excel Admin Sales dan di sisi marketplace. Traceability CPKB di BMP bekerja di level channel: "Batch B-001 terkirim via Channel Shopee periode X" - cukup untuk recall.
- Fee marketplace di-netting ke revenue (praktik keliru yang umum) = revenue under-stated, margin terdistorsi. Kebijakan BMP: gross revenue + fee sebagai beban via deductions Payment Entry.
- Menjual batch yang belum lulus QC harus mustahil secara sistem (selector DN menyembunyikannya), bukan sekadar peringatan - ini gerbang CPKB.
- Retur subjektif diperlakukan sebagai defect = QC kewalahan menginvestigasi "masalah" yang bukan masalah; sebaliknya retur objektif diperlakukan subjektif = cacat produksi lolos tanpa jejak. Reason code adalah pemisahnya.
- Barang retur restock tanpa cek kondisi = barang rusak masuk kembali sebagai sellable. Aturan: retur subjektif hanya restock bila segel aman; bila tidak, turun grade ke Tester/Decant (jangan dijual sebagai FG baru).
- Oversell multi-channel (stok sama dijual di Shopee & TikTok bersamaan) - BMP bukan real-time sync marketplace; mitigasi: safety stock buffer + pantau Projected Qty, dan Stock Reservation saat flash sale.
- Rate SO→SI berubah diblokir oleh policy same-rate (Chapter C); koreksi harga yang sah (penyesuaian admin fee) lewat baris diskon dengan alasan, bukan edit rate.
Delta v16 (subset register)
- Payment Schedule due date dinamis mengalir SO→SI (relevan untuk jalur distributor dengan payment terms).
- Presisi conversion_factor 9 desimal menyentuh baris DN/SI (relevan bila ada satuan alternatif).
- Validator over-delivery allowance dipindah ke Selling Settings (dibahas Chapter C).
- Perbaikan permission/validasi minor di sekitar selling ⚠️.
Catatan scope BMP
- Adopsi penuh: Sales Order (rekap CSV konsolidasi + dedup idempoten by Customer+Item+Date; sales_person_id = snapshot), Delivery Note (gerbang batch Accepted + COGS), Sales Invoice (revenue gross + PPN), Payment Entry Receive dengan deductions untuk fee marketplace, is_return dengan reason code wajib.
- Keputusan desain BMP: SO konsolidasi per channel per hari (bukan per order); revenue GROSS + fee beban; retur dua rasa dengan reason code; gerbang "FG layak jual" (Accepted + FG Store) dijaga di selector DN; scrap sale jalur sederhana tanpa batch/QC.
- Tolak: Quotation, Sales Partner, POS (konsisten Chapter A & Peta Menu).
- Hide & pantau: Product Bundle (hampers/paket) - angkat bila bisnis mulai jual bundel.
Chapter B tertutup. Siklus transaksi Sales berdiri dengan pola khasnya: rekap CSV → SO konsolidasi → DN ber-batch Accepted → SI revenue gross → settlement via deductions, plus retur dua rasa yang menjaga Quality tidak kebanjiran komplain subjektif.
Chapter C - Selling Settings
Mesin apa: ruang policy modul - single doctype (selling_settings) yang tidak mencatat transaksi, tapi menentukan boleh-tidaknya dan bagaimana seluruh aktivitas Chapter A-D terjadi. Wujud modul Administration BMP untuk domain penjualan, konsisten pola Accounts Settings dan Stock Settings.
Perilaku per kelompok policy:
- Integritas transaksi:
- validate_selling_price_list ⚠️ - wajib ada price list terpasang sebelum SO/SI bisa submit (mencegah "jual tanpa harga").
- maintain_same_rate_across_selling_transactions ⚠️ - toggle "rate SO, DN, SI harus sama". Default ON di BMP: rate tidak boleh berubah di tengah alur (konsisten simetri dengan Buying). Koreksi harga yang sah (penyesuaian admin fee marketplace) lewat baris diskon dengan alasan, bukan edit rate senyap.
- hide_tax_and_charges toggle ⚠️ - untuk user non-finance yang tidak perlu lihat rincian pajak di form jual.
- Allowance pengiriman:
- over_delivery_allowance & over_billing_allowance default 0, override eksplisit per item (pagar ketat dulu, kelonggaran diminta sadar). Konsisten dengan pola allowance over-receipt di Purchase & Stock.
- allow_zero_valuation_rate toggle ⚠️ - relevan hanya untuk item non-stok atau scrap sale; untuk FG parfum harus OFF.
- Retur & komplain:
- Reason code retur wajib - tanpa pilihan reason, analitik "kenapa barang kembali" buta. Dua rasa utama yang sudah kita kunci: Subjektif (aroma tidak cocok, tanpa QC) vs Objektif (cacat fisik, picu investigasi Quality).
- is_return workflow default ON - pola native ERPNext, cukup untuk skala BMP.
- Quotation & CRM (yang kita tolak):
- quotation_series & field terkait tetap ada di doctype tapi tidak terpakai (karena Quotation dibuang).
- enable_independent_camps_for_quotation_and_invoice ⚠️ - toggle enterprise yang tidak relevan.
- Reservasi & diskon:
- automatically_set_reserve_stock_on_so toggle ⚠️ - default OFF; reservasi manual via Stock Reservation Entry (Stock Chapter B) cukup untuk skala ini.
- allow_multiple_sales_orders_against_blanket_order - tidak relevan (Blanket Order juga dibuang).
Lintas domain: policy di sini menggerbangi semua penulis SO/DN/SI; maintain_same_rate bekerja berpasangan dengan kebijakan simetris di Buying Settings (Purchase Chapter C); allow_zero_valuation_rate memungkinkan scrap sale jalur sederhana (Chapter B); reason code retur menyambungkan alur retur ke Quality (investigasi batch) bila objektif.
Edge case:
- maintain_same_rate OFF = rate SO dan SI bisa berbeda tanpa warning; admin finance kesulitan menjelaskan selisih. Ini pilihan sadar, bukan default.
- Allowance 0 kaku untuk timbangan fisik (cairan parfum diukur volume) - namun karena DN berbasis unit (botol), 0 tepat; override hanya untuk kasus kemasan dengan toleransi dimensi.
- Reason code retur tidak diisi = klasifikasi subjektif/objektif tercampur; Quality kebanjiran komplain yang bukan masalah produksi, dan masalah produksi sesungguhnya terkubur.
- Mengubah default allowance di tengah jalan tidak retroaktif - DN/SI lama tetap pakai allowance saat dibuat (pola yang sama di semua modul Settings).
Delta v16 (subset register): validator allowance dipindah ke level settings (lebih ketat); permission fixes minor.
Catatan scope BMP:
- Adopsi penuh: pola single doctype policy; maintain_same_rate default ON (simetri Buying); allowance 0 + override per item; reason code retur wajib dengan dua rasa (subjektif/objektif).
- Keputusan desain BMP: allow_zero_valuation_rate OFF untuk FG parfum; reservasi toggle (tidak auto); CRM-family tidak dipakai.
- Adaptasi: reason code retur adalah custom field dropdown dengan opsi baku (Subjektif/Objektif/Botol Bocor/Salah Kirim/dll.) - keputusan yang konsisten dengan Peta Menu Rev3 "retur tanpa drama".
Chapter D - Reports
Mesin apa: mata dan telinga penjualan - serta jembatan audit ke Accounting dan Manufacturing. Laporan di sini adalah proyeksi on-the-fly dari SO/DN/SI dan Payment Ledger, bukan entitas tersimpan. Mereka menjawab empat pertanyaan owner: "channel mana yang menghasilkan uang?", "produk mana yang marginnya bagus?", "siapa yang belum bayar/settlement?", dan "batch mana yang sudah terkirim ke mana?"
Perilaku per laporan (di erpnext/selling/report/):
- Sales Analytics - laporan paling hidup untuk owner. Sumbu: per Customer (= per Channel) × per Item Group × per periode. Metrik: qty, amount, margin. Filter: Customer (=Channel), Sales Person (PIC), Item Group, rentang tanggal. Karena Customer di BMP = channel, laporan ini secara otomatis memberi gambaran kontribusi per channel & per PIC tanpa field custom.
- Gross Profit - revenue − COGS per baris transaksi. Sumber COGS = rate DN (yang membawa hasil roll-up Manufacturing). Perilaku: laba kotor per botol jujur karena HPP-nya sudah membawa biaya RM + overhead mixing + overhead filling. Filter per Customer, Item, periode. Ini laporan kunci untuk keputusan harga.
SISIPAN: Akses: metrik margin (Sales Analytics, Gross Profit) membaca kolom ter-Cloak (cogs, gross_profit) - hanya Owner/Finance; role IT tidak melihat margin (konsisten Security Layers v1.5).
- Customer Ledger / AR Aging - membaca Payment Ledger Entry (Accounting Chapter C), bukan GL - karena settlement marketplace butuh pasangan invoice↔pembayaran yang andal. Bucket umur jatuh tempo configurable. Perilaku: bagi marketplace, ini mengukur "berapa settlement yang belum cair"; bagi distributor, "berapa piutang yang menunggak". Dua entitas, satu alat.
- Batch-wise Sales History - senjata traceability CPKB. Pilih satu Batch ID → tampil semua DN/SI yang mengirim batch tersebut, ke channel mana, tanggal berapa, qty berapa. Ini melengkapi Batch Traceability di Manufacturing Chapter D dari sisi hilir. Auditor BPOM membuka dua laporan ini bersama-sama.
- Item Sales Report - per item: qty terjual, revenue, rata-rata rate jual. Filter periode, channel, Sales Person. Bahan untuk identifikasi SKU mass market vs niche.
- Sales Person Wise Transaction Summary - laporan kinerja per Admin Sales / PIC (Budi, Siti, Andi, Rina, Dedi). Menjawab "siapa yang mencatat penjualan apa dan berapa" - accountability report sesuai prinsip Chapter A. Bukan komisi (komisi dihitung di luar BMP); ini murni jejak input.
- Marketplace Settlement Report (BMP-native) - rekap per Customer (= per Channel) per periode: gross revenue (SI), payment diterima (Payment Entry), fee marketplace (deductions), outstanding. Laporan ini yang mengubah settlement marketplace dari "tebak-tebakan Excel" menjadi angka yang bisa diaudit. Ini laporan kunci untuk cash-flow UMKM marketplace.
Lintas domain: membaca SO/DN/SI (Chapter B); membaca COGS (Stock/Manufacturing); membaca Payment Ledger (Accounting C); Sales Person (Chapter A); batch (Manufacturing Chapter B); Sales Analytics bisa menembus ke My Attention bila ada channel dengan outstanding settlement melewati ambang (pola landing page konsisten).
Edge case:
- Sales Analytics berbohong bila ada SO yang belum di-DN/SI - laporan "sales booked" bukan "sales realized". Pastikan filter docstatus = 1 (submitted).
- Gross Profit terdistorsi bila update_stock di SI dipakai tanpa DN terpisah - COGS dihitung di SI, tapi tidak ada jejak pengiriman; laporan margin benar tapi jejak fisik hilang. Kebijakan BMP: SI tanpa update_stock, DN terpisah.
- AR Aging marketplace vs distributor tercampur dalam satu bucket - mitigasi: filter per Customer Group (Marketplace/Retail/Distributor) untuk analisis terpisah.
- Batch-wise Sales History hanya sejujur inheritance - validasi single-batch-per-run di Manufacturing Chapter B adalah pencegahan termurah.
- Marketplace Settlement Report butuh konsistensi antara SI (gross) dan deductions Payment Entry (fee); bila admin salah input fee ke akun beban biasa (bukan via deductions), laporan tidak akan match. Ini alasan deductions adalah jalur wajib, bukan opsi.
- Sales Person report dibaca sebagai "komisi" padahal hanya accountability - komunikasi eksplisit agar tidak memicu konflik internal; skema komisi hidup di luar BMP.
Delta v16 (subset register): optimasi performa report via snapshot closing (pola yang sama dengan Accounting Chapter F & Stock Chapter E); perbaikan permission/validasi minor ⚠️.
Catatan scope BMP:
- Adopsi penuh: Sales Analytics (per Customer/Channel + PIC), Gross Profit, Customer Ledger/AR Aging, Batch-wise Sales History, Item Sales Report, Sales Person Wise Summary.
- Keputusan desain BMP: Marketplace Settlement Report sebagai laporan native BMP - menjembatani SI gross dengan Payment Entry netto via deductions.
- Adaptasi UI: Customer Ledger + Settlement Report menembus ke My Attention bila outstanding > ambang (konsistensi pola landing page); semua laporan export xlsx satu klik.
Status keseluruhan BMP sekarang