mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-23 23:19:20 +00:00
Merge pull request #41575 from frappe/version-14-hotfix
chore: release v14
This commit is contained in:
@@ -74,15 +74,21 @@
|
|||||||
"discount_amount",
|
"discount_amount",
|
||||||
"discount_percentage",
|
"discount_percentage",
|
||||||
"for_price_list",
|
"for_price_list",
|
||||||
"section_break_13",
|
"dynamic_condition_tab",
|
||||||
"threshold_percentage",
|
|
||||||
"priority",
|
|
||||||
"condition",
|
"condition",
|
||||||
"column_break_66",
|
"section_break_13",
|
||||||
"apply_multiple_pricing_rules",
|
"apply_multiple_pricing_rules",
|
||||||
"apply_discount_on_rate",
|
"apply_discount_on_rate",
|
||||||
|
"column_break_66",
|
||||||
|
"threshold_percentage",
|
||||||
|
"validate_pricing_rule_section",
|
||||||
"validate_applied_rule",
|
"validate_applied_rule",
|
||||||
|
"column_break_texp",
|
||||||
"rule_description",
|
"rule_description",
|
||||||
|
"priority_section",
|
||||||
|
"has_priority",
|
||||||
|
"column_break_sayg",
|
||||||
|
"priority",
|
||||||
"help_section",
|
"help_section",
|
||||||
"pricing_rule_help",
|
"pricing_rule_help",
|
||||||
"reference_section",
|
"reference_section",
|
||||||
@@ -477,7 +483,7 @@
|
|||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "section_break_13",
|
"fieldname": "section_break_13",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Tab Break",
|
||||||
"label": "Advanced Settings"
|
"label": "Advanced Settings"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -487,6 +493,7 @@
|
|||||||
"label": "Threshold for Suggestion (In Percentage)"
|
"label": "Threshold for Suggestion (In Percentage)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "has_priority",
|
||||||
"description": "Higher the number, higher the priority",
|
"description": "Higher the number, higher the priority",
|
||||||
"fieldname": "priority",
|
"fieldname": "priority",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
@@ -513,6 +520,7 @@
|
|||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"depends_on": "eval:doc.price_or_product_discount == 'Price'",
|
"depends_on": "eval:doc.price_or_product_discount == 'Price'",
|
||||||
|
"description": "If enabled, then system will only validate the pricing rule and not apply automatically. User has to manually set the discount percentage / margin / free items to validate the pricing rule",
|
||||||
"fieldname": "validate_applied_rule",
|
"fieldname": "validate_applied_rule",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Validate Applied Rule"
|
"label": "Validate Applied Rule"
|
||||||
@@ -525,7 +533,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "help_section",
|
"fieldname": "help_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Tab Break",
|
||||||
|
"label": "Help Article",
|
||||||
"options": "Simple"
|
"options": "Simple"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -603,12 +612,42 @@
|
|||||||
"fieldname": "apply_recursion_over",
|
"fieldname": "apply_recursion_over",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Apply Recursion Over (As Per Transaction UOM)"
|
"label": "Apply Recursion Over (As Per Transaction UOM)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "priority_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Priority"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "dynamic_condition_tab",
|
||||||
|
"fieldtype": "Tab Break",
|
||||||
|
"label": "Dynamic Condition"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "validate_pricing_rule_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Validate Pricing Rule"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_texp",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_sayg",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "Enable this checkbox even if you want to set the zero priority",
|
||||||
|
"fieldname": "has_priority",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Has Priority"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-gift",
|
"icon": "fa fa-gift",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-02-14 04:53:34.887358",
|
"modified": "2024-05-17 13:16:34.496704",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Pricing Rule",
|
"name": "Pricing Rule",
|
||||||
|
|||||||
@@ -47,6 +47,12 @@ class PricingRule(Document):
|
|||||||
frappe.throw(_("Duplicate {0} found in the table").format(self.apply_on))
|
frappe.throw(_("Duplicate {0} found in the table").format(self.apply_on))
|
||||||
|
|
||||||
def validate_mandatory(self):
|
def validate_mandatory(self):
|
||||||
|
if self.has_priority and not self.priority:
|
||||||
|
throw(_("Priority is mandatory"), frappe.MandatoryError, _("Please Set Priority"))
|
||||||
|
|
||||||
|
if self.priority and not self.has_priority:
|
||||||
|
self.has_priority = 1
|
||||||
|
|
||||||
for apply_on, field in apply_on_dict.items():
|
for apply_on, field in apply_on_dict.items():
|
||||||
if self.apply_on == apply_on and len(self.get(field) or []) < 1:
|
if self.apply_on == apply_on and len(self.get(field) or []) < 1:
|
||||||
throw(_("{0} is not added in the table").format(apply_on), frappe.MandatoryError)
|
throw(_("{0} is not added in the table").format(apply_on), frappe.MandatoryError)
|
||||||
|
|||||||
@@ -1031,6 +1031,62 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
|
||||||
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
|
||||||
|
|
||||||
|
def test_priority_of_multiple_pricing_rules(self):
|
||||||
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
|
||||||
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
|
||||||
|
|
||||||
|
test_record = {
|
||||||
|
"doctype": "Pricing Rule",
|
||||||
|
"title": "_Test Pricing Rule 1",
|
||||||
|
"name": "_Test Pricing Rule 1",
|
||||||
|
"apply_on": "Item Code",
|
||||||
|
"currency": "USD",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"selling": 1,
|
||||||
|
"price_or_product_discount": "Price",
|
||||||
|
"rate_or_discount": "Discount Percentage",
|
||||||
|
"discount_percentage": 10,
|
||||||
|
"has_priority": 1,
|
||||||
|
"priority": 1,
|
||||||
|
"company": "_Test Company",
|
||||||
|
}
|
||||||
|
|
||||||
|
frappe.get_doc(test_record.copy()).insert()
|
||||||
|
|
||||||
|
test_record = {
|
||||||
|
"doctype": "Pricing Rule",
|
||||||
|
"title": "_Test Pricing Rule 2",
|
||||||
|
"name": "_Test Pricing Rule 2",
|
||||||
|
"apply_on": "Item Code",
|
||||||
|
"currency": "USD",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"selling": 1,
|
||||||
|
"price_or_product_discount": "Price",
|
||||||
|
"rate_or_discount": "Discount Percentage",
|
||||||
|
"discount_percentage": 20,
|
||||||
|
"has_priority": 1,
|
||||||
|
"priority": 3,
|
||||||
|
"company": "_Test Company",
|
||||||
|
}
|
||||||
|
|
||||||
|
frappe.get_doc(test_record.copy()).insert()
|
||||||
|
|
||||||
|
so = make_sales_order(item_code="_Test Item", qty=1, price_list_rate=1000, do_not_submit=True)
|
||||||
|
self.assertEqual(so.items[0].discount_percentage, 20)
|
||||||
|
self.assertEqual(so.items[0].rate, 800)
|
||||||
|
|
||||||
|
frappe.delete_doc_if_exists("Sales Order", so.name)
|
||||||
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
|
||||||
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
|
||||||
|
|
||||||
|
|
||||||
test_dependencies = ["Campaign"]
|
test_dependencies = ["Campaign"]
|
||||||
|
|
||||||
@@ -1059,6 +1115,7 @@ def make_pricing_rule(**args):
|
|||||||
"priority": args.priority or 1,
|
"priority": args.priority or 1,
|
||||||
"discount_amount": args.discount_amount or 0.0,
|
"discount_amount": args.discount_amount or 0.0,
|
||||||
"apply_multiple_pricing_rules": args.apply_multiple_pricing_rules or 0,
|
"apply_multiple_pricing_rules": args.apply_multiple_pricing_rules or 0,
|
||||||
|
"has_priority": args.has_priority or 0,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ def get_pricing_rules(args, doc=None):
|
|||||||
|
|
||||||
for apply_on in ["Item Code", "Item Group", "Brand"]:
|
for apply_on in ["Item Code", "Item Group", "Brand"]:
|
||||||
pricing_rules.extend(_get_pricing_rules(apply_on, args, values))
|
pricing_rules.extend(_get_pricing_rules(apply_on, args, values))
|
||||||
|
if pricing_rules and pricing_rules[0].has_priority:
|
||||||
|
continue
|
||||||
|
|
||||||
if pricing_rules and not apply_multiple_pricing_rules(pricing_rules):
|
if pricing_rules and not apply_multiple_pricing_rules(pricing_rules):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -440,8 +440,12 @@ function hide_fields(doc) {
|
|||||||
|
|
||||||
var item_fields_stock = ['warehouse_section', 'received_qty', 'rejected_qty'];
|
var item_fields_stock = ['warehouse_section', 'received_qty', 'rejected_qty'];
|
||||||
|
|
||||||
cur_frm.fields_dict['items'].grid.set_column_disp(item_fields_stock,
|
if (cur_frm.fields_dict["items"]) {
|
||||||
(cint(doc.update_stock)==1 || cint(doc.is_return)==1 ? true : false));
|
cur_frm.fields_dict["items"].grid.set_column_disp(
|
||||||
|
item_fields_stock,
|
||||||
|
cint(doc.update_stock) == 1 || cint(doc.is_return) == 1 ? true : false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
cur_frm.refresh_fields();
|
cur_frm.refresh_fields();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -982,7 +982,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
pr_items = frappe.get_all(
|
pr_items = frappe.get_all(
|
||||||
"Purchase Receipt Item",
|
"Purchase Receipt Item",
|
||||||
filters={"parent": ("in", linked_purchase_receipts)},
|
filters={"parent": ("in", linked_purchase_receipts)},
|
||||||
fields=["name", "provisional_expense_account", "qty", "base_rate"],
|
fields=["name", "provisional_expense_account", "qty", "base_rate", "rate"],
|
||||||
)
|
)
|
||||||
default_provisional_account = self.get_company_default("default_provisional_account")
|
default_provisional_account = self.get_company_default("default_provisional_account")
|
||||||
provisional_accounts = set(
|
provisional_accounts = set(
|
||||||
@@ -1010,6 +1010,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
"provisional_account": item.provisional_expense_account or default_provisional_account,
|
"provisional_account": item.provisional_expense_account or default_provisional_account,
|
||||||
"qty": item.qty,
|
"qty": item.qty,
|
||||||
"base_rate": item.base_rate,
|
"base_rate": item.base_rate,
|
||||||
|
"rate": item.rate,
|
||||||
"has_provisional_entry": item.name in rows_with_provisional_entries,
|
"has_provisional_entry": item.name in rows_with_provisional_entries,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1026,7 +1027,10 @@ class PurchaseInvoice(BuyingController):
|
|||||||
self.posting_date,
|
self.posting_date,
|
||||||
pr_item.get("provisional_account"),
|
pr_item.get("provisional_account"),
|
||||||
reverse=1,
|
reverse=1,
|
||||||
item_amount=(min(item.qty, pr_item.get("qty")) * pr_item.get("base_rate")),
|
item_amount=(
|
||||||
|
(min(item.qty, pr_item.get("qty")) * pr_item.get("rate"))
|
||||||
|
* purchase_receipt_doc.get("conversion_rate")
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_gross_purchase_amount_for_linked_assets(self, item):
|
def update_gross_purchase_amount_for_linked_assets(self, item):
|
||||||
|
|||||||
@@ -211,7 +211,8 @@ def get_conditions(filters):
|
|||||||
|
|
||||||
if filters.get("account"):
|
if filters.get("account"):
|
||||||
filters.account = get_accounts_with_children(filters.account)
|
filters.account = get_accounts_with_children(filters.account)
|
||||||
conditions.append("account in %(account)s")
|
if filters.account:
|
||||||
|
conditions.append("account in %(account)s")
|
||||||
|
|
||||||
if filters.get("cost_center"):
|
if filters.get("cost_center"):
|
||||||
filters.cost_center = get_cost_centers_with_children(filters.cost_center)
|
filters.cost_center = get_cost_centers_with_children(filters.cost_center)
|
||||||
@@ -316,7 +317,7 @@ def get_accounts_with_children(accounts):
|
|||||||
else:
|
else:
|
||||||
frappe.throw(_("Account: {0} does not exist").format(d))
|
frappe.throw(_("Account: {0} does not exist").format(d))
|
||||||
|
|
||||||
return list(set(all_accounts))
|
return list(set(all_accounts)) if all_accounts else None
|
||||||
|
|
||||||
|
|
||||||
def get_data_with_opening_closing(filters, account_details, accounting_dimensions, gl_entries):
|
def get_data_with_opening_closing(filters, account_details, accounting_dimensions, gl_entries):
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ def get_exploded_items(bom, data, indent=0, qty=1):
|
|||||||
exploded_items = frappe.get_all(
|
exploded_items = frappe.get_all(
|
||||||
"BOM Item",
|
"BOM Item",
|
||||||
filters={"parent": bom},
|
filters={"parent": bom},
|
||||||
fields=["qty", "bom_no", "qty", "item_code", "item_name", "description", "uom"],
|
fields=["qty", "bom_no", "qty", "item_code", "item_name", "description", "uom", "idx"],
|
||||||
|
order_by="idx ASC",
|
||||||
)
|
)
|
||||||
|
|
||||||
for item in exploded_items:
|
for item in exploded_items:
|
||||||
|
|||||||
@@ -362,4 +362,5 @@ erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index # 2
|
|||||||
erpnext.patches.v14_0.set_maintain_stock_for_bom_item
|
erpnext.patches.v14_0.set_maintain_stock_for_bom_item
|
||||||
execute:frappe.db.set_single_value('E Commerce Settings', 'show_actual_qty', 1)
|
execute:frappe.db.set_single_value('E Commerce Settings', 'show_actual_qty', 1)
|
||||||
erpnext.patches.v14_0.delete_orphaned_asset_movement_item_records
|
erpnext.patches.v14_0.delete_orphaned_asset_movement_item_records
|
||||||
erpnext.patches.v14_0.remove_cancelled_asset_capitalization_from_asset
|
erpnext.patches.v14_0.remove_cancelled_asset_capitalization_from_asset
|
||||||
|
erpnext.patches.v14_0.enable_set_priority_for_pricing_rules #1
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
pr_table = frappe.qb.DocType("Pricing Rule")
|
||||||
|
(
|
||||||
|
frappe.qb.update(pr_table)
|
||||||
|
.set(pr_table.has_priority, 1)
|
||||||
|
.where((pr_table.priority.isnotnull()) & (pr_table.priority != ""))
|
||||||
|
).run()
|
||||||
@@ -5,7 +5,7 @@ import copy
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _, bold
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import (
|
from frappe.utils import (
|
||||||
cint,
|
cint,
|
||||||
@@ -397,6 +397,13 @@ class Item(Document):
|
|||||||
def validate_warehouse_for_reorder(self):
|
def validate_warehouse_for_reorder(self):
|
||||||
"""Validate Reorder level table for duplicate and conditional mandatory"""
|
"""Validate Reorder level table for duplicate and conditional mandatory"""
|
||||||
warehouse_material_request_type: list[tuple[str, str]] = []
|
warehouse_material_request_type: list[tuple[str, str]] = []
|
||||||
|
|
||||||
|
_warehouse_before_save = frappe._dict()
|
||||||
|
if not self.is_new() and self._doc_before_save:
|
||||||
|
_warehouse_before_save = {
|
||||||
|
d.name: d.warehouse for d in self._doc_before_save.get("reorder_levels") or []
|
||||||
|
}
|
||||||
|
|
||||||
for d in self.get("reorder_levels"):
|
for d in self.get("reorder_levels"):
|
||||||
if not d.warehouse_group:
|
if not d.warehouse_group:
|
||||||
d.warehouse_group = d.warehouse
|
d.warehouse_group = d.warehouse
|
||||||
@@ -413,6 +420,19 @@ class Item(Document):
|
|||||||
if d.warehouse_reorder_level and not d.warehouse_reorder_qty:
|
if d.warehouse_reorder_level and not d.warehouse_reorder_qty:
|
||||||
frappe.throw(_("Row #{0}: Please set reorder quantity").format(d.idx))
|
frappe.throw(_("Row #{0}: Please set reorder quantity").format(d.idx))
|
||||||
|
|
||||||
|
if d.warehouse_group and d.warehouse:
|
||||||
|
if _warehouse_before_save.get(d.name) == d.warehouse:
|
||||||
|
continue
|
||||||
|
|
||||||
|
child_warehouses = get_child_warehouses(d.warehouse_group)
|
||||||
|
if d.warehouse not in child_warehouses:
|
||||||
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"Row #{0}: The warehouse {1} is not a child warehouse of a group warehouse {2}"
|
||||||
|
).format(d.idx, bold(d.warehouse), bold(d.warehouse_group)),
|
||||||
|
title=_("Incorrect Check in (group) Warehouse for Reorder"),
|
||||||
|
)
|
||||||
|
|
||||||
def stock_ledger_created(self):
|
def stock_ledger_created(self):
|
||||||
if not hasattr(self, "_stock_ledger_created"):
|
if not hasattr(self, "_stock_ledger_created"):
|
||||||
self._stock_ledger_created = len(
|
self._stock_ledger_created = len(
|
||||||
@@ -1318,3 +1338,10 @@ def get_asset_naming_series():
|
|||||||
from erpnext.assets.doctype.asset.asset import get_asset_naming_series
|
from erpnext.assets.doctype.asset.asset import get_asset_naming_series
|
||||||
|
|
||||||
return get_asset_naming_series()
|
return get_asset_naming_series()
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.request_cache
|
||||||
|
def get_child_warehouses(warehouse):
|
||||||
|
from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
|
||||||
|
|
||||||
|
return get_child_warehouses(warehouse)
|
||||||
|
|||||||
@@ -848,6 +848,27 @@ class TestItem(FrappeTestCase):
|
|||||||
self.assertEqual(data[0].description, item.description)
|
self.assertEqual(data[0].description, item.description)
|
||||||
self.assertTrue("description" in data[0])
|
self.assertTrue("description" in data[0])
|
||||||
|
|
||||||
|
def test_group_warehouse_for_reorder_item(self):
|
||||||
|
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||||
|
|
||||||
|
item_doc = make_item("_Test Group Warehouse For Reorder Item", {"is_stock_item": 1})
|
||||||
|
warehouse = create_warehouse("_Test Warehouse - _TC")
|
||||||
|
warehouse_doc = frappe.get_doc("Warehouse", warehouse)
|
||||||
|
warehouse_doc.db_set("parent_warehouse", "")
|
||||||
|
|
||||||
|
item_doc.append(
|
||||||
|
"reorder_levels",
|
||||||
|
{
|
||||||
|
"warehouse": warehouse,
|
||||||
|
"warehouse_reorder_level": 10,
|
||||||
|
"warehouse_reorder_qty": 100,
|
||||||
|
"material_request_type": "Purchase",
|
||||||
|
"warehouse_group": "_Test Warehouse Group - _TC",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertRaises(frappe.ValidationError, item_doc.save)
|
||||||
|
|
||||||
|
|
||||||
def set_item_variant_settings(fields):
|
def set_item_variant_settings(fields):
|
||||||
doc = frappe.get_doc("Item Variant Settings")
|
doc = frappe.get_doc("Item Variant Settings")
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<div class="row">
|
<div class="row {% if df.bold %}important{% endif %} data-field">
|
||||||
{% if doc.flags.show_inclusive_tax_in_print %}
|
{% if doc.flags.show_inclusive_tax_in_print %}
|
||||||
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
|
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
|
||||||
<label>{{ _("Total (Without Tax)") }}</label></div>
|
<label>{{ _("Total (Without Tax)") }}</label></div>
|
||||||
<div class="col-xs-7 text-right">
|
<div class="col-xs-7 text-right value">
|
||||||
{{ doc.get_formatted("net_total", doc) }}
|
{{ doc.get_formatted("net_total", doc) }}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
|
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
|
||||||
<label>{{ _(df.label) }}</label></div>
|
<label>{{ _(df.label) }}</label></div>
|
||||||
<div class="col-xs-7 text-right">
|
<div class="col-xs-7 text-right value">
|
||||||
{{ doc.get_formatted("total", doc) }}
|
{{ doc.get_formatted("total", doc) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
Reference in New Issue
Block a user