fix: `Blanket Order` (backport #34279) (#34548) * fix: hide `+` button based on `Blanket Order Type` (cherry picked from commitabf9a28d6a) * feat: add field `Over Order Allowance (%)` in `Buying Settings` (cherry picked from commitf5937f46cb) # Conflicts: # erpnext/buying/doctype/buying_settings/buying_settings.json * refactor: rewrite `blanket_order.py` queries in `QB` (cherry picked from commitf3993783a3) * fix: don't map item row having `0` qty (cherry picked from commitfc1088d9c4) * feat: consider `over_order_allowance` while validating order qty (cherry picked from commit8bcbc45add) # Conflicts: # erpnext/buying/doctype/purchase_order/purchase_order.py * feat: add field `Over Order Allowance (%)` in `Selling Settings` (cherry picked from commitd7da8928ac) # Conflicts: # erpnext/selling/doctype/selling_settings/selling_settings.json * feat: consider `over_order_allowance` while validating sales order qty (cherry picked from commit53701c37b1) # Conflicts: # erpnext/buying/doctype/purchase_order/purchase_order.py * test: add test cases for `Over Order Allowance` against `Blanket Order` (cherry picked from commit66f650061d) * chore: `conflicts` --------- Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com> (cherry picked from commit8ddbac5158) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
"column_break_3",
|
||||
"po_required",
|
||||
"pr_required",
|
||||
"over_order_allowance",
|
||||
"maintain_same_rate",
|
||||
"allow_multiple_items",
|
||||
"bill_for_rejected_quantity_in_purchase_invoice",
|
||||
@@ -42,57 +43,6 @@
|
||||
"label": "Default Buying Price List",
|
||||
"options": "Price List"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "po_required",
|
||||
"fieldtype": "Select",
|
||||
"label": "Is Purchase Order Required for Purchase Invoice & Receipt Creation?",
|
||||
"options": "No\nYes"
|
||||
},
|
||||
{
|
||||
"fieldname": "pr_required",
|
||||
"fieldtype": "Select",
|
||||
"label": "Is Purchase Receipt Required for Purchase Invoice Creation?",
|
||||
"options": "No\nYes"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "maintain_same_rate",
|
||||
"fieldtype": "Check",
|
||||
"label": "Maintain Same Rate Throughout the Purchase Cycle"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "allow_multiple_items",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow Item To Be Added Multiple Times in a Transaction"
|
||||
},
|
||||
{
|
||||
"fieldname": "subcontract",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Subcontract"
|
||||
},
|
||||
{
|
||||
"default": "Material Transferred for Subcontract",
|
||||
"fieldname": "backflush_raw_materials_of_subcontract_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Backflush Raw Materials of Subcontract Based On",
|
||||
"options": "BOM\nMaterial Transferred for Subcontract"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.backflush_raw_materials_of_subcontract_based_on == \"BOM\"",
|
||||
"description": "Percentage you are allowed to transfer more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to transfer 110 units.",
|
||||
"fieldname": "over_transfer_allowance",
|
||||
"fieldtype": "Float",
|
||||
"label": "Over Transfer Allowance (%)"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "Stop",
|
||||
"depends_on": "maintain_same_rate",
|
||||
@@ -110,12 +60,70 @@
|
||||
"label": "Role Allowed to Override Stop Action",
|
||||
"options": "Role"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "po_required",
|
||||
"fieldtype": "Select",
|
||||
"label": "Is Purchase Order Required for Purchase Invoice & Receipt Creation?",
|
||||
"options": "No\nYes"
|
||||
},
|
||||
{
|
||||
"fieldname": "pr_required",
|
||||
"fieldtype": "Select",
|
||||
"label": "Is Purchase Receipt Required for Purchase Invoice Creation?",
|
||||
"options": "No\nYes"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Percentage you are allowed to order more against the Blanket Order Quantity. For example: If you have a Blanket Order of Quantity 100 units. and your Allowance is 10% then you are allowed to order 110 units.",
|
||||
"fieldname": "over_order_allowance",
|
||||
"fieldtype": "Float",
|
||||
"label": "Over Order Allowance (%)"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "maintain_same_rate",
|
||||
"fieldtype": "Check",
|
||||
"label": "Maintain Same Rate Throughout the Purchase Cycle"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "allow_multiple_items",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow Item To Be Added Multiple Times in a Transaction"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "If checked, Rejected Quantity will be included while making Purchase Invoice from Purchase Receipt.",
|
||||
"fieldname": "bill_for_rejected_quantity_in_purchase_invoice",
|
||||
"fieldtype": "Check",
|
||||
"label": "Bill for Rejected Quantity in Purchase Invoice"
|
||||
},
|
||||
{
|
||||
"fieldname": "subcontract",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Subcontract"
|
||||
},
|
||||
{
|
||||
"default": "Material Transferred for Subcontract",
|
||||
"fieldname": "backflush_raw_materials_of_subcontract_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Backflush Raw Materials of Subcontract Based On",
|
||||
"options": "BOM\nMaterial Transferred for Subcontract"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.backflush_raw_materials_of_subcontract_based_on == \"BOM\"",
|
||||
"description": "Percentage you are allowed to transfer more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to transfer 110 units.",
|
||||
"fieldname": "over_transfer_allowance",
|
||||
"fieldtype": "Float",
|
||||
"label": "Over Transfer Allowance (%)"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-cog",
|
||||
@@ -123,7 +131,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2021-09-08 19:26:23.548837",
|
||||
"modified": "2023-03-22 13:01:49.640869",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Buying Settings",
|
||||
|
||||
@@ -21,6 +21,9 @@ from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category
|
||||
from erpnext.accounts.party import get_party_account, get_party_account_currency
|
||||
from erpnext.buying.utils import check_on_hold_or_closed_status, validate_for_items
|
||||
from erpnext.controllers.buying_controller import BuyingController
|
||||
from erpnext.manufacturing.doctype.blanket_order.blanket_order import (
|
||||
validate_against_blanket_order,
|
||||
)
|
||||
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
||||
from erpnext.stock.doctype.item.item import get_item_defaults, get_last_purchase_details
|
||||
from erpnext.stock.stock_balance import get_ordered_qty, update_bin_qty
|
||||
@@ -72,6 +75,7 @@ class PurchaseOrder(BuyingController):
|
||||
self.validate_bom_for_subcontracting_items()
|
||||
self.create_raw_materials_supplied("supplied_items")
|
||||
self.set_received_qty_for_drop_ship_items()
|
||||
validate_against_blanket_order(self)
|
||||
validate_inter_company_party(
|
||||
self.doctype, self.supplier, self.company, self.inter_company_order_reference
|
||||
)
|
||||
|
||||
@@ -7,6 +7,12 @@ frappe.ui.form.on('Blanket Order', {
|
||||
},
|
||||
|
||||
setup: function(frm) {
|
||||
frm.custom_make_buttons = {
|
||||
'Purchase Order': 'Purchase Order',
|
||||
'Sales Order': 'Sales Order',
|
||||
'Quotation': 'Quotation',
|
||||
};
|
||||
|
||||
frm.add_fetch("customer", "customer_name", "customer_name");
|
||||
frm.add_fetch("supplier", "supplier_name", "supplier_name");
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@ import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from frappe.query_builder.functions import Sum
|
||||
from frappe.utils import flt, getdate
|
||||
|
||||
from erpnext.stock.doctype.item.item import get_item_defaults
|
||||
@@ -29,21 +30,23 @@ class BlanketOrder(Document):
|
||||
|
||||
def update_ordered_qty(self):
|
||||
ref_doctype = "Sales Order" if self.blanket_order_type == "Selling" else "Purchase Order"
|
||||
|
||||
trans = frappe.qb.DocType(ref_doctype)
|
||||
trans_item = frappe.qb.DocType(f"{ref_doctype} Item")
|
||||
|
||||
item_ordered_qty = frappe._dict(
|
||||
frappe.db.sql(
|
||||
"""
|
||||
select trans_item.item_code, sum(trans_item.stock_qty) as qty
|
||||
from `tab{0} Item` trans_item, `tab{0}` trans
|
||||
where trans.name = trans_item.parent
|
||||
and trans_item.blanket_order=%s
|
||||
and trans.docstatus=1
|
||||
and trans.status not in ('Closed', 'Stopped')
|
||||
group by trans_item.item_code
|
||||
""".format(
|
||||
ref_doctype
|
||||
),
|
||||
self.name,
|
||||
)
|
||||
(
|
||||
frappe.qb.from_(trans_item)
|
||||
.from_(trans)
|
||||
.select(trans_item.item_code, Sum(trans_item.stock_qty).as_("qty"))
|
||||
.where(
|
||||
(trans.name == trans_item.parent)
|
||||
& (trans_item.blanket_order == self.name)
|
||||
& (trans.docstatus == 1)
|
||||
& (trans.status.notin(["Stopped", "Closed"]))
|
||||
)
|
||||
.groupby(trans_item.item_code)
|
||||
).run()
|
||||
)
|
||||
|
||||
for d in self.items:
|
||||
@@ -79,7 +82,43 @@ def make_order(source_name):
|
||||
"doctype": doctype + " Item",
|
||||
"field_map": {"rate": "blanket_order_rate", "parent": "blanket_order"},
|
||||
"postprocess": update_item,
|
||||
"condition": lambda item: (flt(item.qty) - flt(item.ordered_qty)) > 0,
|
||||
},
|
||||
},
|
||||
)
|
||||
return target_doc
|
||||
|
||||
|
||||
def validate_against_blanket_order(order_doc):
|
||||
if order_doc.doctype in ("Sales Order", "Purchase Order"):
|
||||
order_data = {}
|
||||
|
||||
for item in order_doc.get("items"):
|
||||
if item.against_blanket_order and item.blanket_order:
|
||||
if item.blanket_order in order_data:
|
||||
if item.item_code in order_data[item.blanket_order]:
|
||||
order_data[item.blanket_order][item.item_code] += item.qty
|
||||
else:
|
||||
order_data[item.blanket_order][item.item_code] = item.qty
|
||||
else:
|
||||
order_data[item.blanket_order] = {item.item_code: item.qty}
|
||||
|
||||
if order_data:
|
||||
allowance = flt(
|
||||
frappe.db.get_single_value(
|
||||
"Selling Settings" if order_doc.doctype == "Sales Order" else "Buying Settings",
|
||||
"over_order_allowance",
|
||||
)
|
||||
)
|
||||
for bo_name, item_data in order_data.items():
|
||||
bo_doc = frappe.get_doc("Blanket Order", bo_name)
|
||||
for item in bo_doc.get("items"):
|
||||
if item.item_code in item_data:
|
||||
remaining_qty = item.qty - item.ordered_qty
|
||||
allowed_qty = remaining_qty + (remaining_qty * (allowance / 100))
|
||||
if allowed_qty < item_data[item.item_code]:
|
||||
frappe.throw(
|
||||
_("Item {0} cannot be ordered more than {1} against Blanket Order {2}.").format(
|
||||
item.item_code, allowed_qty, bo_name
|
||||
)
|
||||
)
|
||||
|
||||
@@ -63,6 +63,33 @@ class TestBlanketOrder(FrappeTestCase):
|
||||
po1.currency = get_company_currency(po1.company)
|
||||
self.assertEqual(po1.items[0].qty, (bo.items[0].qty - bo.items[0].ordered_qty))
|
||||
|
||||
def test_over_order_allowance(self):
|
||||
# Sales Order
|
||||
bo = make_blanket_order(blanket_order_type="Selling", quantity=100)
|
||||
|
||||
frappe.flags.args.doctype = "Sales Order"
|
||||
so = make_order(bo.name)
|
||||
so.currency = get_company_currency(so.company)
|
||||
so.delivery_date = today()
|
||||
so.items[0].qty = 110
|
||||
self.assertRaises(frappe.ValidationError, so.submit)
|
||||
|
||||
frappe.db.set_single_value("Selling Settings", "over_order_allowance", 10)
|
||||
so.submit()
|
||||
|
||||
# Purchase Order
|
||||
bo = make_blanket_order(blanket_order_type="Purchasing", quantity=100)
|
||||
|
||||
frappe.flags.args.doctype = "Purchase Order"
|
||||
po = make_order(bo.name)
|
||||
po.currency = get_company_currency(po.company)
|
||||
po.schedule_date = today()
|
||||
po.items[0].qty = 110
|
||||
self.assertRaises(frappe.ValidationError, po.submit)
|
||||
|
||||
frappe.db.set_single_value("Buying Settings", "over_order_allowance", 10)
|
||||
po.submit()
|
||||
|
||||
|
||||
def make_blanket_order(**args):
|
||||
args = frappe._dict(args)
|
||||
|
||||
@@ -22,6 +22,9 @@ from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
|
||||
)
|
||||
from erpnext.accounts.party import get_party_account
|
||||
from erpnext.controllers.selling_controller import SellingController
|
||||
from erpnext.manufacturing.doctype.blanket_order.blanket_order import (
|
||||
validate_against_blanket_order,
|
||||
)
|
||||
from erpnext.manufacturing.doctype.production_plan.production_plan import (
|
||||
get_items_for_material_requests,
|
||||
)
|
||||
@@ -53,6 +56,7 @@ class SalesOrder(SellingController):
|
||||
self.validate_warehouse()
|
||||
self.validate_drop_ship()
|
||||
self.validate_serial_no_based_delivery()
|
||||
validate_against_blanket_order(self)
|
||||
validate_inter_company_party(
|
||||
self.doctype, self.customer, self.company, self.inter_company_order_reference
|
||||
)
|
||||
|
||||
@@ -30,12 +30,18 @@
|
||||
"so_required",
|
||||
"dn_required",
|
||||
"sales_update_frequency",
|
||||
"over_order_allowance",
|
||||
"allow_multiple_items",
|
||||
"allow_against_multiple_purchase_orders",
|
||||
"hide_tax_id",
|
||||
"allow_sales_order_creation_for_expired_quotation"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "customer_defaults_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Customer Defaults"
|
||||
},
|
||||
{
|
||||
"default": "Customer Name",
|
||||
"fieldname": "cust_master_name",
|
||||
@@ -44,13 +50,6 @@
|
||||
"label": "Customer Naming By",
|
||||
"options": "Customer Name\nNaming Series\nAuto Name"
|
||||
},
|
||||
{
|
||||
"fieldname": "campaign_naming_by",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Campaign Naming By",
|
||||
"options": "Campaign Name\nNaming Series\nAuto Name"
|
||||
},
|
||||
{
|
||||
"fieldname": "customer_group",
|
||||
"fieldtype": "Link",
|
||||
@@ -58,6 +57,10 @@
|
||||
"label": "Default Customer Group",
|
||||
"options": "Customer Group"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "territory",
|
||||
"fieldtype": "Link",
|
||||
@@ -66,11 +69,31 @@
|
||||
"options": "Territory"
|
||||
},
|
||||
{
|
||||
"fieldname": "selling_price_list",
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "crm_settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "CRM Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "campaign_naming_by",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Default Price List",
|
||||
"options": "Price List"
|
||||
"label": "Campaign Naming By",
|
||||
"options": "Campaign Name\nNaming Series\nAuto Name"
|
||||
},
|
||||
{
|
||||
"fieldname": "contract_naming_by",
|
||||
"fieldtype": "Select",
|
||||
"label": "Contract Naming By",
|
||||
"options": "Party Name\nNaming Series"
|
||||
},
|
||||
{
|
||||
"fieldname": "default_valid_till",
|
||||
"fieldtype": "Data",
|
||||
"label": "Default Quotation Validity Days"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_9",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "15",
|
||||
@@ -80,9 +103,65 @@
|
||||
"label": "Close Opportunity After Days"
|
||||
},
|
||||
{
|
||||
"fieldname": "default_valid_till",
|
||||
"fieldtype": "Data",
|
||||
"label": "Default Quotation Validity Days"
|
||||
"fieldname": "item_price_settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Item Price Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "selling_price_list",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Default Price List",
|
||||
"options": "Price List"
|
||||
},
|
||||
{
|
||||
"default": "Stop",
|
||||
"depends_on": "maintain_same_sales_rate",
|
||||
"fieldname": "maintain_same_rate_action",
|
||||
"fieldtype": "Select",
|
||||
"label": "Action if Same Rate is Not Maintained Throughout Sales Cycle",
|
||||
"mandatory_depends_on": "maintain_same_sales_rate",
|
||||
"options": "Stop\nWarn"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.maintain_same_sales_rate && doc.maintain_same_rate_action == 'Stop'",
|
||||
"fieldname": "role_to_override_stop_action",
|
||||
"fieldtype": "Link",
|
||||
"label": "Role Allowed to Override Stop Action",
|
||||
"options": "Role"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_15",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "maintain_same_sales_rate",
|
||||
"fieldtype": "Check",
|
||||
"label": "Maintain Same Rate Throughout Sales Cycle"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "editable_price_list_rate",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow User to Edit Price List Rate in Transactions"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "validate_selling_price",
|
||||
"fieldtype": "Check",
|
||||
"label": "Validate Selling Price for Item Against Purchase Rate or Valuation Rate"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "editable_bundle_item_rates",
|
||||
"fieldtype": "Check",
|
||||
"label": "Calculate Product Bundle Price based on Child Items' Rates"
|
||||
},
|
||||
{
|
||||
"fieldname": "sales_transactions_settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Transaction Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "so_required",
|
||||
@@ -107,15 +186,10 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "maintain_same_sales_rate",
|
||||
"fieldtype": "Check",
|
||||
"label": "Maintain Same Rate Throughout Sales Cycle"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "editable_price_list_rate",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow User to Edit Price List Rate in Transactions"
|
||||
"description": "Percentage you are allowed to order more against the Blanket Order Quantity. For example: If you have a Blanket Order of Quantity 100 units. and your Allowance is 10% then you are allowed to order 110 units.",
|
||||
"fieldname": "over_order_allowance",
|
||||
"fieldtype": "Float",
|
||||
"label": "Over Order Allowance (%)"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@@ -129,83 +203,17 @@
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow Multiple Sales Orders Against a Customer's Purchase Order"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "validate_selling_price",
|
||||
"fieldtype": "Check",
|
||||
"label": "Validate Selling Price for Item Against Purchase Rate or Valuation Rate"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "hide_tax_id",
|
||||
"fieldtype": "Check",
|
||||
"label": "Hide Customer's Tax ID from Sales Transactions"
|
||||
},
|
||||
{
|
||||
"default": "Stop",
|
||||
"depends_on": "maintain_same_sales_rate",
|
||||
"fieldname": "maintain_same_rate_action",
|
||||
"fieldtype": "Select",
|
||||
"label": "Action if Same Rate is Not Maintained Throughout Sales Cycle",
|
||||
"mandatory_depends_on": "maintain_same_sales_rate",
|
||||
"options": "Stop\nWarn"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.maintain_same_sales_rate && doc.maintain_same_rate_action == 'Stop'",
|
||||
"fieldname": "role_to_override_stop_action",
|
||||
"fieldtype": "Link",
|
||||
"label": "Role Allowed to Override Stop Action",
|
||||
"options": "Role"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_15",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "editable_bundle_item_rates",
|
||||
"fieldname": "allow_sales_order_creation_for_expired_quotation",
|
||||
"fieldtype": "Check",
|
||||
"label": "Calculate Product Bundle Price based on Child Items' Rates"
|
||||
},
|
||||
{
|
||||
"fieldname": "customer_defaults_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Customer Defaults"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "crm_settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "CRM Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_9",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "item_price_settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Item Price Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "sales_transactions_settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Transaction Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "contract_naming_by",
|
||||
"fieldtype": "Select",
|
||||
"label": "Contract Naming By",
|
||||
"options": "Party Name\nNaming Series"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "allow_sales_order_creation_for_expired_quotation",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow Sales Order Creation For Expired Quotation"
|
||||
"label": "Allow Sales Order Creation For Expired Quotation"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-cog",
|
||||
@@ -213,7 +221,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2023-02-04 12:37:53.380857",
|
||||
"modified": "2023-03-22 13:09:38.513317",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Selling Settings",
|
||||
|
||||
Reference in New Issue
Block a user