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

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:

  1. 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:

Atribut & Linkage Kunci:

  1. 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).
  2. 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.

  1. 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:

Edge case:

  1. 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.
  2. 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.
  3. Customer disabled tapi punya SO terbuka = DN/SI lanjutan terblokir; disable wajib didahului penyelesaian order terbuka (pola yang sama dengan Supplier di Purchase).
  4. 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.
  5. 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:

  1. 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).
  2. 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.
  3. Tolak: Quotation, Lead/Opportunity/Campaign (CRM), Sales Partner - tidak ada pipeline penjualan dalam model marketplace; reseller hidup di sistem mereka sendiri.
  4. 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:

  1. Sales Order (erpnext/selling/doctype/sales_order/) - titik masuk rekap agregat.
  2. Delivery Note (milik Stock Chapter B; perilaku jual di sini) - momen fisik keluar.
  3. Sales Invoice (milik Accounting Chapter B; perilaku jual di sini) - momen revenue diakui.
  4. Settlement & Payment Entry Receive (milik Accounting Chapter C) - momen uang cair.

B.2 Tiga jalur lainnya (varian dari tulang punggung)

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

  1. Stock (Chapter B & D): DN menulis SLE out + COGS; gerbang batch Accepted + FG Store; Stock Reservation mencegah oversell multi-channel.
  2. Manufacturing (Chapter B): definisi "FG layak jual" (batch Accepted + FG Store) diwarisi; batch inheritance (FG = Bulk) membuat traceability CPKB nyambung sampai ke lot RM.
  3. Accounting (Chapter B & C): SI menulis GL revenue + AR; Payment Entry Receive menutup piutang via deductions (fee marketplace); PPN Keluaran dari Sales Taxes Template.
  4. Quality: hanya tersentuh oleh retur objektif (investigasi batch + Non Conformance) - sengaja tidak oleh retur subjektif.
  5. 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

  1. 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).
  2. 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.
  3. 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.
  4. Menjual batch yang belum lulus QC harus mustahil secara sistem (selector DN menyembunyikannya), bukan sekadar peringatan - ini gerbang CPKB.
  5. 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.
  6. 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).
  7. 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.
  8. 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)

Catatan scope BMP

  1. 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.
  2. 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.
  3. Tolak: Quotation, Sales Partner, POS (konsisten Chapter A & Peta Menu).
  4. 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:

  1. Integritas transaksi:
  2. Allowance pengiriman:
  3. Retur & komplain:
  4. Quotation & CRM (yang kita tolak):
  5. Reservasi & diskon:

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:

  1. maintain_same_rate OFF = rate SO dan SI bisa berbeda tanpa warning; admin finance kesulitan menjelaskan selisih. Ini pilihan sadar, bukan default.
  2. 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.
  3. Reason code retur tidak diisi = klasifikasi subjektif/objektif tercampur; Quality kebanjiran komplain yang bukan masalah produksi, dan masalah produksi sesungguhnya terkubur.
  4. 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:

  1. 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).
  2. Keputusan desain BMP: allow_zero_valuation_rate OFF untuk FG parfum; reservasi toggle (tidak auto); CRM-family tidak dipakai.
  3. 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/):

  1. 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.
  2. 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).

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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:

  1. Sales Analytics berbohong bila ada SO yang belum di-DN/SI - laporan "sales booked" bukan "sales realized". Pastikan filter docstatus = 1 (submitted).
  2. 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.
  3. AR Aging marketplace vs distributor tercampur dalam satu bucket - mitigasi: filter per Customer Group (Marketplace/Retail/Distributor) untuk analisis terpisah.
  4. Batch-wise Sales History hanya sejujur inheritance - validasi single-batch-per-run di Manufacturing Chapter B adalah pencegahan termurah.
  5. 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.
  6. 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:

  1. 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.
  2. Keputusan desain BMP: Marketplace Settlement Report sebagai laporan native BMP - menjembatani SI gross dengan Payment Entry netto via deductions.
  3. 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