Merge branch 'v12-pre-release' into version-12

This commit is contained in:
Sahil Khan
2020-01-20 18:02:31 +05:30
6 changed files with 20 additions and 35 deletions

View File

@@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides from erpnext.hooks import regional_overrides
from frappe.utils import getdate from frappe.utils import getdate
__version__ = '12.4.0' __version__ = '12.4.1'
def get_default_company(user=None): def get_default_company(user=None):
'''Get default company for user''' '''Get default company for user'''

View File

@@ -782,11 +782,12 @@ def add_non_stock_items_cost(stock_entry, work_order, expense_account):
for name in non_stock_items: for name in non_stock_items:
non_stock_items_cost += flt(items.get(name[0])) * flt(stock_entry.fg_completed_qty) / flt(bom.quantity) non_stock_items_cost += flt(items.get(name[0])) * flt(stock_entry.fg_completed_qty) / flt(bom.quantity)
stock_entry.append('additional_costs', { if non_stock_items_cost:
'expense_account': expense_account, stock_entry.append('additional_costs', {
'description': _("Non stock items"), 'expense_account': expense_account,
'amount': non_stock_items_cost 'description': _("Non stock items"),
}) 'amount': non_stock_items_cost
})
def add_operations_cost(stock_entry, work_order=None, expense_account=None): def add_operations_cost(stock_entry, work_order=None, expense_account=None):
from erpnext.stock.doctype.stock_entry.stock_entry import get_operating_cost_per_unit from erpnext.stock.doctype.stock_entry.stock_entry import get_operating_cost_per_unit
@@ -803,11 +804,12 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None):
additional_operating_cost_per_unit = \ additional_operating_cost_per_unit = \
flt(work_order.additional_operating_cost) / flt(work_order.qty) flt(work_order.additional_operating_cost) / flt(work_order.qty)
stock_entry.append('additional_costs', { if additional_operating_cost_per_unit:
"expense_account": expense_account, stock_entry.append('additional_costs', {
"description": "Additional Operating Cost", "expense_account": expense_account,
"amount": additional_operating_cost_per_unit * flt(stock_entry.fg_completed_qty) "description": "Additional Operating Cost",
}) "amount": additional_operating_cost_per_unit * flt(stock_entry.fg_completed_qty)
})
@frappe.whitelist() @frappe.whitelist()
def get_bom_diff(bom1, bom2): def get_bom_diff(bom1, bom2):

View File

@@ -13,7 +13,7 @@ from frappe.model.document import Document
class ItemPrice(Document): class ItemPrice(Document):
def validate(self): def validate(self):
self.validate_item() self.validate_item()
self.validate_dates() self.validate_dates()
@@ -51,7 +51,7 @@ class ItemPrice(Document):
def check_duplicates(self): def check_duplicates(self):
conditions = "where item_code=%(item_code)s and price_list=%(price_list)s and name != %(name)s" conditions = "where item_code=%(item_code)s and price_list=%(price_list)s and name != %(name)s"
for field in ['uom', 'min_qty', 'valid_from', for field in ['uom', 'valid_from',
'valid_upto', 'packing_unit', 'customer', 'supplier']: 'valid_upto', 'packing_unit', 'customer', 'supplier']:
if self.get(field): if self.get(field):
conditions += " and {0} = %({1})s".format(field, field) conditions += " and {0} = %({1})s".format(field, field)

View File

