refactor: pass typed arguments to get_item_details methods (#44230)
* refactor: pass proper types to get_item_details methods * chore: excempt previous commit from git blame
This commit is contained in:
@@ -41,3 +41,4 @@ a308792ee7fda18a681e9181f4fd00b36385bc23
|
|||||||
|
|
||||||
# noisy typing refactoring of get_item_details
|
# noisy typing refactoring of get_item_details
|
||||||
7b7211ac79c248a79ba8a999ff34e734d874c0ae
|
7b7211ac79c248a79ba8a999ff34e734d874c0ae
|
||||||
|
d827ed21adc7b36047e247cbb0dc6388d048a7f9
|
||||||
|
|||||||
@@ -533,7 +533,11 @@ class POSInvoice(SalesInvoice):
|
|||||||
|
|
||||||
def set_pos_fields(self, for_validate=False):
|
def set_pos_fields(self, for_validate=False):
|
||||||
"""Set retail related fields from POS Profiles"""
|
"""Set retail related fields from POS Profiles"""
|
||||||
from erpnext.stock.get_item_details import get_pos_profile, get_pos_profile_item_details_
|
from erpnext.stock.get_item_details import (
|
||||||
|
ItemDetailsCtx,
|
||||||
|
get_pos_profile,
|
||||||
|
get_pos_profile_item_details_,
|
||||||
|
)
|
||||||
|
|
||||||
if not self.pos_profile:
|
if not self.pos_profile:
|
||||||
pos_profile = get_pos_profile(self.company) or {}
|
pos_profile = get_pos_profile(self.company) or {}
|
||||||
@@ -603,7 +607,7 @@ class POSInvoice(SalesInvoice):
|
|||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if item.get("item_code"):
|
if item.get("item_code"):
|
||||||
profile_details = get_pos_profile_item_details_(
|
profile_details = get_pos_profile_item_details_(
|
||||||
frappe._dict(item.as_dict()), profile.get("company"), profile
|
ItemDetailsCtx(item.as_dict()), profile.get("company"), profile
|
||||||
)
|
)
|
||||||
for fname, val in profile_details.items():
|
for fname, val in profile_details.items():
|
||||||
if (not for_validate) or (for_validate and not item.get(fname)):
|
if (not for_validate) or (for_validate and not item.get(fname)):
|
||||||
|
|||||||
@@ -766,7 +766,11 @@ class SalesInvoice(SellingController):
|
|||||||
"Company", self.company, "default_cash_account"
|
"Company", self.company, "default_cash_account"
|
||||||
)
|
)
|
||||||
|
|
||||||
from erpnext.stock.get_item_details import get_pos_profile, get_pos_profile_item_details_
|
from erpnext.stock.get_item_details import (
|
||||||
|
ItemDetailsCtx,
|
||||||
|
get_pos_profile,
|
||||||
|
get_pos_profile_item_details_,
|
||||||
|
)
|
||||||
|
|
||||||
if not self.pos_profile and not self.flags.ignore_pos_profile:
|
if not self.pos_profile and not self.flags.ignore_pos_profile:
|
||||||
pos_profile = get_pos_profile(self.company) or {}
|
pos_profile = get_pos_profile(self.company) or {}
|
||||||
@@ -835,7 +839,7 @@ class SalesInvoice(SellingController):
|
|||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if item.get("item_code"):
|
if item.get("item_code"):
|
||||||
profile_details = get_pos_profile_item_details_(
|
profile_details = get_pos_profile_item_details_(
|
||||||
frappe._dict(item.as_dict()), pos, pos, update_data=True
|
ItemDetailsCtx(item.as_dict()), pos, pos, update_data=True
|
||||||
)
|
)
|
||||||
for fname, val in profile_details.items():
|
for fname, val in profile_details.items():
|
||||||
if (not for_validate) or (for_validate and not item.get(fname)):
|
if (not for_validate) or (for_validate and not item.get(fname)):
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
|||||||
from erpnext.stock import get_warehouse_account_map
|
from erpnext.stock import get_warehouse_account_map
|
||||||
from erpnext.stock.doctype.item.item import get_item_defaults
|
from erpnext.stock.doctype.item.item import get_item_defaults
|
||||||
from erpnext.stock.get_item_details import (
|
from erpnext.stock.get_item_details import (
|
||||||
|
ItemDetailsCtx,
|
||||||
get_default_cost_center,
|
get_default_cost_center,
|
||||||
get_default_expense_account,
|
get_default_expense_account,
|
||||||
get_item_warehouse_,
|
get_item_warehouse_,
|
||||||
@@ -748,7 +749,7 @@ def get_target_item_details(item_code=None, company=None):
|
|||||||
item_group_defaults = get_item_group_defaults(item.name, company)
|
item_group_defaults = get_item_group_defaults(item.name, company)
|
||||||
brand_defaults = get_brand_defaults(item.name, company)
|
brand_defaults = get_brand_defaults(item.name, company)
|
||||||
out.cost_center = get_default_cost_center(
|
out.cost_center = get_default_cost_center(
|
||||||
frappe._dict({"item_code": item.name, "company": company}),
|
ItemDetailsCtx({"item_code": item.name, "company": company}),
|
||||||
item_defaults,
|
item_defaults,
|
||||||
item_group_defaults,
|
item_group_defaults,
|
||||||
brand_defaults,
|
brand_defaults,
|
||||||
@@ -785,45 +786,42 @@ def get_target_asset_details(asset=None, company=None):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_consumed_stock_item_details(args_):
|
@erpnext.normalize_ctx_input(ItemDetailsCtx)
|
||||||
if isinstance(args_, str):
|
def get_consumed_stock_item_details(ctx: ItemDetailsCtx):
|
||||||
args_ = json.loads(args_)
|
|
||||||
|
|
||||||
args = frappe._dict(args_)
|
|
||||||
out = frappe._dict()
|
out = frappe._dict()
|
||||||
|
|
||||||
item = frappe._dict()
|
item = frappe._dict()
|
||||||
if args.item_code:
|
if ctx.item_code:
|
||||||
item = frappe.get_cached_doc("Item", args.item_code)
|
item = frappe.get_cached_doc("Item", ctx.item_code)
|
||||||
|
|
||||||
out.item_name = item.item_name
|
out.item_name = item.item_name
|
||||||
out.batch_no = None
|
out.batch_no = None
|
||||||
out.serial_no = ""
|
out.serial_no = ""
|
||||||
|
|
||||||
out.stock_qty = flt(args.stock_qty) or 1
|
out.stock_qty = flt(ctx.stock_qty) or 1
|
||||||
out.stock_uom = item.stock_uom
|
out.stock_uom = item.stock_uom
|
||||||
|
|
||||||
out.warehouse = get_item_warehouse_(args, item, overwrite_warehouse=True) if item else None
|
out.warehouse = get_item_warehouse_(ctx, item, overwrite_warehouse=True) if item else None
|
||||||
|
|
||||||
# Cost Center
|
# Cost Center
|
||||||
item_defaults = get_item_defaults(item.name, args.company)
|
item_defaults = get_item_defaults(item.name, ctx.company)
|
||||||
item_group_defaults = get_item_group_defaults(item.name, args.company)
|
item_group_defaults = get_item_group_defaults(item.name, ctx.company)
|
||||||
brand_defaults = get_brand_defaults(item.name, args.company)
|
brand_defaults = get_brand_defaults(item.name, ctx.company)
|
||||||
out.cost_center = get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults)
|
out.cost_center = get_default_cost_center(ctx, item_defaults, item_group_defaults, brand_defaults)
|
||||||
|
|
||||||
if args.item_code and out.warehouse:
|
if ctx.item_code and out.warehouse:
|
||||||
incoming_rate_args = frappe._dict(
|
incoming_rate_args = frappe._dict(
|
||||||
{
|
{
|
||||||
"item_code": args.item_code,
|
"item_code": ctx.item_code,
|
||||||
"warehouse": out.warehouse,
|
"warehouse": out.warehouse,
|
||||||
"posting_date": args.posting_date,
|
"posting_date": ctx.posting_date,
|
||||||
"posting_time": args.posting_time,
|
"posting_time": ctx.posting_time,
|
||||||
"qty": -1 * flt(out.stock_qty),
|
"qty": -1 * flt(out.stock_qty),
|
||||||
"voucher_type": args.doctype,
|
"voucher_type": ctx.doctype,
|
||||||
"voucher_no": args.name,
|
"voucher_no": ctx.name,
|
||||||
"company": args.company,
|
"company": ctx.company,
|
||||||
"serial_no": args.serial_no,
|
"serial_no": ctx.serial_no,
|
||||||
"batch_no": args.batch_no,
|
"batch_no": ctx.batch_no,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
out.update(get_warehouse_details(incoming_rate_args))
|
out.update(get_warehouse_details(incoming_rate_args))
|
||||||
@@ -851,31 +849,28 @@ def get_warehouse_details(args):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_consumed_asset_details(args):
|
@erpnext.normalize_ctx_input(ItemDetailsCtx)
|
||||||
if isinstance(args, str):
|
def get_consumed_asset_details(ctx):
|
||||||
args = json.loads(args)
|
|
||||||
|
|
||||||
args = frappe._dict(args)
|
|
||||||
out = frappe._dict()
|
out = frappe._dict()
|
||||||
|
|
||||||
asset_details = frappe._dict()
|
asset_details = frappe._dict()
|
||||||
if args.asset:
|
if ctx.asset:
|
||||||
asset_details = frappe.db.get_value(
|
asset_details = frappe.db.get_value(
|
||||||
"Asset", args.asset, ["asset_name", "item_code", "item_name"], as_dict=1
|
"Asset", ctx.asset, ["asset_name", "item_code", "item_name"], as_dict=1
|
||||||
)
|
)
|
||||||
if not asset_details:
|
if not asset_details:
|
||||||
frappe.throw(_("Asset {0} does not exist").format(args.asset))
|
frappe.throw(_("Asset {0} does not exist").format(ctx.asset))
|
||||||
|
|
||||||
out.item_code = asset_details.item_code
|
out.item_code = asset_details.item_code
|
||||||
out.asset_name = asset_details.asset_name
|
out.asset_name = asset_details.asset_name
|
||||||
out.item_name = asset_details.item_name
|
out.item_name = asset_details.item_name
|
||||||
|
|
||||||
if args.asset:
|
if ctx.asset:
|
||||||
out.current_asset_value = flt(
|
out.current_asset_value = flt(
|
||||||
get_asset_value_after_depreciation(args.asset, finance_book=args.finance_book)
|
get_asset_value_after_depreciation(ctx.asset, finance_book=ctx.finance_book)
|
||||||
)
|
)
|
||||||
out.asset_value = get_value_after_depreciation_on_disposal_date(
|
out.asset_value = get_value_after_depreciation_on_disposal_date(
|
||||||
args.asset, args.posting_date, finance_book=args.finance_book
|
ctx.asset, ctx.posting_date, finance_book=ctx.finance_book
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
out.current_asset_value = 0
|
out.current_asset_value = 0
|
||||||
@@ -884,7 +879,7 @@ def get_consumed_asset_details(args):
|
|||||||
# Account
|
# Account
|
||||||
if asset_details.item_code:
|
if asset_details.item_code:
|
||||||
out.fixed_asset_account = get_asset_category_account(
|
out.fixed_asset_account = get_asset_category_account(
|
||||||
"fixed_asset_account", item=asset_details.item_code, company=args.company
|
"fixed_asset_account", item=asset_details.item_code, company=ctx.company
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
out.fixed_asset_account = None
|
out.fixed_asset_account = None
|
||||||
@@ -892,37 +887,32 @@ def get_consumed_asset_details(args):
|
|||||||
# Cost Center
|
# Cost Center
|
||||||
if asset_details.item_code:
|
if asset_details.item_code:
|
||||||
item = frappe.get_cached_doc("Item", asset_details.item_code)
|
item = frappe.get_cached_doc("Item", asset_details.item_code)
|
||||||
item_defaults = get_item_defaults(item.name, args.company)
|
item_defaults = get_item_defaults(item.name, ctx.company)
|
||||||
item_group_defaults = get_item_group_defaults(item.name, args.company)
|
item_group_defaults = get_item_group_defaults(item.name, ctx.company)
|
||||||
brand_defaults = get_brand_defaults(item.name, args.company)
|
brand_defaults = get_brand_defaults(item.name, ctx.company)
|
||||||
out.cost_center = get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults)
|
out.cost_center = get_default_cost_center(ctx, item_defaults, item_group_defaults, brand_defaults)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_service_item_details(args):
|
@erpnext.normalize_ctx_input(ItemDetailsCtx)
|
||||||
if isinstance(args, str):
|
def get_service_item_details(ctx):
|
||||||
args = json.loads(args)
|
|
||||||
|
|
||||||
args = frappe._dict(args)
|
|
||||||
out = frappe._dict()
|
out = frappe._dict()
|
||||||
|
|
||||||
item = frappe._dict()
|
item = frappe._dict()
|
||||||
if args.item_code:
|
if ctx.item_code:
|
||||||
item = frappe.get_cached_doc("Item", args.item_code)
|
item = frappe.get_cached_doc("Item", ctx.item_code)
|
||||||
|
|
||||||
out.item_name = item.item_name
|
out.item_name = item.item_name
|
||||||
out.qty = flt(args.qty) or 1
|
out.qty = flt(ctx.qty) or 1
|
||||||
out.uom = item.purchase_uom or item.stock_uom
|
out.uom = item.purchase_uom or item.stock_uom
|
||||||
|
|
||||||
item_defaults = get_item_defaults(item.name, args.company)
|
item_defaults = get_item_defaults(item.name, ctx.company)
|
||||||
item_group_defaults = get_item_group_defaults(item.name, args.company)
|
item_group_defaults = get_item_group_defaults(item.name, ctx.company)
|
||||||
brand_defaults = get_brand_defaults(item.name, args.company)
|
brand_defaults = get_brand_defaults(item.name, ctx.company)
|
||||||
|
|
||||||
out.expense_account = get_default_expense_account(
|
out.expense_account = get_default_expense_account(ctx, item_defaults, item_group_defaults, brand_defaults)
|
||||||
args, item_defaults, item_group_defaults, brand_defaults
|
out.cost_center = get_default_cost_center(ctx, item_defaults, item_group_defaults, brand_defaults)
|
||||||
)
|
|
||||||
out.cost_center = get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults)
|
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ from erpnext.setup.utils import get_exchange_rate
|
|||||||
from erpnext.stock.doctype.item.item import get_uom_conv_factor
|
from erpnext.stock.doctype.item.item import get_uom_conv_factor
|
||||||
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
||||||
from erpnext.stock.get_item_details import (
|
from erpnext.stock.get_item_details import (
|
||||||
|
ItemDetailsCtx,
|
||||||
_get_item_tax_template,
|
_get_item_tax_template,
|
||||||
get_conversion_factor,
|
get_conversion_factor,
|
||||||
get_item_details,
|
get_item_details,
|
||||||
@@ -752,24 +753,28 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if item.get("item_code"):
|
if item.get("item_code"):
|
||||||
args = parent_dict.copy()
|
ctx: ItemDetailsCtx = ItemDetailsCtx(parent_dict.copy())
|
||||||
args.update(item.as_dict())
|
ctx.update(item.as_dict())
|
||||||
|
|
||||||
args["doctype"] = self.doctype
|
ctx.update(
|
||||||
args["name"] = self.name
|
{
|
||||||
args["child_doctype"] = item.doctype
|
"doctype": self.doctype,
|
||||||
args["child_docname"] = item.name
|
"name": self.name,
|
||||||
args["ignore_pricing_rule"] = (
|
"child_doctype": item.doctype,
|
||||||
self.ignore_pricing_rule if hasattr(self, "ignore_pricing_rule") else 0
|
"child_docname": item.name,
|
||||||
|
"ignore_pricing_rule": (
|
||||||
|
self.ignore_pricing_rule if hasattr(self, "ignore_pricing_rule") else 0
|
||||||
|
),
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if not args.get("transaction_date"):
|
if not ctx.transaction_date:
|
||||||
args["transaction_date"] = args.get("posting_date")
|
ctx.transaction_date = ctx.posting_date
|
||||||
|
|
||||||
if self.get("is_subcontracted"):
|
if self.get("is_subcontracted"):
|
||||||
args["is_subcontracted"] = self.is_subcontracted
|
ctx.is_subcontracted = self.is_subcontracted
|
||||||
|
|
||||||
ret = get_item_details(args, self, for_validate=for_validate, overwrite_warehouse=False)
|
ret = get_item_details(ctx, self, for_validate=for_validate, overwrite_warehouse=False)
|
||||||
for fieldname, value in ret.items():
|
for fieldname, value in ret.items():
|
||||||
if item.meta.get_field(fieldname) and value is not None:
|
if item.meta.get_field(fieldname) and value is not None:
|
||||||
if item.get(fieldname) is None or fieldname in force_item_fields:
|
if item.get(fieldname) is None or fieldname in force_item_fields:
|
||||||
@@ -3161,14 +3166,16 @@ def get_supplier_block_status(party_name):
|
|||||||
|
|
||||||
|
|
||||||
def set_child_tax_template_and_map(item, child_item, parent_doc):
|
def set_child_tax_template_and_map(item, child_item, parent_doc):
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"item_code": item.item_code,
|
{
|
||||||
"posting_date": parent_doc.transaction_date,
|
"item_code": item.item_code,
|
||||||
"tax_category": parent_doc.get("tax_category"),
|
"posting_date": parent_doc.transaction_date,
|
||||||
"company": parent_doc.get("company"),
|
"tax_category": parent_doc.get("tax_category"),
|
||||||
}
|
"company": parent_doc.get("company"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
child_item.item_tax_template = _get_item_tax_template(args, item.taxes)
|
child_item.item_tax_template = _get_item_tax_template(ctx, item.taxes)
|
||||||
if child_item.get("item_tax_template"):
|
if child_item.get("item_tax_template"):
|
||||||
child_item.item_tax_rate = get_item_tax_map(
|
child_item.item_tax_rate = get_item_tax_map(
|
||||||
parent_doc.get("company"), child_item.item_tax_template, as_json=True
|
parent_doc.get("company"), child_item.item_tax_template, as_json=True
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from frappe.utils import nowdate, today, unique
|
|||||||
from pypika import Order
|
from pypika import Order
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.stock.get_item_details import _get_item_tax_template
|
from erpnext.stock.get_item_details import ItemDetailsCtx, _get_item_tax_template
|
||||||
|
|
||||||
|
|
||||||
# searches for active employees
|
# searches for active employees
|
||||||
@@ -813,14 +813,16 @@ def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
valid_from = filters.get("valid_from")
|
valid_from = filters.get("valid_from")
|
||||||
valid_from = valid_from[1] if isinstance(valid_from, list) else valid_from
|
valid_from = valid_from[1] if isinstance(valid_from, list) else valid_from
|
||||||
|
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"item_code": filters.get("item_code"),
|
{
|
||||||
"posting_date": valid_from,
|
"item_code": filters.get("item_code"),
|
||||||
"tax_category": filters.get("tax_category"),
|
"posting_date": valid_from,
|
||||||
"company": company,
|
"tax_category": filters.get("tax_category"),
|
||||||
}
|
"company": company,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
taxes = _get_item_tax_template(args, taxes, for_validate=True)
|
taxes = _get_item_tax_template(ctx, taxes, for_validate=True)
|
||||||
return [(d,) for d in set(taxes)]
|
return [(d,) for d in set(taxes)]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from erpnext.controllers.accounts_controller import (
|
|||||||
validate_inclusive_tax,
|
validate_inclusive_tax,
|
||||||
validate_taxes_and_charges,
|
validate_taxes_and_charges,
|
||||||
)
|
)
|
||||||
from erpnext.stock.get_item_details import _get_item_tax_template
|
from erpnext.stock.get_item_details import ItemDetailsCtx, _get_item_tax_template
|
||||||
from erpnext.utilities.regional import temporary_flag
|
from erpnext.utilities.regional import temporary_flag
|
||||||
|
|
||||||
logger = frappe.logger(__name__)
|
logger = frappe.logger(__name__)
|
||||||
@@ -103,15 +103,17 @@ class calculate_taxes_and_totals:
|
|||||||
for item in self.doc.items:
|
for item in self.doc.items:
|
||||||
if item.item_code and item.get("item_tax_template"):
|
if item.item_code and item.get("item_tax_template"):
|
||||||
item_doc = frappe.get_cached_doc("Item", item.item_code)
|
item_doc = frappe.get_cached_doc("Item", item.item_code)
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"net_rate": item.net_rate or item.rate,
|
{
|
||||||
"base_net_rate": item.base_net_rate or item.base_rate,
|
"net_rate": item.net_rate or item.rate,
|
||||||
"tax_category": self.doc.get("tax_category"),
|
"base_net_rate": item.base_net_rate or item.base_rate,
|
||||||
"posting_date": self.doc.get("posting_date"),
|
"tax_category": self.doc.get("tax_category"),
|
||||||
"bill_date": self.doc.get("bill_date"),
|
"posting_date": self.doc.get("posting_date"),
|
||||||
"transaction_date": self.doc.get("transaction_date"),
|
"bill_date": self.doc.get("bill_date"),
|
||||||
"company": self.doc.get("company"),
|
"transaction_date": self.doc.get("transaction_date"),
|
||||||
}
|
"company": self.doc.get("company"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
item_group = item_doc.item_group
|
item_group = item_doc.item_group
|
||||||
item_group_taxes = []
|
item_group_taxes = []
|
||||||
@@ -127,7 +129,7 @@ class calculate_taxes_and_totals:
|
|||||||
# No validation if no taxes in item or item group
|
# No validation if no taxes in item or item group
|
||||||
continue
|
continue
|
||||||
|
|
||||||
taxes = _get_item_tax_template(args, item_taxes + item_group_taxes, for_validate=True)
|
taxes = _get_item_tax_template(ctx, item_taxes + item_group_taxes, for_validate=True)
|
||||||
|
|
||||||
if taxes:
|
if taxes:
|
||||||
if item.item_tax_template not in taxes:
|
if item.item_tax_template not in taxes:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from frappe.website.website_generator import WebsiteGenerator
|
|||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.setup.utils import get_exchange_rate
|
from erpnext.setup.utils import get_exchange_rate
|
||||||
from erpnext.stock.doctype.item.item import get_item_details
|
from erpnext.stock.doctype.item.item import get_item_details
|
||||||
from erpnext.stock.get_item_details import get_conversion_factor, get_price_list_rate
|
from erpnext.stock.get_item_details import ItemDetailsCtx, get_conversion_factor, get_price_list_rate
|
||||||
|
|
||||||
form_grid_templates = {"items": "templates/form_grid/item_grid.html"}
|
form_grid_templates = {"items": "templates/form_grid/item_grid.html"}
|
||||||
|
|
||||||
@@ -1052,7 +1052,7 @@ def get_bom_item_rate(args, bom_doc):
|
|||||||
elif bom_doc.rm_cost_as_per == "Price List":
|
elif bom_doc.rm_cost_as_per == "Price List":
|
||||||
if not bom_doc.buying_price_list:
|
if not bom_doc.buying_price_list:
|
||||||
frappe.throw(_("Please select Price List"))
|
frappe.throw(_("Please select Price List"))
|
||||||
bom_args = frappe._dict(
|
ctx = ItemDetailsCtx(
|
||||||
{
|
{
|
||||||
"doctype": "BOM",
|
"doctype": "BOM",
|
||||||
"price_list": bom_doc.buying_price_list,
|
"price_list": bom_doc.buying_price_list,
|
||||||
@@ -1070,7 +1070,7 @@ def get_bom_item_rate(args, bom_doc):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
item_doc = frappe.get_cached_doc("Item", args.get("item_code"))
|
item_doc = frappe.get_cached_doc("Item", args.get("item_code"))
|
||||||
price_list_data = get_price_list_rate(bom_args, item_doc)
|
price_list_data = get_price_list_rate(ctx, item_doc)
|
||||||
rate = price_list_data.price_list_rate
|
rate = price_list_data.price_list_rate
|
||||||
|
|
||||||
return flt(rate)
|
return flt(rate)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class TestQuotation(IntegrationTestCase):
|
|||||||
def test_gross_profit(self):
|
def test_gross_profit(self):
|
||||||
from erpnext.stock.doctype.item.test_item import make_item
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||||
from erpnext.stock.get_item_details import insert_item_price
|
from erpnext.stock.get_item_details import ItemDetailsCtx, insert_item_price
|
||||||
|
|
||||||
item_doc = make_item("_Test Item for Gross Profit", {"is_stock_item": 1})
|
item_doc = make_item("_Test Item for Gross Profit", {"is_stock_item": 1})
|
||||||
item_code = item_doc.name
|
item_code = item_doc.name
|
||||||
@@ -63,7 +63,7 @@ class TestQuotation(IntegrationTestCase):
|
|||||||
selling_price_list = frappe.get_all("Price List", filters={"selling": 1}, limit=1)[0].name
|
selling_price_list = frappe.get_all("Price List", filters={"selling": 1}, limit=1)[0].name
|
||||||
frappe.db.set_single_value("Stock Settings", "auto_insert_price_list_rate_if_missing", 1)
|
frappe.db.set_single_value("Stock Settings", "auto_insert_price_list_rate_if_missing", 1)
|
||||||
insert_item_price(
|
insert_item_price(
|
||||||
frappe._dict(
|
ItemDetailsCtx(
|
||||||
{
|
{
|
||||||
"item_code": item_code,
|
"item_code": item_code,
|
||||||
"price_list": selling_price_list,
|
"price_list": selling_price_list,
|
||||||
|
|||||||
@@ -35,7 +35,12 @@ from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry impor
|
|||||||
get_sre_reserved_qty_details_for_voucher,
|
get_sre_reserved_qty_details_for_voucher,
|
||||||
has_reserved_stock,
|
has_reserved_stock,
|
||||||
)
|
)
|
||||||
from erpnext.stock.get_item_details import get_bin_details, get_default_bom, get_price_list_rate
|
from erpnext.stock.get_item_details import (
|
||||||
|
ItemDetailsCtx,
|
||||||
|
get_bin_details,
|
||||||
|
get_default_bom,
|
||||||
|
get_price_list_rate,
|
||||||
|
)
|
||||||
from erpnext.stock.stock_balance import get_reserved_qty, update_bin_qty
|
from erpnext.stock.stock_balance import get_reserved_qty, update_bin_qty
|
||||||
|
|
||||||
form_grid_templates = {"items": "templates/form_grid/item_grid.html"}
|
form_grid_templates = {"items": "templates/form_grid/item_grid.html"}
|
||||||
@@ -849,8 +854,8 @@ def make_material_request(source_name, target_doc=None):
|
|||||||
target.item_code, target.warehouse, source_parent.company, True
|
target.item_code, target.warehouse, source_parent.company, True
|
||||||
).get("actual_qty", 0)
|
).get("actual_qty", 0)
|
||||||
|
|
||||||
args = target.as_dict().copy()
|
ctx = ItemDetailsCtx(target.as_dict().copy())
|
||||||
args.update(
|
ctx.update(
|
||||||
{
|
{
|
||||||
"company": source_parent.get("company"),
|
"company": source_parent.get("company"),
|
||||||
"price_list": frappe.db.get_single_value("Buying Settings", "buying_price_list"),
|
"price_list": frappe.db.get_single_value("Buying Settings", "buying_price_list"),
|
||||||
@@ -860,7 +865,7 @@ def make_material_request(source_name, target_doc=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
target.rate = flt(
|
target.rate = flt(
|
||||||
get_price_list_rate(args, item_doc=frappe.get_cached_doc("Item", target.item_code)).get(
|
get_price_list_rate(ctx, item_doc=frappe.get_cached_doc("Item", target.item_code)).get(
|
||||||
"price_list_rate"
|
"price_list_rate"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle
|
|||||||
get_batch_from_bundle,
|
get_batch_from_bundle,
|
||||||
)
|
)
|
||||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||||
from erpnext.stock.get_item_details import get_item_details
|
from erpnext.stock.get_item_details import ItemDetailsCtx, get_item_details
|
||||||
from erpnext.stock.serial_batch_bundle import SerialBatchCreation
|
from erpnext.stock.serial_batch_bundle import SerialBatchCreation
|
||||||
|
|
||||||
|
|
||||||
@@ -436,7 +436,7 @@ class TestBatch(IntegrationTestCase):
|
|||||||
company = "_Test Company with perpetual inventory"
|
company = "_Test Company with perpetual inventory"
|
||||||
currency = frappe.get_cached_value("Company", company, "default_currency")
|
currency = frappe.get_cached_value("Company", company, "default_currency")
|
||||||
|
|
||||||
args = frappe._dict(
|
ctx = ItemDetailsCtx(
|
||||||
{
|
{
|
||||||
"item_code": "_Test Batch Price Item",
|
"item_code": "_Test Batch Price Item",
|
||||||
"company": company,
|
"company": company,
|
||||||
@@ -452,18 +452,18 @@ class TestBatch(IntegrationTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# test price for batch1
|
# test price for batch1
|
||||||
args.update({"batch_no": batch1})
|
ctx.update({"batch_no": batch1})
|
||||||
details = get_item_details(args)
|
details = get_item_details(ctx)
|
||||||
self.assertEqual(details.get("price_list_rate"), 200)
|
self.assertEqual(details.get("price_list_rate"), 200)
|
||||||
|
|
||||||
# test price for batch2
|
# test price for batch2
|
||||||
args.update({"batch_no": batch2})
|
ctx.update({"batch_no": batch2})
|
||||||
details = get_item_details(args)
|
details = get_item_details(ctx)
|
||||||
self.assertEqual(details.get("price_list_rate"), 300)
|
self.assertEqual(details.get("price_list_rate"), 300)
|
||||||
|
|
||||||
# test price for batch3
|
# test price for batch3
|
||||||
args.update({"batch_no": batch3})
|
ctx.update({"batch_no": batch3})
|
||||||
details = get_item_details(args)
|
details = get_item_details(ctx)
|
||||||
self.assertEqual(details.get("price_list_rate"), 400)
|
self.assertEqual(details.get("price_list_rate"), 400)
|
||||||
|
|
||||||
def test_basic_batch_wise_valuation(self, batch_qty=100):
|
def test_basic_batch_wise_valuation(self, batch_qty=100):
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ from erpnext.stock.doctype.item.item import (
|
|||||||
validate_is_stock_item,
|
validate_is_stock_item,
|
||||||
)
|
)
|
||||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||||
from erpnext.stock.get_item_details import get_item_details
|
from erpnext.stock.get_item_details import ItemDetailsCtx, get_item_details
|
||||||
|
|
||||||
IGNORE_TEST_RECORD_DEPENDENCIES = ["BOM"]
|
IGNORE_TEST_RECORD_DEPENDENCIES = ["BOM"]
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Warehouse", "Item Group", "Item Tax Template", "Brand", "Item Attribute"]
|
EXTRA_TEST_RECORD_DEPENDENCIES = ["Warehouse", "Item Group", "Item Tax Template", "Brand", "Item Attribute"]
|
||||||
@@ -145,21 +145,23 @@ class TestItem(IntegrationTestCase):
|
|||||||
currency = frappe.get_cached_value("Company", company, "default_currency")
|
currency = frappe.get_cached_value("Company", company, "default_currency")
|
||||||
|
|
||||||
details = get_item_details(
|
details = get_item_details(
|
||||||
{
|
ItemDetailsCtx(
|
||||||
"item_code": "_Test Item",
|
{
|
||||||
"company": company,
|
"item_code": "_Test Item",
|
||||||
"price_list": "_Test Price List",
|
"company": company,
|
||||||
"currency": currency,
|
"price_list": "_Test Price List",
|
||||||
"doctype": "Sales Order",
|
"currency": currency,
|
||||||
"conversion_rate": 1,
|
"doctype": "Sales Order",
|
||||||
"price_list_currency": currency,
|
"conversion_rate": 1,
|
||||||
"plc_conversion_rate": 1,
|
"price_list_currency": currency,
|
||||||
"order_type": "Sales",
|
"plc_conversion_rate": 1,
|
||||||
"customer": "_Test Customer",
|
"order_type": "Sales",
|
||||||
"conversion_factor": 1,
|
"customer": "_Test Customer",
|
||||||
"price_list_uom_dependant": 1,
|
"conversion_factor": 1,
|
||||||
"ignore_pricing_rule": 1,
|
"price_list_uom_dependant": 1,
|
||||||
}
|
"ignore_pricing_rule": 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
for key, value in to_check.items():
|
for key, value in to_check.items():
|
||||||
@@ -172,23 +174,27 @@ class TestItem(IntegrationTestCase):
|
|||||||
create_fixed_asset_item()
|
create_fixed_asset_item()
|
||||||
|
|
||||||
details = get_item_details(
|
details = get_item_details(
|
||||||
{
|
ItemDetailsCtx(
|
||||||
"item_code": "Macbook Pro",
|
{
|
||||||
"company": "_Test Company",
|
"item_code": "Macbook Pro",
|
||||||
"currency": "INR",
|
"company": "_Test Company",
|
||||||
"doctype": "Purchase Receipt",
|
"currency": "INR",
|
||||||
}
|
"doctype": "Purchase Receipt",
|
||||||
|
}
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(details.get("expense_account"), "_Test Fixed Asset - _TC")
|
self.assertEqual(details.get("expense_account"), "_Test Fixed Asset - _TC")
|
||||||
|
|
||||||
frappe.db.set_value("Asset Category", "Computers", "enable_cwip_accounting", "1")
|
frappe.db.set_value("Asset Category", "Computers", "enable_cwip_accounting", "1")
|
||||||
details = get_item_details(
|
details = get_item_details(
|
||||||
{
|
ItemDetailsCtx(
|
||||||
"item_code": "Macbook Pro",
|
{
|
||||||
"company": "_Test Company",
|
"item_code": "Macbook Pro",
|
||||||
"currency": "INR",
|
"company": "_Test Company",
|
||||||
"doctype": "Purchase Receipt",
|
"currency": "INR",
|
||||||
}
|
"doctype": "Purchase Receipt",
|
||||||
|
}
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(details.get("expense_account"), "CWIP Account - _TC")
|
self.assertEqual(details.get("expense_account"), "CWIP Account - _TC")
|
||||||
|
|
||||||
@@ -271,22 +277,24 @@ class TestItem(IntegrationTestCase):
|
|||||||
|
|
||||||
for data in expected_item_tax_template:
|
for data in expected_item_tax_template:
|
||||||
details = get_item_details(
|
details = get_item_details(
|
||||||
{
|
ItemDetailsCtx(
|
||||||
"item_code": data["item_code"],
|
{
|
||||||
"tax_category": data["tax_category"],
|
"item_code": data["item_code"],
|
||||||
"company": "_Test Company",
|
"tax_category": data["tax_category"],
|
||||||
"price_list": "_Test Price List",
|
"company": "_Test Company",
|
||||||
"currency": "_Test Currency",
|
"price_list": "_Test Price List",
|
||||||
"doctype": "Sales Order",
|
"currency": "_Test Currency",
|
||||||
"conversion_rate": 1,
|
"doctype": "Sales Order",
|
||||||
"price_list_currency": "_Test Currency",
|
"conversion_rate": 1,
|
||||||
"plc_conversion_rate": 1,
|
"price_list_currency": "_Test Currency",
|
||||||
"order_type": "Sales",
|
"plc_conversion_rate": 1,
|
||||||
"customer": "_Test Customer",
|
"order_type": "Sales",
|
||||||
"conversion_factor": 1,
|
"customer": "_Test Customer",
|
||||||
"price_list_uom_dependant": 1,
|
"conversion_factor": 1,
|
||||||
"ignore_pricing_rule": 1,
|
"price_list_uom_dependant": 1,
|
||||||
}
|
"ignore_pricing_rule": 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(details.item_tax_template, data["item_tax_template"])
|
self.assertEqual(details.item_tax_template, data["item_tax_template"])
|
||||||
@@ -320,17 +328,19 @@ class TestItem(IntegrationTestCase):
|
|||||||
"cost_center": "_Test Cost Center 2 - _TC", # from item group
|
"cost_center": "_Test Cost Center 2 - _TC", # from item group
|
||||||
}
|
}
|
||||||
sales_item_details = get_item_details(
|
sales_item_details = get_item_details(
|
||||||
{
|
ItemDetailsCtx(
|
||||||
"item_code": "Test Item With Defaults",
|
{
|
||||||
"company": "_Test Company",
|
"item_code": "Test Item With Defaults",
|
||||||
"price_list": "_Test Price List",
|
"company": "_Test Company",
|
||||||
"currency": "_Test Currency",
|
"price_list": "_Test Price List",
|
||||||
"doctype": "Sales Invoice",
|
"currency": "_Test Currency",
|
||||||
"conversion_rate": 1,
|
"doctype": "Sales Invoice",
|
||||||
"price_list_currency": "_Test Currency",
|
"conversion_rate": 1,
|
||||||
"plc_conversion_rate": 1,
|
"price_list_currency": "_Test Currency",
|
||||||
"customer": "_Test Customer",
|
"plc_conversion_rate": 1,
|
||||||
}
|
"customer": "_Test Customer",
|
||||||
|
}
|
||||||
|
)
|
||||||
)
|
)
|
||||||
for key, value in sales_item_check.items():
|
for key, value in sales_item_check.items():
|
||||||
self.assertEqual(value, sales_item_details.get(key))
|
self.assertEqual(value, sales_item_details.get(key))
|
||||||
@@ -343,17 +353,19 @@ class TestItem(IntegrationTestCase):
|
|||||||
"cost_center": "_Test Write Off Cost Center - _TC", # from item
|
"cost_center": "_Test Write Off Cost Center - _TC", # from item
|
||||||
}
|
}
|
||||||
purchase_item_details = get_item_details(
|
purchase_item_details = get_item_details(
|
||||||
{
|
ItemDetailsCtx(
|
||||||
"item_code": "Test Item With Defaults",
|
{
|
||||||
"company": "_Test Company",
|
"item_code": "Test Item With Defaults",
|
||||||
"price_list": "_Test Price List",
|
"company": "_Test Company",
|
||||||
"currency": "_Test Currency",
|
"price_list": "_Test Price List",
|
||||||
"doctype": "Purchase Invoice",
|
"currency": "_Test Currency",
|
||||||
"conversion_rate": 1,
|
"doctype": "Purchase Invoice",
|
||||||
"price_list_currency": "_Test Currency",
|
"conversion_rate": 1,
|
||||||
"plc_conversion_rate": 1,
|
"price_list_currency": "_Test Currency",
|
||||||
"supplier": "_Test Supplier",
|
"plc_conversion_rate": 1,
|
||||||
}
|
"supplier": "_Test Supplier",
|
||||||
|
}
|
||||||
|
)
|
||||||
)
|
)
|
||||||
for key, value in purchase_item_check.items():
|
for key, value in purchase_item_check.items():
|
||||||
self.assertEqual(value, purchase_item_details.get(key))
|
self.assertEqual(value, purchase_item_details.get(key))
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from frappe.tests import IntegrationTestCase, UnitTestCase
|
|||||||
from frappe.tests.utils import make_test_records_for_doctype
|
from frappe.tests.utils import make_test_records_for_doctype
|
||||||
|
|
||||||
from erpnext.stock.doctype.item_price.item_price import ItemPriceDuplicateItem
|
from erpnext.stock.doctype.item_price.item_price import ItemPriceDuplicateItem
|
||||||
from erpnext.stock.get_item_details import get_price_list_rate_for
|
from erpnext.stock.get_item_details import ItemDetailsCtx, get_price_list_rate_for
|
||||||
|
|
||||||
|
|
||||||
class UnitTestItemPrice(UnitTestCase):
|
class UnitTestItemPrice(UnitTestCase):
|
||||||
@@ -80,85 +80,97 @@ class TestItemPrice(IntegrationTestCase):
|
|||||||
# Check correct price at this quantity
|
# Check correct price at this quantity
|
||||||
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][2])
|
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][2])
|
||||||
|
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"price_list": doc.price_list,
|
{
|
||||||
"customer": doc.customer,
|
"price_list": doc.price_list,
|
||||||
"uom": "_Test UOM",
|
"customer": doc.customer,
|
||||||
"transaction_date": "2017-04-18",
|
"uom": "_Test UOM",
|
||||||
"qty": 10,
|
"transaction_date": "2017-04-18",
|
||||||
}
|
"qty": 10,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
price = get_price_list_rate_for(args, doc.item_code)
|
price = get_price_list_rate_for(ctx, doc.item_code)
|
||||||
self.assertEqual(price, 20.0)
|
self.assertEqual(price, 20.0)
|
||||||
|
|
||||||
def test_price_with_no_qty(self):
|
def test_price_with_no_qty(self):
|
||||||
# Check correct price when no quantity
|
# Check correct price when no quantity
|
||||||
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][2])
|
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][2])
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"price_list": doc.price_list,
|
{
|
||||||
"customer": doc.customer,
|
"price_list": doc.price_list,
|
||||||
"uom": "_Test UOM",
|
"customer": doc.customer,
|
||||||
"transaction_date": "2017-04-18",
|
"uom": "_Test UOM",
|
||||||
}
|
"transaction_date": "2017-04-18",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
price = get_price_list_rate_for(args, doc.item_code)
|
price = get_price_list_rate_for(ctx, doc.item_code)
|
||||||
self.assertEqual(price, None)
|
self.assertEqual(price, None)
|
||||||
|
|
||||||
def test_prices_at_date(self):
|
def test_prices_at_date(self):
|
||||||
# Check correct price at first date
|
# Check correct price at first date
|
||||||
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][2])
|
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][2])
|
||||||
|
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"price_list": doc.price_list,
|
{
|
||||||
"customer": "_Test Customer",
|
"price_list": doc.price_list,
|
||||||
"uom": "_Test UOM",
|
"customer": "_Test Customer",
|
||||||
"transaction_date": "2017-04-18",
|
"uom": "_Test UOM",
|
||||||
"qty": 7,
|
"transaction_date": "2017-04-18",
|
||||||
}
|
"qty": 7,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
price = get_price_list_rate_for(args, doc.item_code)
|
price = get_price_list_rate_for(ctx, doc.item_code)
|
||||||
self.assertEqual(price, 20)
|
self.assertEqual(price, 20)
|
||||||
|
|
||||||
def test_prices_at_invalid_date(self):
|
def test_prices_at_invalid_date(self):
|
||||||
# Check correct price at invalid date
|
# Check correct price at invalid date
|
||||||
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][3])
|
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][3])
|
||||||
|
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"price_list": doc.price_list,
|
{
|
||||||
"qty": 7,
|
"price_list": doc.price_list,
|
||||||
"uom": "_Test UOM",
|
"qty": 7,
|
||||||
"transaction_date": "01-15-2019",
|
"uom": "_Test UOM",
|
||||||
}
|
"transaction_date": "01-15-2019",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
price = get_price_list_rate_for(args, doc.item_code)
|
price = get_price_list_rate_for(ctx, doc.item_code)
|
||||||
self.assertEqual(price, None)
|
self.assertEqual(price, None)
|
||||||
|
|
||||||
def test_prices_outside_of_date(self):
|
def test_prices_outside_of_date(self):
|
||||||
# Check correct price when outside of the date
|
# Check correct price when outside of the date
|
||||||
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][4])
|
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][4])
|
||||||
|
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"price_list": doc.price_list,
|
{
|
||||||
"customer": "_Test Customer",
|
"price_list": doc.price_list,
|
||||||
"uom": "_Test UOM",
|
"customer": "_Test Customer",
|
||||||
"transaction_date": "2017-04-25",
|
"uom": "_Test UOM",
|
||||||
"qty": 7,
|
"transaction_date": "2017-04-25",
|
||||||
}
|
"qty": 7,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
price = get_price_list_rate_for(args, doc.item_code)
|
price = get_price_list_rate_for(ctx, doc.item_code)
|
||||||
self.assertEqual(price, None)
|
self.assertEqual(price, None)
|
||||||
|
|
||||||
def test_lowest_price_when_no_date_provided(self):
|
def test_lowest_price_when_no_date_provided(self):
|
||||||
# Check lowest price when no date provided
|
# Check lowest price when no date provided
|
||||||
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][1])
|
doc = frappe.copy_doc(self.globalTestRecords["Item Price"][1])
|
||||||
|
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"price_list": doc.price_list,
|
{
|
||||||
"uom": "_Test UOM",
|
"price_list": doc.price_list,
|
||||||
"qty": 7,
|
"uom": "_Test UOM",
|
||||||
}
|
"qty": 7,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
price = get_price_list_rate_for(args, doc.item_code)
|
price = get_price_list_rate_for(ctx, doc.item_code)
|
||||||
self.assertEqual(price, 10)
|
self.assertEqual(price, 10)
|
||||||
|
|
||||||
def test_invalid_item(self):
|
def test_invalid_item(self):
|
||||||
@@ -182,14 +194,16 @@ class TestItemPrice(IntegrationTestCase):
|
|||||||
doc.price_list_rate = 21
|
doc.price_list_rate = 21
|
||||||
doc.insert()
|
doc.insert()
|
||||||
|
|
||||||
args = {
|
ctx = ItemDetailsCtx(
|
||||||
"price_list": doc.price_list,
|
{
|
||||||
"uom": "_Test UOM",
|
"price_list": doc.price_list,
|
||||||
"transaction_date": "2017-04-18",
|
"uom": "_Test UOM",
|
||||||
"qty": 7,
|
"transaction_date": "2017-04-18",
|
||||||
}
|
"qty": 7,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
price = get_price_list_rate_for(args, doc.item_code)
|
price = get_price_list_rate_for(ctx, doc.item_code)
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
|
|
||||||
self.assertEqual(price, 21)
|
self.assertEqual(price, 21)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
|
|
||||||
from erpnext.stock.get_item_details import get_item_details, get_price_list_rate
|
from erpnext.stock.get_item_details import ItemDetailsCtx, get_item_details, get_price_list_rate
|
||||||
|
|
||||||
|
|
||||||
class PackedItem(Document):
|
class PackedItem(Document):
|
||||||
@@ -243,8 +243,8 @@ def update_packed_item_price_data(pi_row, item_data, doc):
|
|||||||
return
|
return
|
||||||
|
|
||||||
item_doc = frappe.get_cached_doc("Item", pi_row.item_code)
|
item_doc = frappe.get_cached_doc("Item", pi_row.item_code)
|
||||||
row_data = pi_row.as_dict().copy()
|
ctx = ItemDetailsCtx(pi_row.as_dict().copy())
|
||||||
row_data.update(
|
ctx.update(
|
||||||
{
|
{
|
||||||
"company": doc.get("company"),
|
"company": doc.get("company"),
|
||||||
"price_list": doc.get("selling_price_list"),
|
"price_list": doc.get("selling_price_list"),
|
||||||
@@ -252,10 +252,10 @@ def update_packed_item_price_data(pi_row, item_data, doc):
|
|||||||
"conversion_rate": doc.get("conversion_rate"),
|
"conversion_rate": doc.get("conversion_rate"),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if not row_data.get("transaction_date"):
|
if not ctx.transaction_date:
|
||||||
row_data.update({"transaction_date": doc.get("transaction_date")})
|
ctx.update({"transaction_date": doc.get("transaction_date")})
|
||||||
|
|
||||||
rate = get_price_list_rate(row_data, item_doc).get("price_list_rate")
|
rate = get_price_list_rate(ctx, item_doc).get("price_list_rate")
|
||||||
|
|
||||||
pi_row.rate = rate or item_data.get("valuation_rate") or 0.0
|
pi_row.rate = rate or item_data.get("valuation_rate") or 0.0
|
||||||
|
|
||||||
@@ -323,7 +323,7 @@ def on_doctype_update():
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_items_from_product_bundle(row):
|
def get_items_from_product_bundle(row):
|
||||||
row, items = json.loads(row), []
|
row, items = ItemDetailsCtx(json.loads(row)), []
|
||||||
|
|
||||||
bundled_items = get_product_bundle_items(row["item_code"])
|
bundled_items = get_product_bundle_items(row["item_code"])
|
||||||
for item in bundled_items:
|
for item in bundled_items:
|
||||||
|
|||||||
@@ -1618,7 +1618,7 @@ class TestPurchaseReceipt(IntegrationTestCase):
|
|||||||
self.assertTrue(return_pi.docstatus == 1)
|
self.assertTrue(return_pi.docstatus == 1)
|
||||||
|
|
||||||
def test_disable_last_purchase_rate(self):
|
def test_disable_last_purchase_rate(self):
|
||||||
from erpnext.stock.get_item_details import get_item_details
|
from erpnext.stock.get_item_details import ItemDetailsCtx, get_item_details
|
||||||
|
|
||||||
item = make_item(
|
item = make_item(
|
||||||
"_Test Disable Last Purchase Rate",
|
"_Test Disable Last Purchase Rate",
|
||||||
@@ -1633,8 +1633,8 @@ class TestPurchaseReceipt(IntegrationTestCase):
|
|||||||
item_code=item.name,
|
item_code=item.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
args = pr.items[0].as_dict()
|
ctx = ItemDetailsCtx(pr.items[0].as_dict())
|
||||||
args.update(
|
ctx.update(
|
||||||
{
|
{
|
||||||
"supplier": pr.supplier,
|
"supplier": pr.supplier,
|
||||||
"doctype": pr.doctype,
|
"doctype": pr.doctype,
|
||||||
@@ -1646,7 +1646,7 @@ class TestPurchaseReceipt(IntegrationTestCase):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
res = get_item_details(args)
|
res = get_item_details(ctx)
|
||||||
self.assertEqual(res.get("last_purchase_rate"), 0)
|
self.assertEqual(res.get("last_purchase_rate"), 0)
|
||||||
|
|
||||||
frappe.db.set_single_value("Buying Settings", "disable_last_purchase_rate", 0)
|
frappe.db.set_single_value("Buying Settings", "disable_last_purchase_rate", 0)
|
||||||
@@ -1657,7 +1657,7 @@ class TestPurchaseReceipt(IntegrationTestCase):
|
|||||||
item_code=item.name,
|
item_code=item.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
res = get_item_details(args)
|
res = get_item_details(ctx)
|
||||||
self.assertEqual(res.get("last_purchase_rate"), 100)
|
self.assertEqual(res.get("last_purchase_rate"), 100)
|
||||||
|
|
||||||
def test_validate_received_qty_for_internal_pr(self):
|
def test_validate_received_qty_for_internal_pr(self):
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import (
|
|||||||
OpeningEntryAccountError,
|
OpeningEntryAccountError,
|
||||||
)
|
)
|
||||||
from erpnext.stock.get_item_details import (
|
from erpnext.stock.get_item_details import (
|
||||||
|
ItemDetailsCtx,
|
||||||
get_barcode_data,
|
get_barcode_data,
|
||||||
get_bin_details,
|
get_bin_details,
|
||||||
get_conversion_factor,
|
get_conversion_factor,
|
||||||
@@ -1636,7 +1637,7 @@ class StockEntry(StockController):
|
|||||||
pro_doc.set_actual_dates()
|
pro_doc.set_actual_dates()
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_item_details(self, args=None, for_update=False):
|
def get_item_details(self, args: ItemDetailsCtx = None, for_update=False):
|
||||||
item = frappe.db.sql(
|
item = frappe.db.sql(
|
||||||
"""select i.name, i.stock_uom, i.description, i.image, i.item_name, i.item_group,
|
"""select i.name, i.stock_uom, i.description, i.image, i.item_name, i.item_group,
|
||||||
i.has_batch_no, i.sample_quantity, i.has_serial_no, i.allow_alternative_item,
|
i.has_batch_no, i.sample_quantity, i.has_serial_no, i.allow_alternative_item,
|
||||||
|
|||||||
Reference in New Issue
Block a user