mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-02 11:49:10 +00:00
Merge branch 'v12-pre-release' into version-12
This commit is contained in:
@@ -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'''
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
Reference in New Issue
Block a user