diff --git a/erpnext/public/js/sales_order_proforma.js b/erpnext/public/js/sales_order_proforma.js
index 3363ffefc66..314e0e803ec 100644
--- a/erpnext/public/js/sales_order_proforma.js
+++ b/erpnext/public/js/sales_order_proforma.js
@@ -93,6 +93,12 @@ Object.assign(erpnext.proforma, {
default: "Quantity",
onchange: () => this.toggle_basis(dialog),
},
+ {
+ fieldname: "hide_item_qty",
+ fieldtype: "Check",
+ label: __("Hide Item Quantity in Print"),
+ depends_on: 'eval:doc.based_on=="Amount"',
+ },
{
fieldname: "items",
fieldtype: "Table",
@@ -212,6 +218,7 @@ Object.assign(erpnext.proforma, {
sales_order: frm.doc.name,
items: JSON.stringify(items),
based_on: values.based_on,
+ hide_item_qty: values.hide_item_qty ? 1 : 0,
naming_series: values.naming_series,
print_format: values.print_format,
letter_head: values.letter_head,
diff --git a/erpnext/selling/doctype/proforma_invoice/proforma_invoice.json b/erpnext/selling/doctype/proforma_invoice/proforma_invoice.json
index a8d6e035015..3b698d6d1bb 100644
--- a/erpnext/selling/doctype/proforma_invoice/proforma_invoice.json
+++ b/erpnext/selling/doctype/proforma_invoice/proforma_invoice.json
@@ -14,6 +14,7 @@
"company",
"currency",
"based_on",
+ "hide_item_qty",
"items_section",
"items",
"total_qty",
@@ -105,6 +106,15 @@
"options": "Quantity\nAmount",
"read_only": 1
},
+ {
+ "default": "0",
+ "depends_on": "eval:doc.based_on==\"Amount\"",
+ "description": "Hide the item quantity and rate on the printed proforma.",
+ "fieldname": "hide_item_qty",
+ "fieldtype": "Check",
+ "label": "Hide Item Quantity in Print",
+ "read_only": 1
+ },
{
"fieldname": "items_section",
"fieldtype": "Section Break",
diff --git a/erpnext/selling/doctype/proforma_invoice/proforma_invoice.py b/erpnext/selling/doctype/proforma_invoice/proforma_invoice.py
index 956dcbc0b10..d633c7426d0 100644
--- a/erpnext/selling/doctype/proforma_invoice/proforma_invoice.py
+++ b/erpnext/selling/doctype/proforma_invoice/proforma_invoice.py
@@ -30,6 +30,7 @@ class ProformaInvoice(Document):
customer_name: DF.Data | None
emailed_to: DF.SmallText | None
grand_total: DF.Currency
+ hide_item_qty: DF.Check
items: DF.Table[ProformaInvoiceItem]
letter_head: DF.Link | None
naming_series: DF.Literal["PRO-.YYYY.-"]
@@ -84,6 +85,7 @@ class ProformaInvoice(Document):
sales_order.run_method("calculate_taxes_and_totals")
sales_order.proforma_no = self.name
sales_order.proforma_date = self.proforma_date
+ sales_order.hide_item_qty = self.hide_item_qty
self.db_set("grand_total", sales_order.grand_total)
return frappe.attach_print(
"Sales Order",
@@ -138,6 +140,7 @@ def make_proforma_invoice(
sales_order: str,
items: str,
based_on: str = "Quantity",
+ hide_item_qty: bool | int = 0,
naming_series: str | None = None,
print_format: str | None = None,
letter_head: str | None = None,
@@ -145,7 +148,8 @@ def make_proforma_invoice(
"""The sole creation path for a Proforma Invoice (the doctype is `in_create`).
`based_on` decides what the user edited per line: "Quantity" (rate fixed, amount = qty x rate)
- or "Amount" (qty fixed at ordered, rate derived so the line totals the entered amount).
+ or "Amount" (both qty and amount entered, rate derived). `hide_item_qty` (Amount basis only)
+ hides the qty and rate on the printed proforma for a clean value-based document.
"""
validate_feature_enabled()
selected = frappe.parse_json(items)
@@ -155,6 +159,7 @@ def make_proforma_invoice(
proforma = frappe.new_doc("Proforma Invoice")
proforma.sales_order = sales_order
proforma.based_on = based_on
+ proforma.hide_item_qty = 1 if (based_on == "Amount" and int(hide_item_qty or 0)) else 0
if naming_series:
proforma.naming_series = naming_series
proforma.print_format = print_format or frappe.db.get_single_value(
diff --git a/erpnext/selling/doctype/proforma_invoice/test_proforma_invoice.py b/erpnext/selling/doctype/proforma_invoice/test_proforma_invoice.py
index 5ab30691208..a5e1789bb85 100644
--- a/erpnext/selling/doctype/proforma_invoice/test_proforma_invoice.py
+++ b/erpnext/selling/doctype/proforma_invoice/test_proforma_invoice.py
@@ -112,6 +112,27 @@ class TestProformaInvoice(ERPNextTestSuite):
self.assertEqual(flt(data["proformed_qty"]), 3)
self.assertEqual(flt(data["proformed_amount"]), 300)
+ def test_hide_item_qty_only_applies_to_amount_basis(self):
+ sales_order = make_sales_order(qty=10)
+ so_detail = sales_order.items[0].name
+
+ amount_based = make_proforma_invoice(
+ sales_order.name,
+ json.dumps([{"so_detail": so_detail, "qty": 5, "amount": 250}]),
+ based_on="Amount",
+ hide_item_qty=1,
+ )
+ self.assertEqual(frappe.db.get_value("Proforma Invoice", amount_based, "hide_item_qty"), 1)
+
+ # ignored outside Amount basis
+ qty_based = make_proforma_invoice(
+ sales_order.name,
+ json.dumps([{"so_detail": so_detail, "qty": 4}]),
+ based_on="Quantity",
+ hide_item_qty=1,
+ )
+ self.assertEqual(frappe.db.get_value("Proforma Invoice", qty_based, "hide_item_qty"), 0)
+
def test_feature_toggle_is_enforced(self):
sales_order = make_sales_order(qty=10)
frappe.db.set_single_value("Selling Settings", "enable_proforma_invoice", 0)
diff --git a/erpnext/selling/print_format/proforma_invoice/proforma_invoice.json b/erpnext/selling/print_format/proforma_invoice/proforma_invoice.json
index 52417275cdf..8ef8184928d 100644
--- a/erpnext/selling/print_format/proforma_invoice/proforma_invoice.json
+++ b/erpnext/selling/print_format/proforma_invoice/proforma_invoice.json
@@ -9,7 +9,7 @@
"docstatus": 0,
"doctype": "Print Format",
"font_size": 0,
- "html": "
\n",
+ "html": "\n",
"idx": 0,
"line_breaks": 0,
"margin_bottom": 15.0,