refactor: Refactored over delivery/receipt/billing fields (#17788)
* refact: Refactored over delivery/receipt/billing fields * fix: test case
This commit is contained in:
parent
39c3cfa25d
commit
868766ddf0
@ -10,6 +10,7 @@
|
||||
"acc_frozen_upto",
|
||||
"frozen_accounts_modifier",
|
||||
"determine_address_tax_category_from",
|
||||
"over_billing_allowance",
|
||||
"column_break_4",
|
||||
"credit_controller",
|
||||
"check_supplier_invoice_uniqueness",
|
||||
@ -168,12 +169,18 @@
|
||||
"fieldname": "automatically_fetch_payment_terms",
|
||||
"fieldtype": "Check",
|
||||
"label": "Automatically Fetch Payment Terms"
|
||||
},
|
||||
{
|
||||
"description": "Percentage you are allowed to bill more against the amount ordered. For example: If the order value is $100 for an item and tolerance is set as 10% then you are allowed to bill for $110.",
|
||||
"fieldname": "over_billing_allowance",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Over Billing Allowance (%)"
|
||||
}
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2019-04-28 18:20:55.789946",
|
||||
"modified": "2019-07-04 18:20:55.789946",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounts Settings",
|
||||
@ -200,4 +207,4 @@
|
||||
"quick_entry": 1,
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 1
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
import json
|
||||
import frappe.defaults
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||
from frappe.utils import flt, add_days, nowdate, getdate
|
||||
@ -15,7 +16,7 @@ from erpnext.stock.doctype.material_request.test_material_request import make_ma
|
||||
from erpnext.stock.doctype.material_request.material_request import make_purchase_order
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
from erpnext.controllers.accounts_controller import update_child_qty_rate
|
||||
import json
|
||||
from erpnext.controllers.status_updater import OverAllowanceError
|
||||
|
||||
class TestPurchaseOrder(unittest.TestCase):
|
||||
def test_make_purchase_receipt(self):
|
||||
@ -41,7 +42,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
po.load_from_db()
|
||||
self.assertEqual(po.get("items")[0].received_qty, 4)
|
||||
|
||||
frappe.db.set_value('Item', '_Test Item', 'tolerance', 50)
|
||||
frappe.db.set_value('Item', '_Test Item', 'over_delivery_receipt_allowance', 50)
|
||||
|
||||
pr = create_pr_against_po(po.name, received_qty=8)
|
||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty)
|
||||
@ -57,12 +58,12 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
|
||||
def test_ordered_qty_against_pi_with_update_stock(self):
|
||||
existing_ordered_qty = get_ordered_qty()
|
||||
|
||||
po = create_purchase_order()
|
||||
|
||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 10)
|
||||
|
||||
frappe.db.set_value('Item', '_Test Item', 'tolerance', 50)
|
||||
frappe.db.set_value('Item', '_Test Item', 'over_delivery_receipt_allowance', 50)
|
||||
frappe.db.set_value('Item', '_Test Item', 'over_billing_allowance', 20)
|
||||
|
||||
pi = make_pi_from_po(po.name)
|
||||
pi.update_stock = 1
|
||||
@ -81,6 +82,11 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
po.load_from_db()
|
||||
self.assertEqual(po.get("items")[0].received_qty, 0)
|
||||
|
||||
frappe.db.set_value('Item', '_Test Item', 'over_delivery_receipt_allowance', 0)
|
||||
frappe.db.set_value('Item', '_Test Item', 'over_billing_allowance', 0)
|
||||
frappe.db.set_value("Accounts Settings", None, "over_billing_allowance", 0)
|
||||
|
||||
|
||||
def test_update_child_qty_rate(self):
|
||||
mr = make_material_request(qty=10)
|
||||
po = make_purchase_order(mr.name)
|
||||
|
@ -475,21 +475,20 @@ class AccountsController(TransactionBase):
|
||||
order_doctype = "Purchase Order"
|
||||
|
||||
order_list = list(set([d.get(order_field)
|
||||
for d in self.get("items") if d.get(order_field)]))
|
||||
for d in self.get("items") if d.get(order_field)]))
|
||||
|
||||
journal_entries = get_advance_journal_entries(party_type, party, party_account,
|
||||
amount_field, order_doctype, order_list, include_unallocated)
|
||||
amount_field, order_doctype, order_list, include_unallocated)
|
||||
|
||||
payment_entries = get_advance_payment_entries(party_type, party, party_account,
|
||||
order_doctype, order_list, include_unallocated)
|
||||
order_doctype, order_list, include_unallocated)
|
||||
|
||||
res = journal_entries + payment_entries
|
||||
|
||||
return res
|
||||
|
||||
def is_inclusive_tax(self):
|
||||
is_inclusive = cint(frappe.db.get_single_value("Accounts Settings",
|
||||
"show_inclusive_tax_in_print"))
|
||||
is_inclusive = cint(frappe.db.get_single_value("Accounts Settings", "show_inclusive_tax_in_print"))
|
||||
|
||||
if is_inclusive:
|
||||
is_inclusive = 0
|
||||
@ -501,7 +500,7 @@ class AccountsController(TransactionBase):
|
||||
def validate_advance_entries(self):
|
||||
order_field = "sales_order" if self.doctype == "Sales Invoice" else "purchase_order"
|
||||
order_list = list(set([d.get(order_field)
|
||||
for d in self.get("items") if d.get(order_field)]))
|
||||
for d in self.get("items") if d.get(order_field)]))
|
||||
|
||||
if not order_list: return
|
||||
|
||||
@ -513,7 +512,7 @@ class AccountsController(TransactionBase):
|
||||
if not advance_entries_against_si or d.reference_name not in advance_entries_against_si:
|
||||
frappe.msgprint(_(
|
||||
"Payment Entry {0} is linked against Order {1}, check if it should be pulled as advance in this invoice.")
|
||||
.format(d.reference_name, d.against_order))
|
||||
.format(d.reference_name, d.against_order))
|
||||
|
||||
def update_against_document_in_jv(self):
|
||||
"""
|
||||
@ -551,9 +550,9 @@ class AccountsController(TransactionBase):
|
||||
'unadjusted_amount': flt(d.advance_amount),
|
||||
'allocated_amount': flt(d.allocated_amount),
|
||||
'exchange_rate': (self.conversion_rate
|
||||
if self.party_account_currency != self.company_currency else 1),
|
||||
if self.party_account_currency != self.company_currency else 1),
|
||||
'grand_total': (self.base_grand_total
|
||||
if self.party_account_currency == self.company_currency else self.grand_total),
|
||||
if self.party_account_currency == self.company_currency else self.grand_total),
|
||||
'outstanding_amount': self.outstanding_amount
|
||||
})
|
||||
lst.append(args)
|
||||
@ -576,36 +575,37 @@ class AccountsController(TransactionBase):
|
||||
unlink_ref_doc_from_payment_entries(self)
|
||||
|
||||
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
||||
from erpnext.controllers.status_updater import get_tolerance_for
|
||||
item_tolerance = {}
|
||||
global_tolerance = None
|
||||
from erpnext.controllers.status_updater import get_allowance_for
|
||||
item_allowance = {}
|
||||
global_qty_allowance, global_amount_allowance = None, None
|
||||
|
||||
for item in self.get("items"):
|
||||
if item.get(item_ref_dn):
|
||||
ref_amt = flt(frappe.db.get_value(ref_dt + " Item",
|
||||
item.get(item_ref_dn), based_on), self.precision(based_on, item))
|
||||
item.get(item_ref_dn), based_on), self.precision(based_on, item))
|
||||
if not ref_amt:
|
||||
frappe.msgprint(
|
||||
_("Warning: System will not check overbilling since amount for Item {0} in {1} is zero").format(
|
||||
item.item_code, ref_dt))
|
||||
_("Warning: System will not check overbilling since amount for Item {0} in {1} is zero")
|
||||
.format(item.item_code, ref_dt))
|
||||
else:
|
||||
already_billed = frappe.db.sql("""select sum(%s) from `tab%s`
|
||||
where %s=%s and docstatus=1 and parent != %s""" %
|
||||
(based_on, self.doctype + " Item", item_ref_dn, '%s', '%s'),
|
||||
(item.get(item_ref_dn), self.name))[0][0]
|
||||
already_billed = frappe.db.sql("""
|
||||
select sum(%s)
|
||||
from `tab%s`
|
||||
where %s=%s and docstatus=1 and parent != %s
|
||||
""" % (based_on, self.doctype + " Item", item_ref_dn, '%s', '%s'),
|
||||
(item.get(item_ref_dn), self.name))[0][0]
|
||||
|
||||
total_billed_amt = flt(flt(already_billed) + flt(item.get(based_on)),
|
||||
self.precision(based_on, item))
|
||||
self.precision(based_on, item))
|
||||
|
||||
tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code,
|
||||
item_tolerance, global_tolerance)
|
||||
allowance, item_allowance, global_qty_allowance, global_amount_allowance = \
|
||||
get_allowance_for(item.item_code, item_allowance, global_qty_allowance, global_amount_allowance, "amount")
|
||||
|
||||
max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
|
||||
max_allowed_amt = flt(ref_amt * (100 + allowance) / 100)
|
||||
|
||||
if total_billed_amt - max_allowed_amt > 0.01:
|
||||
frappe.throw(_(
|
||||
"Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set in Stock Settings").format(
|
||||
item.item_code, item.idx, max_allowed_amt))
|
||||
frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set in Stock Settings")
|
||||
.format(item.item_code, item.idx, max_allowed_amt))
|
||||
|
||||
def get_company_default(self, fieldname):
|
||||
from erpnext.accounts.utils import get_company_default
|
||||
@ -615,9 +615,10 @@ class AccountsController(TransactionBase):
|
||||
stock_items = []
|
||||
item_codes = list(set(item.item_code for item in self.get("items")))
|
||||
if item_codes:
|
||||
stock_items = [r[0] for r in frappe.db.sql("""select name
|
||||
from `tabItem` where name in (%s) and is_stock_item=1""" % \
|
||||
(", ".join((["%s"] * len(item_codes))),), item_codes)]
|
||||
stock_items = [r[0] for r in frappe.db.sql("""
|
||||
select name from `tabItem`
|
||||
where name in (%s) and is_stock_item=1
|
||||
""" % (", ".join((["%s"] * len(item_codes))),), item_codes)]
|
||||
|
||||
return stock_items
|
||||
|
||||
|
@ -7,6 +7,8 @@ from frappe.utils import flt, comma_or, nowdate, getdate
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
class OverAllowanceError(frappe.ValidationError): pass
|
||||
|
||||
def validate_status(status, options):
|
||||
if status not in options:
|
||||
frappe.throw(_("Status must be one of {0}").format(comma_or(options)))
|
||||
@ -154,8 +156,9 @@ class StatusUpdater(Document):
|
||||
|
||||
def validate_qty(self):
|
||||
"""Validates qty at row level"""
|
||||
self.tolerance = {}
|
||||
self.global_tolerance = None
|
||||
self.item_allowance = {}
|
||||
self.global_qty_allowance = None
|
||||
self.global_amount_allowance = None
|
||||
|
||||
for args in self.status_updater:
|
||||
if "target_ref_field" not in args:
|
||||
@ -186,32 +189,41 @@ class StatusUpdater(Document):
|
||||
|
||||
# if not item[args['target_ref_field']]:
|
||||
# msgprint(_("Note: System will not check over-delivery and over-booking for Item {0} as quantity or amount is 0").format(item.item_code))
|
||||
if args.get('no_tolerance'):
|
||||
if args.get('no_allowance'):
|
||||
item['reduce_by'] = item[args['target_field']] - item[args['target_ref_field']]
|
||||
if item['reduce_by'] > .01:
|
||||
self.limits_crossed_error(args, item)
|
||||
|
||||
elif item[args['target_ref_field']]:
|
||||
self.check_overflow_with_tolerance(item, args)
|
||||
self.check_overflow_with_allowance(item, args)
|
||||
|
||||
def check_overflow_with_tolerance(self, item, args):
|
||||
def check_overflow_with_allowance(self, item, args):
|
||||
"""
|
||||
Checks if there is overflow condering a relaxation tolerance
|
||||
Checks if there is overflow condering a relaxation allowance
|
||||
"""
|
||||
# check if overflow is within tolerance
|
||||
tolerance, self.tolerance, self.global_tolerance = get_tolerance_for(item['item_code'],
|
||||
self.tolerance, self.global_tolerance)
|
||||
qty_or_amount = "qty" if "qty" in args['target_ref_field'] else "amount"
|
||||
|
||||
# check if overflow is within allowance
|
||||
allowance, self.item_allowance, self.global_qty_allowance, self.global_amount_allowance = \
|
||||
get_allowance_for(item['item_code'], self.item_allowance,
|
||||
self.global_qty_allowance, self.global_amount_allowance, qty_or_amount)
|
||||
|
||||
overflow_percent = ((item[args['target_field']] - item[args['target_ref_field']]) /
|
||||
item[args['target_ref_field']]) * 100
|
||||
|
||||
if overflow_percent - tolerance > 0.01:
|
||||
item['max_allowed'] = flt(item[args['target_ref_field']] * (100+tolerance)/100)
|
||||
if overflow_percent - allowance > 0.01:
|
||||
item['max_allowed'] = flt(item[args['target_ref_field']] * (100+allowance)/100)
|
||||
item['reduce_by'] = item[args['target_field']] - item['max_allowed']
|
||||
|
||||
self.limits_crossed_error(args, item)
|
||||
self.limits_crossed_error(args, item, qty_or_amount)
|
||||
|
||||
def limits_crossed_error(self, args, item):
|
||||
def limits_crossed_error(self, args, item, qty_or_amount):
|
||||
'''Raise exception for limits crossed'''
|
||||
if qty_or_amount == "qty":
|
||||
action_msg = _('To allow over receipt / delivery, update "Over Receipt/Delivery Allowance" in Stock Settings or the Item.')
|
||||
else:
|
||||
action_msg = _('To allow over billing, update "Over Billing Allowance" in Accounts Settings or the Item.')
|
||||
|
||||
frappe.throw(_('This document is over limit by {0} {1} for item {4}. Are you making another {3} against the same {2}?')
|
||||
.format(
|
||||
frappe.bold(_(item["target_ref_field"].title())),
|
||||
@ -219,9 +231,7 @@ class StatusUpdater(Document):
|
||||
frappe.bold(_(args.get('target_dt'))),
|
||||
frappe.bold(_(self.doctype)),
|
||||
frappe.bold(item.get('item_code'))
|
||||
) + '<br><br>' +
|
||||
_('To allow over-billing or over-ordering, update "Allowance" in Stock Settings or the Item.'),
|
||||
title = _('Limit Crossed'))
|
||||
) + '<br><br>' + action_msg, OverAllowanceError, title = _('Limit Crossed'))
|
||||
|
||||
def update_qty(self, update_modified=True):
|
||||
"""Updates qty or amount at row level
|
||||
@ -358,19 +368,34 @@ class StatusUpdater(Document):
|
||||
ref_doc.db_set("per_billed", per_billed)
|
||||
ref_doc.set_status(update=True)
|
||||
|
||||
def get_tolerance_for(item_code, item_tolerance={}, global_tolerance=None):
|
||||
def get_allowance_for(item_code, item_allowance={}, global_qty_allowance=None, global_amount_allowance=None, qty_or_amount="qty"):
|
||||
"""
|
||||
Returns the tolerance for the item, if not set, returns global tolerance
|
||||
Returns the allowance for the item, if not set, returns global allowance
|
||||
"""
|
||||
if item_tolerance.get(item_code):
|
||||
return item_tolerance[item_code], item_tolerance, global_tolerance
|
||||
if qty_or_amount == "qty":
|
||||
if item_allowance.get(item_code, frappe._dict()).get("qty"):
|
||||
return item_allowance[item_code].qty, item_allowance, global_qty_allowance, global_amount_allowance
|
||||
else:
|
||||
if item_allowance.get(item_code, frappe._dict()).get("amount"):
|
||||
return item_allowance[item_code].amount, item_allowance, global_qty_allowance, global_amount_allowance
|
||||
|
||||
tolerance = flt(frappe.db.get_value('Item',item_code,'tolerance') or 0)
|
||||
qty_allowance, over_billing_allowance = \
|
||||
frappe.db.get_value('Item', item_code, ['over_delivery_receipt_allowance', 'over_billing_allowance'])
|
||||
|
||||
if not tolerance:
|
||||
if global_tolerance == None:
|
||||
global_tolerance = flt(frappe.db.get_value('Stock Settings', None, 'tolerance'))
|
||||
tolerance = global_tolerance
|
||||
if qty_or_amount == "qty" and not qty_allowance:
|
||||
if global_qty_allowance == None:
|
||||
global_qty_allowance = flt(frappe.db.get_single_value('Stock Settings', 'over_delivery_receipt_allowance'))
|
||||
qty_allowance = global_qty_allowance
|
||||
elif qty_or_amount == "amount" and not over_billing_allowance:
|
||||
if global_amount_allowance == None:
|
||||
global_amount_allowance = flt(frappe.db.get_single_value('Accounts Settings', 'over_billing_allowance'))
|
||||
over_billing_allowance = global_amount_allowance
|
||||
|
||||
item_tolerance[item_code] = tolerance
|
||||
return tolerance, item_tolerance, global_tolerance
|
||||
if qty_or_amount == "qty":
|
||||
allowance = qty_allowance
|
||||
item_allowance.setdefault(item_code, frappe._dict()).setdefault("qty", qty_allowance)
|
||||
else:
|
||||
allowance = over_billing_allowance
|
||||
item_allowance.setdefault(item_code, frappe._dict()).setdefault("amount", over_billing_allowance)
|
||||
|
||||
return allowance, item_allowance, global_qty_allowance, global_amount_allowance
|
||||
|
@ -603,6 +603,7 @@ erpnext.patches.v11_1.set_salary_details_submittable
|
||||
erpnext.patches.v11_1.rename_depends_on_lwp
|
||||
execute:frappe.delete_doc("Report", "Inactive Items")
|
||||
erpnext.patches.v11_1.delete_scheduling_tool
|
||||
erpnext.patches.v12_0.rename_tolerance_fields
|
||||
erpnext.patches.v12_0.make_custom_fields_for_bank_remittance #14-06-2019
|
||||
execute:frappe.delete_doc_if_exists("Page", "support-analytics")
|
||||
erpnext.patches.v12_0.make_item_manufacturer
|
||||
|
15
erpnext/patches/v12_0/rename_tolerance_fields.py
Normal file
15
erpnext/patches/v12_0/rename_tolerance_fields.py
Normal file
@ -0,0 +1,15 @@
|
||||
import frappe
|
||||
from frappe.model.utils.rename_field import rename_field
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("stock", "doctype", "item")
|
||||
frappe.reload_doc("stock", "doctype", "stock_settings")
|
||||
frappe.reload_doc("accounts", "doctype", "accounts_settings")
|
||||
|
||||
rename_field('Stock Settings', "tolerance", "over_delivery_receipt_allowance")
|
||||
rename_field('Item', "tolerance", "over_delivery_receipt_allowance")
|
||||
|
||||
qty_allowance = frappe.db.get_single_value("Stock Settings", "over_delivery_receipt_allowance")
|
||||
frappe.db.set_value("Accounts Settings", None, "over_delivery_receipt_allowance", qty_allowance)
|
||||
|
||||
frappe.db.sql("update tabItem set over_billing_allowance=over_delivery_receipt_allowance")
|
@ -65,7 +65,7 @@ $.extend(erpnext.queries, {
|
||||
frappe.throw(__("Please set {0}",
|
||||
[__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name))]));
|
||||
}
|
||||
|
||||
console.log(frappe.dynamic_link)
|
||||
return {
|
||||
query: 'frappe.contacts.doctype.address.address.address_query',
|
||||
filters: {
|
||||
|
@ -192,8 +192,8 @@ class TestSalesOrder(unittest.TestCase):
|
||||
|
||||
def test_reserved_qty_for_over_delivery(self):
|
||||
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
|
||||
# set over-delivery tolerance
|
||||
frappe.db.set_value('Item', "_Test Item", 'tolerance', 50)
|
||||
# set over-delivery allowance
|
||||
frappe.db.set_value('Item', "_Test Item", 'over_delivery_receipt_allowance', 50)
|
||||
|
||||
existing_reserved_qty = get_reserved_qty()
|
||||
|
||||
@ -209,8 +209,9 @@ class TestSalesOrder(unittest.TestCase):
|
||||
def test_reserved_qty_for_over_delivery_via_sales_invoice(self):
|
||||
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
|
||||
|
||||
# set over-delivery tolerance
|
||||
frappe.db.set_value('Item', "_Test Item", 'tolerance', 50)
|
||||
# set over-delivery allowance
|
||||
frappe.db.set_value('Item', "_Test Item", 'over_delivery_receipt_allowance', 50)
|
||||
frappe.db.set_value('Item', "_Test Item", 'over_billing_allowance', 20)
|
||||
|
||||
existing_reserved_qty = get_reserved_qty()
|
||||
|
||||
@ -291,8 +292,8 @@ class TestSalesOrder(unittest.TestCase):
|
||||
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
|
||||
make_stock_entry(item="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=10, rate=100)
|
||||
|
||||
# set over-delivery tolerance
|
||||
frappe.db.set_value('Item', "_Test Product Bundle Item", 'tolerance', 50)
|
||||
# set over-delivery allowance
|
||||
frappe.db.set_value('Item', "_Test Product Bundle Item", 'over_delivery_receipt_allowance', 50)
|
||||
|
||||
existing_reserved_qty_item1 = get_reserved_qty("_Test Item")
|
||||
existing_reserved_qty_item2 = get_reserved_qty("_Test Item Home Desktop 100")
|
||||
|
@ -51,7 +51,7 @@ class DeliveryNote(SellingController):
|
||||
'source_field': 'qty',
|
||||
'percent_join_field': 'against_sales_invoice',
|
||||
'overflow_type': 'delivery',
|
||||
'no_tolerance': 1
|
||||
'no_allowance': 1
|
||||
}]
|
||||
if cint(self.is_return):
|
||||
self.status_updater.append({
|
||||
|
@ -29,7 +29,8 @@
|
||||
"is_fixed_asset",
|
||||
"asset_category",
|
||||
"asset_naming_series",
|
||||
"tolerance",
|
||||
"over_delivery_receipt_allowance",
|
||||
"over_billing_allowance",
|
||||
"image",
|
||||
"section_break_11",
|
||||
"brand",
|
||||
@ -284,14 +285,6 @@
|
||||
"fieldtype": "Select",
|
||||
"label": "Asset Naming Series"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "tolerance",
|
||||
"fieldtype": "Float",
|
||||
"label": "Allow over delivery or receipt upto this percent",
|
||||
"oldfieldname": "tolerance",
|
||||
"oldfieldtype": "Currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "image",
|
||||
"fieldtype": "Attach Image",
|
||||
@ -1021,6 +1014,26 @@
|
||||
"fieldtype": "Check",
|
||||
"label": "Synced With Hub",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "manufacturers",
|
||||
"fieldtype": "Table",
|
||||
"label": "Manufacturers",
|
||||
"options": "Item Manufacturer"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "over_delivery_receipt_allowance",
|
||||
"fieldtype": "Float",
|
||||
"label": "Over Delivery/Receipt Allowance (%)",
|
||||
"oldfieldname": "tolerance",
|
||||
"oldfieldtype": "Currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "over_billing_allowance",
|
||||
"fieldtype": "Float",
|
||||
"label": "Over Billing Allowance (%)",
|
||||
"depends_on": "eval:!doc.__islocal"
|
||||
}
|
||||
],
|
||||
"has_web_view": 1,
|
||||
@ -1028,7 +1041,7 @@
|
||||
"idx": 2,
|
||||
"image_field": "image",
|
||||
"max_attachments": 1,
|
||||
"modified": "2019-07-05 12:18:13.977931",
|
||||
"modified": "2019-07-12 12:18:13.977931",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Item",
|
||||
|
@ -255,7 +255,7 @@
|
||||
"columns": 0,
|
||||
"description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "tolerance",
|
||||
"fieldname": "over_delivery_receipt_allowance",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -264,7 +264,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Limit Percent",
|
||||
"label": "Over Delivery/Receipt Allowance (%)",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@ -918,7 +918,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-06-18 01:19:07.738045",
|
||||
"modified": "2019-07-04 01:19:07.738045",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Settings",
|
||||
|
Loading…
x
Reference in New Issue
Block a user