@@ -21,7 +21,7 @@ class TestItemPrice(unittest.TestCase):
def test_addition_of_new_fields(self): def test_addition_of_new_fields(self):
# Based on https://github.com/frappe/erpnext/issues/8456 # Based on https://github.com/frappe/erpnext/issues/8456
test_fields_existance = [ test_fields_existance = [
'supplier', 'customer', 'uom', 'min_qty', 'lead_time_days', 'supplier', 'customer', 'uom', 'lead_time_days',
'packing_unit', 'valid_from', 'valid_upto', 'note' 'packing_unit', 'valid_from', 'valid_upto', 'note'
] ]
doc_fields = frappe.copy_doc(test_records[1]).__dict__.keys() doc_fields = frappe.copy_doc(test_records[1]).__dict__.keys()
@@ -43,7 +43,6 @@ class TestItemPrice(unittest.TestCase):
args = { args = {
"price_list": doc.price_list, "price_list": doc.price_list,
"min_qty": doc.min_qty,
"customer": doc.customer, "customer": doc.customer,
"uom": "_Test UOM", "uom": "_Test UOM",
"transaction_date": '2017-04-18', "transaction_date": '2017-04-18',
@@ -58,7 +57,6 @@ class TestItemPrice(unittest.TestCase):
doc = frappe.copy_doc(test_records[2]) doc = frappe.copy_doc(test_records[2])
args = { args = {
"price_list": doc.price_list, "price_list": doc.price_list,
"min_qty": 30,
"customer": doc.customer, "customer": doc.customer,
"uom": "_Test UOM", "uom": "_Test UOM",
"transaction_date": '2017-04-18', "transaction_date": '2017-04-18',
@@ -74,7 +72,6 @@ class TestItemPrice(unittest.TestCase):
args = { args = {
"price_list": doc.price_list, "price_list": doc.price_list,
"min_qty": doc.min_qty,
"customer": "_Test Customer", "customer": "_Test Customer",
"uom": "_Test UOM", "uom": "_Test UOM",
"transaction_date": '2017-04-18', "transaction_date": '2017-04-18',
@@ -90,7 +87,6 @@ class TestItemPrice(unittest.TestCase):
args = { args = {
"price_list": doc.price_list, "price_list": doc.price_list,
"min_qty": doc.min_qty,
"qty": 7, "qty": 7,
"uom": "_Test UOM", "uom": "_Test UOM",
"transaction_date": "01-15-2019" "transaction_date": "01-15-2019"
@@ -105,7 +101,6 @@ class TestItemPrice(unittest.TestCase):
args = { args = {
"price_list": doc.price_list, "price_list": doc.price_list,
"min_qty": doc.min_qty,
"customer": "_Test Customer", "customer": "_Test Customer",
"uom": "_Test UOM", "uom": "_Test UOM",
"transaction_date": "2017-04-25", "transaction_date": "2017-04-25",
@@ -121,7 +116,6 @@ class TestItemPrice(unittest.TestCase):
args = { args = {
"price_list": doc.price_list, "price_list": doc.price_list,
"min_qty": doc.min_qty,
"uom": "_Test UOM", "uom": "_Test UOM",
"qty": 7, "qty": 7,
} }

View File

@@ -682,6 +682,8 @@ class StockEntry(StockController):
if item_account_wise_additional_cost: if item_account_wise_additional_cost:
for d in self.get("items"): for d in self.get("items"):
for account, amount in iteritems(item_account_wise_additional_cost.get((d.item_code, d.name), {})): for account, amount in iteritems(item_account_wise_additional_cost.get((d.item_code, d.name), {})):
if not amount: continue
gl_entries.append(self.get_gl_dict({ gl_entries.append(self.get_gl_dict({
"account": account, "account": account,
"against": d.expense_account, "against": d.expense_account,

View File

@@ -581,7 +581,7 @@ def get_item_price(args, item_code, ignore_party=False):
Get name, price_list_rate from Item Price based on conditions Get name, price_list_rate from Item Price based on conditions
Check if the desired qty is within the increment of the packing list. Check if the desired qty is within the increment of the packing list.
:param args: dict (or frappe._dict) with mandatory fields price_list, uom :param args: dict (or frappe._dict) with mandatory fields price_list, uom
optional fields min_qty, transaction_date, customer, supplier optional fields transaction_date, customer, supplier
:param item_code: str, Item Doctype field item_code :param item_code: str, Item Doctype field item_code
""" """
@@ -599,24 +599,16 @@ def get_item_price(args, item_code, ignore_party=False):
else: else:
conditions += " and (customer is null or customer = '') and (supplier is null or supplier = '')" conditions += " and (customer is null or customer = '') and (supplier is null or supplier = '')"
if args.get('min_qty'):
conditions += " and ifnull(min_qty, 0) <= %(min_qty)s"
if args.get('transaction_date'): if args.get('transaction_date'):
conditions += """ and %(transaction_date)s between conditions += """ and %(transaction_date)s between
ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')""" ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""
return frappe.db.sql(""" select name, price_list_rate, uom return frappe.db.sql(""" select name, price_list_rate, uom
from `tabItem Price` {conditions} from `tabItem Price` {conditions}
order by valid_from desc, min_qty desc, uom desc """.format(conditions=conditions), args) order by valid_from desc, uom desc """.format(conditions=conditions), args)
def get_price_list_rate_for(args, item_code): def get_price_list_rate_for(args, item_code):
""" """
Return Price Rate based on min_qty of each Item Price Rate.\
For example, desired qty is 10 and Item Price Rates exists
for min_qty 9 and min_qty 20. It returns Item Price Rate for qty 9 as
the best fit in the range of avaliable min_qtyies
:param customer: link to Customer DocType :param customer: link to Customer DocType
:param supplier: link to Supplier DocType :param supplier: link to Supplier DocType
:param price_list: str (Standard Buying or Standard Selling) :param price_list: str (Standard Buying or Standard Selling)
@@ -630,8 +622,6 @@ def get_price_list_rate_for(args, item_code):
"customer": args.get('customer'), "customer": args.get('customer'),
"supplier": args.get('supplier'), "supplier": args.get('supplier'),
"uom": args.get('uom'), "uom": args.get('uom'),
"min_qty": args.get('qty') if args.get('price_list_uom_dependant')\
else flt(args.get('qty')) * flt(args.get("conversion_factor", 1)),
"transaction_date": args.get('transaction_date'), "transaction_date": args.get('transaction_date'),
} }
@@ -647,9 +637,6 @@ def get_price_list_rate_for(args, item_code):
general_price_list_rate = get_item_price(item_price_args, item_code, general_price_list_rate = get_item_price(item_price_args, item_code,
ignore_party=args.get("ignore_party")) ignore_party=args.get("ignore_party"))
if not general_price_list_rate:
del item_price_args["min_qty"]
general_price_list_rate = get_item_price(item_price_args, item_code, ignore_party=args.get("ignore_party"))
if not general_price_list_rate and args.get("uom") != args.get("stock_uom"): if not general_price_list_rate and args.get("uom") != args.get("stock_uom"):
item_price_args["uom"] = args.get("stock_uom") item_price_args["uom"] = args.get("stock_uom")