mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-06 05:39:12 +00:00
Merge pull request #39881 from frappe/version-14-hotfix
chore: release v14
This commit is contained in:
@@ -105,7 +105,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
"to_fiscal_year": data.fiscal_year
|
"to_fiscal_year": data.fiscal_year
|
||||||
};
|
};
|
||||||
|
|
||||||
if(data.based_on == 'cost_center'){
|
if(data.based_on == 'Cost Center'){
|
||||||
frappe.route_options["cost_center"] = data.account
|
frappe.route_options["cost_center"] = data.account
|
||||||
} else {
|
} else {
|
||||||
frappe.route_options["project"] = data.account
|
frappe.route_options["project"] = data.account
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ frappe.ui.form.on('Asset', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
make_schedules_editable: function(frm) {
|
make_schedules_editable: function(frm) {
|
||||||
if (frm.doc.finance_books.length) {
|
if (frm.doc.finance_books && frm.doc.finance_books.length) {
|
||||||
var is_manual_hence_editable = frm.doc.finance_books.filter(d => d.depreciation_method == "Manual").length > 0
|
var is_manual_hence_editable = frm.doc.finance_books.filter(d => d.depreciation_method == "Manual").length > 0
|
||||||
? true : false;
|
? true : false;
|
||||||
var is_shift_hence_editable = frm.doc.finance_books.filter(d => d.shift_based).length > 0
|
var is_shift_hence_editable = frm.doc.finance_books.filter(d => d.shift_based).length > 0
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ def modify_depreciation_schedule_for_asset_repairs(asset):
|
|||||||
|
|
||||||
|
|
||||||
def reverse_depreciation_entry_made_after_disposal(asset, date):
|
def reverse_depreciation_entry_made_after_disposal(asset, date):
|
||||||
if not asset.calculate_depreciation:
|
if not asset.calculate_depreciation or not asset.get("schedules"):
|
||||||
return
|
return
|
||||||
|
|
||||||
row = -1
|
row = -1
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ frappe.provide("erpnext.assets");
|
|||||||
erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.stock.StockController {
|
erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.stock.StockController {
|
||||||
setup() {
|
setup() {
|
||||||
this.setup_posting_date_time_check();
|
this.setup_posting_date_time_check();
|
||||||
|
this.frm.ignore_doctypes_on_cancel_all = ["Asset Movement"];
|
||||||
}
|
}
|
||||||
|
|
||||||
onload() {
|
onload() {
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ class AssetCapitalization(StockController):
|
|||||||
"Stock Ledger Entry",
|
"Stock Ledger Entry",
|
||||||
"Repost Item Valuation",
|
"Repost Item Valuation",
|
||||||
"Asset",
|
"Asset",
|
||||||
|
"Asset Movement"
|
||||||
)
|
)
|
||||||
self.cancel_target_asset()
|
self.cancel_target_asset()
|
||||||
self.update_stock_ledger()
|
self.update_stock_ledger()
|
||||||
@@ -86,6 +87,7 @@ class AssetCapitalization(StockController):
|
|||||||
def cancel_target_asset(self):
|
def cancel_target_asset(self):
|
||||||
if self.entry_type == "Capitalization" and self.target_asset:
|
if self.entry_type == "Capitalization" and self.target_asset:
|
||||||
asset_doc = frappe.get_doc("Asset", self.target_asset)
|
asset_doc = frappe.get_doc("Asset", self.target_asset)
|
||||||
|
asset_doc.db_set("capitalized_in", None)
|
||||||
if asset_doc.docstatus == 1:
|
if asset_doc.docstatus == 1:
|
||||||
asset_doc.cancel()
|
asset_doc.cancel()
|
||||||
|
|
||||||
|
|||||||
@@ -190,8 +190,8 @@ class BuyingController(SubcontractingController):
|
|||||||
lc_voucher_data = frappe.db.sql(
|
lc_voucher_data = frappe.db.sql(
|
||||||
"""select sum(applicable_charges), cost_center
|
"""select sum(applicable_charges), cost_center
|
||||||
from `tabLanded Cost Item`
|
from `tabLanded Cost Item`
|
||||||
where docstatus = 1 and purchase_receipt_item = %s""",
|
where docstatus = 1 and purchase_receipt_item = %s and receipt_document = %s""",
|
||||||
d.name,
|
(d.name, self.name),
|
||||||
)
|
)
|
||||||
d.landed_cost_voucher_amount = lc_voucher_data[0][0] if lc_voucher_data else 0.0
|
d.landed_cost_voucher_amount = lc_voucher_data[0][0] if lc_voucher_data else 0.0
|
||||||
if not d.cost_center and lc_voucher_data and lc_voucher_data[0][1]:
|
if not d.cost_center and lc_voucher_data and lc_voucher_data[0][1]:
|
||||||
|
|||||||
@@ -831,6 +831,9 @@ class StockController(AccountsController):
|
|||||||
"Stock Reconciliation",
|
"Stock Reconciliation",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not frappe.get_all("Putaway Rule", limit=1):
|
||||||
|
return
|
||||||
|
|
||||||
if self.doctype == "Purchase Invoice" and self.get("update_stock") == 0:
|
if self.doctype == "Purchase Invoice" and self.get("update_stock") == 0:
|
||||||
valid_doctype = False
|
valid_doctype = False
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ def make_order(source_name):
|
|||||||
def update_item(source, target, source_parent):
|
def update_item(source, target, source_parent):
|
||||||
target_qty = source.get("qty") - source.get("ordered_qty")
|
target_qty = source.get("qty") - source.get("ordered_qty")
|
||||||
target.qty = target_qty if not flt(target_qty) < 0 else 0
|
target.qty = target_qty if not flt(target_qty) < 0 else 0
|
||||||
|
target.rate = source.get("rate")
|
||||||
item = get_item_defaults(target.item_code, source_parent.company)
|
item = get_item_defaults(target.item_code, source_parent.company)
|
||||||
if item:
|
if item:
|
||||||
target.item_name = item.get("item_name")
|
target.item_name = item.get("item_name")
|
||||||
@@ -86,6 +87,10 @@ def make_order(source_name):
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if target_doc.doctype == "Purchase Order":
|
||||||
|
target_doc.set_missing_values()
|
||||||
|
|
||||||
return target_doc
|
return target_doc
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,8 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Item Code",
|
"label": "Item Code",
|
||||||
"options": "Item",
|
"options": "Item",
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_name",
|
||||||
@@ -53,7 +54,8 @@
|
|||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "For Warehouse",
|
"label": "For Warehouse",
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 1,
|
"columns": 1,
|
||||||
@@ -141,7 +143,8 @@
|
|||||||
"fieldname": "from_warehouse",
|
"fieldname": "from_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "From Warehouse",
|
"label": "From Warehouse",
|
||||||
"options": "Warehouse"
|
"options": "Warehouse",
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "item_code.safety_stock",
|
"fetch_from": "item_code.safety_stock",
|
||||||
@@ -199,7 +202,7 @@
|
|||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-09-12 12:09:08.358326",
|
"modified": "2024-02-11 16:21:11.977018",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Material Request Plan Item",
|
"name": "Material Request Plan Item",
|
||||||
|
|||||||
@@ -298,7 +298,8 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nClosed\nCancelled\nMaterial Requested",
|
"options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nClosed\nCancelled\nMaterial Requested",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
@@ -436,7 +437,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-12-26 16:31:13.740777",
|
"modified": "2024-02-11 15:42:47.642481",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Production Plan",
|
"name": "Production Plan",
|
||||||
|
|||||||
@@ -576,7 +576,10 @@ class ProductionPlan(Document):
|
|||||||
"project": self.project,
|
"project": self.project,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key = (d.item_code, d.sales_order, d.sales_order_item, d.warehouse)
|
||||||
|
if self.combine_items:
|
||||||
key = (d.item_code, d.sales_order, d.warehouse)
|
key = (d.item_code, d.sales_order, d.warehouse)
|
||||||
|
|
||||||
if not d.sales_order:
|
if not d.sales_order:
|
||||||
key = (d.name, d.item_code, d.warehouse)
|
key = (d.name, d.item_code, d.warehouse)
|
||||||
|
|
||||||
@@ -1691,23 +1694,23 @@ def get_reserved_qty_for_production_plan(item_code, warehouse):
|
|||||||
return reserved_qty_for_production_plan - reserved_qty_for_production
|
return reserved_qty_for_production_plan - reserved_qty_for_production
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.request_cache
|
||||||
def get_non_completed_production_plans():
|
def get_non_completed_production_plans():
|
||||||
table = frappe.qb.DocType("Production Plan")
|
table = frappe.qb.DocType("Production Plan")
|
||||||
child = frappe.qb.DocType("Production Plan Item")
|
child = frappe.qb.DocType("Production Plan Item")
|
||||||
|
|
||||||
query = (
|
return (
|
||||||
frappe.qb.from_(table)
|
frappe.qb.from_(table)
|
||||||
.inner_join(child)
|
.inner_join(child)
|
||||||
.on(table.name == child.parent)
|
.on(table.name == child.parent)
|
||||||
.select(table.name)
|
.select(table.name)
|
||||||
|
.distinct()
|
||||||
.where(
|
.where(
|
||||||
(table.docstatus == 1)
|
(table.docstatus == 1)
|
||||||
& (table.status.notin(["Completed", "Closed"]))
|
& (table.status.notin(["Completed", "Closed"]))
|
||||||
& (child.planned_qty > child.ordered_qty)
|
& (child.planned_qty > child.ordered_qty)
|
||||||
)
|
)
|
||||||
).run(as_dict=True)
|
).run(pluck="name")
|
||||||
|
|
||||||
return list(set([d.name for d in query]))
|
|
||||||
|
|
||||||
|
|
||||||
def get_raw_materials_of_sub_assembly_items(
|
def get_raw_materials_of_sub_assembly_items(
|
||||||
|
|||||||
@@ -448,7 +448,8 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Production Plan",
|
"options": "Production Plan",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "production_plan_item",
|
"fieldname": "production_plan_item",
|
||||||
@@ -600,7 +601,7 @@
|
|||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-08-11 18:35:49.852069",
|
"modified": "2024-02-11 15:47:13.454422",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Work Order",
|
"name": "Work Order",
|
||||||
|
|||||||
@@ -36,7 +36,8 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Item Code",
|
"label": "Item Code",
|
||||||
"options": "Item"
|
"options": "Item",
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "source_warehouse",
|
"fieldname": "source_warehouse",
|
||||||
@@ -141,7 +142,7 @@
|
|||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-09-28 10:50:43.512562",
|
"modified": "2024-02-11 15:45:32.318374",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Work Order Item",
|
"name": "Work Order Item",
|
||||||
|
|||||||
@@ -1047,6 +1047,7 @@ def validate_cancelled_item(item_code, docstatus=None):
|
|||||||
frappe.throw(_("Item {0} is cancelled").format(item_code))
|
frappe.throw(_("Item {0} is cancelled").format(item_code))
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.request_cache
|
||||||
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
|
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
|
||||||
"""returns last purchase details in stock uom"""
|
"""returns last purchase details in stock uom"""
|
||||||
# get last purchase order item details
|
# get last purchase order item details
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class LandedCostVoucher(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
self.check_mandatory()
|
self.check_mandatory()
|
||||||
self.validate_receipt_documents()
|
self.validate_receipt_documents()
|
||||||
|
self.validate_line_items()
|
||||||
init_landed_taxes_and_totals(self)
|
init_landed_taxes_and_totals(self)
|
||||||
self.set_total_taxes_and_charges()
|
self.set_total_taxes_and_charges()
|
||||||
if not self.get("items"):
|
if not self.get("items"):
|
||||||
@@ -45,6 +46,26 @@ class LandedCostVoucher(Document):
|
|||||||
|
|
||||||
self.set_applicable_charges_on_item()
|
self.set_applicable_charges_on_item()
|
||||||
|
|
||||||
|
def validate_line_items(self):
|
||||||
|
for d in self.get("items"):
|
||||||
|
if (
|
||||||
|
d.docstatus == 0
|
||||||
|
and d.purchase_receipt_item
|
||||||
|
and not frappe.db.exists(
|
||||||
|
d.receipt_document_type + " Item",
|
||||||
|
{"name": d.purchase_receipt_item, "parent": d.receipt_document},
|
||||||
|
)
|
||||||
|
):
|
||||||
|
frappe.throw(
|
||||||
|
_("Row {0}: {2} Item {1} does not exist in {2} {3}").format(
|
||||||
|
d.idx,
|
||||||
|
frappe.bold(d.purchase_receipt_item),
|
||||||
|
d.receipt_document_type,
|
||||||
|
frappe.bold(d.receipt_document),
|
||||||
|
),
|
||||||
|
title=_("Incorrect Reference Document (Purchase Receipt Item)"),
|
||||||
|
)
|
||||||
|
|
||||||
def check_mandatory(self):
|
def check_mandatory(self):
|
||||||
if not self.get("purchase_receipts"):
|
if not self.get("purchase_receipts"):
|
||||||
frappe.throw(_("Please enter Receipt Document"))
|
frappe.throw(_("Please enter Receipt Document"))
|
||||||
|
|||||||
@@ -228,9 +228,17 @@ frappe.ui.form.on('Material Request', {
|
|||||||
const qty_fields = ['actual_qty', 'projected_qty', 'min_order_qty'];
|
const qty_fields = ['actual_qty', 'projected_qty', 'min_order_qty'];
|
||||||
|
|
||||||
if(!r.exc) {
|
if(!r.exc) {
|
||||||
$.each(r.message, function(k, v) {
|
$.each(r.message, function(key, value) {
|
||||||
if(!d[k] || in_list(qty_fields, k)) d[k] = v;
|
if(!d[key] || qty_fields.includes(key)) {
|
||||||
|
d[key] = value;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (d.price_list_rate != r.message.price_list_rate) {
|
||||||
|
d.price_list_rate = r.message.price_list_rate;
|
||||||
|
|
||||||
|
frappe.model.set_value(d.doctype, d.name, "rate", d.price_list_rate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -432,7 +440,6 @@ frappe.ui.form.on("Material Request Item", {
|
|||||||
item.amount = flt(item.qty) * flt(item.rate);
|
item.amount = flt(item.qty) * flt(item.rate);
|
||||||
frappe.model.set_value(doctype, name, "amount", item.amount);
|
frappe.model.set_value(doctype, name, "amount", item.amount);
|
||||||
refresh_field("amount", item.name, item.parentfield);
|
refresh_field("amount", item.name, item.parentfield);
|
||||||
frm.events.get_item_data(frm, item, false);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
item_code: function(frm, doctype, name) {
|
item_code: function(frm, doctype, name) {
|
||||||
@@ -452,7 +459,12 @@ frappe.ui.form.on("Material Request Item", {
|
|||||||
set_schedule_date(frm);
|
set_schedule_date(frm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
conversion_factor: function(frm, doctype, name) {
|
||||||
|
const item = locals[doctype][name];
|
||||||
|
frm.events.get_item_data(frm, item, false);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
erpnext.buying.MaterialRequestController = class MaterialRequestController extends erpnext.buying.BuyingController {
|
erpnext.buying.MaterialRequestController = class MaterialRequestController extends erpnext.buying.BuyingController {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"received_qty",
|
"received_qty",
|
||||||
"rate_and_amount_section_break",
|
"rate_and_amount_section_break",
|
||||||
"rate",
|
"rate",
|
||||||
|
"price_list_rate",
|
||||||
"col_break3",
|
"col_break3",
|
||||||
"amount",
|
"amount",
|
||||||
"accounting_details_section",
|
"accounting_details_section",
|
||||||
@@ -474,13 +475,22 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "WIP Composite Asset",
|
"label": "WIP Composite Asset",
|
||||||
"options": "Asset"
|
"options": "Asset"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "price_list_rate",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Price List Rate",
|
||||||
|
"options": "currency",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-11-14 18:37:59.599115",
|
"modified": "2024-02-08 16:30:56.137858",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Material Request Item",
|
"name": "Material Request Item",
|
||||||
|
|||||||
@@ -572,9 +572,7 @@ class PurchaseReceipt(BuyingController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
stock_value_diff = (
|
stock_value_diff = (
|
||||||
flt(d.base_net_amount)
|
flt(d.base_net_amount) + flt(d.item_tax_amount) + flt(d.landed_cost_voucher_amount)
|
||||||
+ flt(d.item_tax_amount / self.conversion_rate)
|
|
||||||
+ flt(d.landed_cost_voucher_amount)
|
|
||||||
)
|
)
|
||||||
elif warehouse_account.get(d.warehouse):
|
elif warehouse_account.get(d.warehouse):
|
||||||
stock_value_diff = get_stock_value_difference(self.name, d.name, d.warehouse)
|
stock_value_diff = get_stock_value_difference(self.name, d.name, d.warehouse)
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
|
|||||||
|
|
||||||
|
|
||||||
def get_web_item_qty_in_stock(item_code, item_warehouse_field, warehouse=None):
|
def get_web_item_qty_in_stock(item_code, item_warehouse_field, warehouse=None):
|
||||||
in_stock, stock_qty = 0, ""
|
|
||||||
template_item_code, is_stock_item = frappe.db.get_value(
|
template_item_code, is_stock_item = frappe.db.get_value(
|
||||||
"Item", item_code, ["variant_of", "is_stock_item"]
|
"Item", item_code, ["variant_of", "is_stock_item"]
|
||||||
)
|
)
|
||||||
@@ -52,10 +51,11 @@ def get_web_item_qty_in_stock(item_code, item_warehouse_field, warehouse=None):
|
|||||||
.where((BIN.item_code == item_code) & (BIN.warehouse == warehouse))
|
.where((BIN.item_code == item_code) & (BIN.warehouse == warehouse))
|
||||||
).run()
|
).run()
|
||||||
|
|
||||||
|
stock_qty = stock_qty[0][0]
|
||||||
if stock_qty:
|
if stock_qty:
|
||||||
total_stock += adjust_qty_for_expired_items(item_code, stock_qty, warehouse)
|
total_stock += adjust_qty_for_expired_items(item_code, stock_qty, warehouse)
|
||||||
|
|
||||||
in_stock = total_stock > 0 and 1 or 0
|
in_stock = int(total_stock > 0)
|
||||||
|
|
||||||
return frappe._dict(
|
return frappe._dict(
|
||||||
{"in_stock": in_stock, "stock_qty": total_stock, "is_stock_item": is_stock_item}
|
{"in_stock": in_stock, "stock_qty": total_stock, "is_stock_item": is_stock_item}
|
||||||
@@ -63,20 +63,16 @@ def get_web_item_qty_in_stock(item_code, item_warehouse_field, warehouse=None):
|
|||||||
|
|
||||||
|
|
||||||
def adjust_qty_for_expired_items(item_code, stock_qty, warehouse):
|
def adjust_qty_for_expired_items(item_code, stock_qty, warehouse):
|
||||||
batches = frappe.get_all("Batch", filters=[{"item": item_code}], fields=["expiry_date", "name"])
|
batches = frappe.get_all("Batch", filters={"item": item_code}, fields=["expiry_date", "name"])
|
||||||
expired_batches = get_expired_batches(batches)
|
expired_batches = get_expired_batches(batches)
|
||||||
stock_qty = [list(item) for item in stock_qty]
|
|
||||||
|
|
||||||
for batch in expired_batches:
|
for batch in expired_batches:
|
||||||
if warehouse:
|
if warehouse:
|
||||||
stock_qty[0][0] = max(0, stock_qty[0][0] - get_batch_qty(batch, warehouse))
|
stock_qty = max(0, stock_qty - get_batch_qty(batch, warehouse))
|
||||||
else:
|
else:
|
||||||
stock_qty[0][0] = max(0, stock_qty[0][0] - qty_from_all_warehouses(get_batch_qty(batch)))
|
stock_qty = max(0, stock_qty - qty_from_all_warehouses(get_batch_qty(batch)))
|
||||||
|
|
||||||
if not stock_qty[0][0]:
|
return stock_qty
|
||||||
break
|
|
||||||
|
|
||||||
return stock_qty[0][0] if stock_qty else 0
|
|
||||||
|
|
||||||
|
|
||||||
def get_expired_batches(batches):
|
def get_expired_batches(batches):
|
||||||
|
|||||||
Reference in New Issue
Block a user