Merge pull request #16554 from SaiFi0102/Brand-Item-Defaults-V12
feat: Brand Item Defaults (v12)
This commit is contained in:
commit
9c43c8f00b
@ -142,6 +142,8 @@ def _make_test_records(verbose):
|
||||
["_Test Write Off", "Indirect Expenses", 0, None, None],
|
||||
["_Test Exchange Gain/Loss", "Indirect Expenses", 0, None, None],
|
||||
|
||||
["_Test Account Sales", "Direct Income", 0, None, None],
|
||||
|
||||
# related to Account Inventory Integration
|
||||
["_Test Account Stock In Hand", "Current Assets", 0, None, None],
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_in_quick_entry": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -79,6 +79,71 @@
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "300px"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "defaults",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Defaults",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "brand_defaults",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Brand Defaults",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Item Default",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
@ -92,7 +157,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-01-07 16:52:05.945810",
|
||||
"modified": "2018-10-23 23:18:06.067612",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Brand",
|
||||
@ -202,4 +267,4 @@
|
||||
"track_changes": 0,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,22 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import copy
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
class Brand(Document):
|
||||
pass
|
||||
pass
|
||||
|
||||
def get_brand_defaults(item, company):
|
||||
item = frappe.get_cached_doc("Item", item)
|
||||
if item.brand:
|
||||
brand = frappe.get_cached_doc("Brand", item.brand)
|
||||
|
||||
for d in brand.brand_defaults or []:
|
||||
if d.company == company:
|
||||
row = copy.deepcopy(d.as_dict())
|
||||
row.pop("name")
|
||||
return row
|
||||
|
||||
return frappe._dict()
|
@ -2,5 +2,16 @@
|
||||
{
|
||||
"brand": "_Test Brand",
|
||||
"doctype": "Brand"
|
||||
},
|
||||
{
|
||||
"brand": "_Test Brand With Item Defaults",
|
||||
"doctype": "Brand",
|
||||
"brand_defaults": [{
|
||||
"company": "_Test Company",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"income_account": "_Test Account Sales - _TC",
|
||||
"buying_cost_center": "_Test Cost Center - _TC",
|
||||
"selling_cost_center": "_Test Cost Center - _TC"
|
||||
}]
|
||||
}
|
||||
]
|
@ -86,7 +86,7 @@ class Item(WebsiteGenerator):
|
||||
def after_insert(self):
|
||||
'''set opening stock and item price'''
|
||||
if self.standard_rate:
|
||||
for default in self.item_defaults:
|
||||
for default in self.item_defaults or [frappe._dict()]:
|
||||
self.add_price(default.default_price_list)
|
||||
|
||||
if self.opening_stock:
|
||||
@ -127,7 +127,6 @@ class Item(WebsiteGenerator):
|
||||
self.validate_retain_sample()
|
||||
self.validate_uom_conversion_factor()
|
||||
self.validate_item_defaults()
|
||||
self.update_defaults_from_item_group()
|
||||
self.validate_customer_provided_part()
|
||||
|
||||
if not self.get("__islocal"):
|
||||
@ -185,7 +184,7 @@ class Item(WebsiteGenerator):
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
|
||||
# default warehouse, or Stores
|
||||
for default in self.item_defaults:
|
||||
for default in self.item_defaults or [frappe._dict({'company': frappe.defaults.get_defaults().company})]:
|
||||
default_warehouse = (default.default_warehouse
|
||||
or frappe.db.get_single_value('Stock Settings', 'default_warehouse')
|
||||
or frappe.db.get_value('Warehouse', {'warehouse_name': _('Stores')}))
|
||||
|
@ -164,6 +164,61 @@ class TestItem(unittest.TestCase):
|
||||
self.assertEqual(details.item_tax_template, data['item_tax_template'])
|
||||
self.assertEqual(json.loads(details.item_tax_rate), expected_item_tax_map[details.item_tax_template])
|
||||
|
||||
def test_item_defaults(self):
|
||||
frappe.delete_doc_if_exists("Item", "Test Item With Defaults", force=1)
|
||||
make_item("Test Item With Defaults", {
|
||||
"item_group": "_Test Item Group",
|
||||
"brand": "_Test Brand With Item Defaults",
|
||||
"item_defaults": [{
|
||||
"company": "_Test Company",
|
||||
"default_warehouse": "_Test Warehouse 2 - _TC", # no override
|
||||
"expense_account": "_Test Account Stock Expenses - _TC", # override brand default
|
||||
"buying_cost_center": "_Test Write Off Cost Center - _TC", # override item group default
|
||||
}]
|
||||
})
|
||||
|
||||
sales_item_check = {
|
||||
"item_code": "Test Item With Defaults",
|
||||
"warehouse": "_Test Warehouse 2 - _TC", # from item
|
||||
"income_account": "_Test Account Sales - _TC", # from brand
|
||||
"expense_account": "_Test Account Stock Expenses - _TC", # from item
|
||||
"cost_center": "_Test Cost Center 2 - _TC", # from item group
|
||||
}
|
||||
sales_item_details = get_item_details({
|
||||
"item_code": "Test Item With Defaults",
|
||||
"company": "_Test Company",
|
||||
"price_list": "_Test Price List",
|
||||
"currency": "_Test Currency",
|
||||
"doctype": "Sales Invoice",
|
||||
"conversion_rate": 1,
|
||||
"price_list_currency": "_Test Currency",
|
||||
"plc_conversion_rate": 1,
|
||||
"customer": "_Test Customer",
|
||||
})
|
||||
for key, value in iteritems(sales_item_check):
|
||||
self.assertEqual(value, sales_item_details.get(key))
|
||||
|
||||
purchase_item_check = {
|
||||
"item_code": "Test Item With Defaults",
|
||||
"warehouse": "_Test Warehouse 2 - _TC", # from item
|
||||
"expense_account": "_Test Account Stock Expenses - _TC", # from item
|
||||
"income_account": "_Test Account Sales - _TC", # from brand
|
||||
"cost_center": "_Test Write Off Cost Center - _TC" # from item
|
||||
}
|
||||
purchase_item_details = get_item_details({
|
||||
"item_code": "Test Item With Defaults",
|
||||
"company": "_Test Company",
|
||||
"price_list": "_Test Price List",
|
||||
"currency": "_Test Currency",
|
||||
"doctype": "Purchase Invoice",
|
||||
"conversion_rate": 1,
|
||||
"price_list_currency": "_Test Currency",
|
||||
"plc_conversion_rate": 1,
|
||||
"supplier": "_Test Supplier",
|
||||
})
|
||||
for key, value in iteritems(purchase_item_check):
|
||||
self.assertEqual(value, purchase_item_details.get(key))
|
||||
|
||||
def test_item_attribute_change_after_variant(self):
|
||||
frappe.delete_doc_if_exists("Item", "_Test Variant Item-L", force=1)
|
||||
|
||||
|
@ -10,6 +10,7 @@ from erpnext.stock.utils import get_incoming_rate
|
||||
from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError, get_valuation_rate
|
||||
from erpnext.stock.get_item_details import get_bin_details, get_default_cost_center, get_conversion_factor, get_reserved_qty_for_so
|
||||
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
||||
from erpnext.setup.doctype.brand.brand import get_brand_defaults
|
||||
from erpnext.stock.doctype.batch.batch import get_batch_no, set_batch_nos, get_batch_qty
|
||||
from erpnext.stock.doctype.item.item import get_item_defaults
|
||||
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, add_additional_cost
|
||||
@ -636,6 +637,7 @@ class StockEntry(StockController):
|
||||
|
||||
item = item[0]
|
||||
item_group_defaults = get_item_group_defaults(item.name, self.company)
|
||||
brand_defaults = get_brand_defaults(item.name, self.company)
|
||||
|
||||
ret = frappe._dict({
|
||||
'uom' : item.stock_uom,
|
||||
@ -644,7 +646,7 @@ class StockEntry(StockController):
|
||||
'image' : item.image,
|
||||
'item_name' : item.item_name,
|
||||
'expense_account' : args.get("expense_account"),
|
||||
'cost_center' : get_default_cost_center(args, item, item_group_defaults),
|
||||
'cost_center' : get_default_cost_center(args, item, item_group_defaults, brand_defaults),
|
||||
'qty' : args.get("qty"),
|
||||
'transfer_qty' : args.get('qty'),
|
||||
'conversion_factor' : 1,
|
||||
|
@ -13,6 +13,7 @@ from erpnext.stock.doctype.batch.batch import get_batch_no
|
||||
from erpnext import get_company_currency
|
||||
from erpnext.stock.doctype.item.item import get_item_defaults, get_uom_conv_factor
|
||||
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
||||
from erpnext.setup.doctype.brand.brand import get_brand_defaults
|
||||
|
||||
from six import string_types, iteritems
|
||||
|
||||
@ -226,9 +227,10 @@ def get_basic_details(args, item):
|
||||
|
||||
item_defaults = get_item_defaults(item.name, args.company)
|
||||
item_group_defaults = get_item_group_defaults(item.name, args.company)
|
||||
brand_defaults = get_brand_defaults(item.name, args.company)
|
||||
|
||||
warehouse = args.get("set_warehouse") or user_default_warehouse or item_defaults.get("default_warehouse") or\
|
||||
item_group_defaults.get("default_warehouse") or args.warehouse
|
||||
item_group_defaults.get("default_warehouse") or brand_defaults.get("default_warehouse") or args.warehouse
|
||||
|
||||
if args.get('doctype') == "Material Request" and not args.get('material_request_type'):
|
||||
args['material_request_type'] = frappe.db.get_value('Material Request',
|
||||
@ -250,9 +252,9 @@ def get_basic_details(args, item):
|
||||
"description": cstr(item.description).strip(),
|
||||
"image": cstr(item.image).strip(),
|
||||
"warehouse": warehouse,
|
||||
"income_account": get_default_income_account(args, item_defaults, item_group_defaults),
|
||||
"expense_account": get_default_expense_account(args, item_defaults, item_group_defaults),
|
||||
"cost_center": get_default_cost_center(args, item_defaults, item_group_defaults),
|
||||
"income_account": get_default_income_account(args, item_defaults, item_group_defaults, brand_defaults),
|
||||
"expense_account": get_default_expense_account(args, item_defaults, item_group_defaults, brand_defaults),
|
||||
"cost_center": get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults),
|
||||
'has_serial_no': item.has_serial_no,
|
||||
'has_batch_no': item.has_batch_no,
|
||||
"batch_no": None,
|
||||
@ -269,7 +271,7 @@ def get_basic_details(args, item):
|
||||
"net_rate": 0.0,
|
||||
"net_amount": 0.0,
|
||||
"discount_percentage": 0.0,
|
||||
"supplier": get_default_supplier(args, item_defaults, item_group_defaults),
|
||||
"supplier": get_default_supplier(args, item_defaults, item_group_defaults, brand_defaults),
|
||||
"update_stock": args.get("update_stock") if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0,
|
||||
"delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0,
|
||||
"is_fixed_asset": item.is_fixed_asset,
|
||||
@ -391,14 +393,16 @@ def calculate_service_end_date(args, item=None):
|
||||
|
||||
return deferred_detail
|
||||
|
||||
def get_default_income_account(args, item, item_group):
|
||||
def get_default_income_account(args, item, item_group, brand):
|
||||
return (item.get("income_account")
|
||||
or item_group.get("income_account")
|
||||
or brand.get("income_account")
|
||||
or args.income_account)
|
||||
|
||||
def get_default_expense_account(args, item, item_group):
|
||||
def get_default_expense_account(args, item, item_group, brand):
|
||||
return (item.get("expense_account")
|
||||
or item_group.get("expense_account")
|
||||
or brand.get("expense_account")
|
||||
or args.expense_account)
|
||||
|
||||
def get_default_deferred_account(args, item, fieldname=None):
|
||||
@ -409,22 +413,23 @@ def get_default_deferred_account(args, item, fieldname=None):
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_default_cost_center(args, item, item_group):
|
||||
def get_default_cost_center(args, item, item_group, brand):
|
||||
cost_center = None
|
||||
if args.get('project'):
|
||||
cost_center = frappe.db.get_value("Project", args.get("project"), "cost_center", cache=True)
|
||||
|
||||
if not cost_center:
|
||||
if args.get('customer'):
|
||||
cost_center = item.get('selling_cost_center') or item_group.get('selling_cost_center')
|
||||
cost_center = item.get('selling_cost_center') or item_group.get('selling_cost_center') or brand.get('selling_cost_center')
|
||||
else:
|
||||
cost_center = item.get('buying_cost_center') or item_group.get('buying_cost_center')
|
||||
cost_center = item.get('buying_cost_center') or item_group.get('buying_cost_center') or brand.get('buying_cost_center')
|
||||
|
||||
return cost_center or args.get("cost_center")
|
||||
|
||||
def get_default_supplier(args, item, item_group):
|
||||
def get_default_supplier(args, item, item_group, brand):
|
||||
return (item.get("default_supplier")
|
||||
or item_group.get("default_supplier"))
|
||||
or item_group.get("default_supplier")
|
||||
or brand.get("default_supplier"))
|
||||
|
||||
def get_price_list_rate(args, item_doc, out):
|
||||
meta = frappe.get_meta(args.parenttype or args.doctype)
|
||||
@ -899,10 +904,11 @@ def get_default_bom(item_code=None):
|
||||
def get_valuation_rate(item_code, company, warehouse=None):
|
||||
item = get_item_defaults(item_code, company)
|
||||
item_group = get_item_group_defaults(item_code, company)
|
||||
brand = get_brand_defaults(item_code, company)
|
||||
# item = frappe.get_doc("Item", item_code)
|
||||
if item.get("is_stock_item"):
|
||||
if not warehouse:
|
||||
warehouse = item.get("default_warehouse") or item_group.get("default_warehouse")
|
||||
warehouse = item.get("default_warehouse") or item_group.get("default_warehouse") or brand.get("default_warehouse")
|
||||
|
||||
return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
|
||||
["valuation_rate"], as_dict=True) or {"valuation_rate": 0}
|
||||
|
Loading…
x
Reference in New Issue
Block a user