Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions rmax_custom/api/delivery_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,13 @@ def _build_consolidated_standard_si(dns, buckets):
si.customer_name = head.customer_name
si.company = head.company
si.currency = head.currency
# Carry the source DN's price list (e.g. "Inter Company Price") onto the SI.
# Without this the SI falls back to the customer/default selling price list
# (e.g. "Retail Price"), which mismatches the DNs. Item rates are still set
# explicitly from the netted DN amounts below, so this only fixes the
# price-list field + price_list_rate, it does not re-price the invoice.
if head.get("selling_price_list"):
si.selling_price_list = head.selling_price_list
si.posting_date = frappe.utils.today()
si.set_posting_time = 1
si.update_stock = 0
Expand Down
32 changes: 32 additions & 0 deletions rmax_custom/public/js/sales_invoice_doctype.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,35 @@ function _rmax_apply_branch_payment_accounts(frm, cdt, cdn) {
});
}

// ---------------------------------------------------------------------------
// Consolidated Delivery Notes link (SI → source DNs)
// ---------------------------------------------------------------------------
// Net-off consolidation links the source DNs to this SI via the custom field
// `custom_consolidated_si` (the standard SI→DN item link is intentionally
// omitted — merged/netted rows can't map to a single DN row), so the
// Connections tab cannot surface them. This button gives the SI → source-DN
// navigation. The DN → SI direction already works via the DN's
// "Consolidated Sales Invoice" field.
frappe.ui.form.on("Sales Invoice", {
refresh: function (frm) {
if (frm.is_new()) return;
frappe.db
.count("Delivery Note", {
filters: { custom_consolidated_si: frm.doc.name },
})
.then(function (n) {
if (n) {
frm.add_custom_button(
__("Delivery Notes ({0})", [n]),
function () {
frappe.set_route("List", "Delivery Note", {
custom_consolidated_si: frm.doc.name,
});
},
__("View")
);
}
});
},
});

29 changes: 29 additions & 0 deletions rmax_custom/tests/test_dn_consolidation.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,24 @@ def test_clubbed_dn_billing_status_flips_on_submit_and_reverts(self):
dn.reload()
self.assertEqual(dn.status, "To Bill")

def test_consolidated_si_inherits_dn_price_list(self):
# Consolidated SI must carry the source DN's selling price list (e.g.
# "Inter Company Price"), not fall back to the customer/default list.
pl = _ensure_selling_price_list("RMAX Consol PL")
dn = frappe.new_doc("Delivery Note")
dn.customer = self.customer
dn.company = self.company
dn.set_warehouse = self.warehouse
dn.selling_price_list = pl
dn.append("items", {
"item_code": self.item, "qty": 3, "rate": 10,
"warehouse": self.warehouse, "uom": "Nos",
})
dn.insert(ignore_permissions=True)
dn.submit()
si = frappe.get_doc("Sales Invoice", consolidate_dns_to_si([dn.name]))
self.assertEqual(si.selling_price_list, pl)

def test_draft_si_delete_clears_stamp_and_succeeds(self):
# Reproduces the bug: a DRAFT consolidated SI stamps the DN via
# custom_consolidated_si; deleting it must clear the stamp (on_trash)
Expand Down Expand Up @@ -150,6 +168,17 @@ def _ensure_item(item_code):
return i.name


def _ensure_selling_price_list(name):
if not frappe.db.exists("Price List", name):
pl = frappe.new_doc("Price List")
pl.price_list_name = name
pl.selling = 1
pl.enabled = 1
pl.currency = "SAR"
pl.insert(ignore_permissions=True)
return name


def _pick_default_company():
return frappe.db.get_single_value("Global Defaults", "default_company") \
or frappe.db.get_value("Company", {}, "name")
Expand Down
Loading