mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-21 10:19:57 +00:00
fix: use Stock Reconciliation for opening stock entry
This commit is contained in:
@@ -883,6 +883,29 @@ $.extend(erpnext.item, {
|
||||
},
|
||||
|
||||
show_opening_stock_dialog: function (frm) {
|
||||
const has_serial = cint(frm.doc.has_serial_no);
|
||||
const has_batch = cint(frm.doc.has_batch_no);
|
||||
|
||||
if (has_serial || has_batch) {
|
||||
const default_company = frappe.defaults.get_default("company");
|
||||
const row = (frm.doc.item_defaults || []).find((d) => d.company === default_company);
|
||||
const default_warehouse = (row && row.default_warehouse) || "";
|
||||
|
||||
frappe.route_options = {
|
||||
purpose: "Opening Stock",
|
||||
company: default_company,
|
||||
};
|
||||
|
||||
frappe.new_doc("Stock Reconciliation", null, (doc) => {
|
||||
const child = doc.items[0];
|
||||
frappe.model.set_value(child.doctype, child.name, "item_code", frm.doc.name);
|
||||
if (default_warehouse) {
|
||||
frappe.model.set_value(child.doctype, child.name, "warehouse", default_warehouse);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const companies = (frm.doc.item_defaults || []).map((d) => d.company).filter(Boolean);
|
||||
|
||||
if (!companies.length) {
|
||||
@@ -901,9 +924,6 @@ $.extend(erpnext.item, {
|
||||
return (row && row.default_warehouse) || "";
|
||||
};
|
||||
|
||||
const has_serial = cint(frm.doc.has_serial_no);
|
||||
const has_batch = cint(frm.doc.has_batch_no);
|
||||
|
||||
const fields = [
|
||||
{
|
||||
label: __("Company"),
|
||||
@@ -950,51 +970,10 @@ $.extend(erpnext.item, {
|
||||
},
|
||||
];
|
||||
|
||||
if (has_serial) {
|
||||
fields.push(
|
||||
{ fieldtype: "Section Break", label: __("Serial / Batch") },
|
||||
{
|
||||
label: __("Serial No Series"),
|
||||
fieldname: "serial_no_series",
|
||||
fieldtype: "Data",
|
||||
default: frm.doc.serial_no_series || "",
|
||||
reqd: 1,
|
||||
description: __(
|
||||
"Example: SN-.YYYY.-.#####. - One serial number will be created per unit of qty."
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (has_batch) {
|
||||
if (!has_serial) {
|
||||
fields.push({ fieldtype: "Section Break", label: __("Serial Nos / Batches") });
|
||||
}
|
||||
fields.push(
|
||||
{
|
||||
label: __("Automatically Create New Batch"),
|
||||
fieldname: "create_new_batch",
|
||||
fieldtype: "Check",
|
||||
default: 1,
|
||||
read_only: 1,
|
||||
},
|
||||
{
|
||||
label: __("Batch Number Series"),
|
||||
fieldname: "batch_number_series",
|
||||
fieldtype: "Data",
|
||||
default: frm.doc.batch_number_series || "",
|
||||
reqd: 1,
|
||||
description: __(
|
||||
"Example: BATCH-.YYYY.-.#####. - A new batch will be auto-created from this series."
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const dialog = new frappe.ui.Dialog({
|
||||
title: __("Set Opening Stock"),
|
||||
title: __("Add Opening Stock"),
|
||||
fields: fields,
|
||||
primary_action_label: __("Create Stock Entry"),
|
||||
primary_action_label: __("Save"),
|
||||
primary_action: function (values) {
|
||||
frappe.call({
|
||||
method: "erpnext.stock.doctype.item.item.make_opening_stock_entry",
|
||||
@@ -1004,9 +983,6 @@ $.extend(erpnext.item, {
|
||||
qty: values.qty,
|
||||
valuation_rate: values.valuation_rate || 0,
|
||||
warehouse: values.warehouse || null,
|
||||
serial_no_series: values.serial_no_series || null,
|
||||
create_new_batch: values.create_new_batch ? 1 : 0,
|
||||
batch_number_series: values.batch_number_series || null,
|
||||
},
|
||||
freeze: true,
|
||||
freeze_message: __("Creating Opening Stock Entry..."),
|
||||
@@ -1022,6 +998,25 @@ $.extend(erpnext.item, {
|
||||
|
||||
dialog.set_value("warehouse", get_warehouse_for_company(companies[0]));
|
||||
dialog.show();
|
||||
dialog.add_custom_action(__("Edit Full Form"), function () {
|
||||
const default_company = frappe.defaults.get_default("company");
|
||||
const row = (frm.doc.item_defaults || []).find((d) => d.company === default_company);
|
||||
|
||||
frappe.route_options = {
|
||||
purpose: "Opening Stock",
|
||||
company: default_company,
|
||||
};
|
||||
|
||||
frappe.new_doc("Stock Reconciliation", null, (doc) => {
|
||||
const child = doc.items[0];
|
||||
frappe.model.set_value(child.doctype, child.name, "item_code", frm.doc.name);
|
||||
if (row && row.default_warehouse) {
|
||||
frappe.model.set_value(child.doctype, child.name, "warehouse", row.default_warehouse);
|
||||
}
|
||||
});
|
||||
|
||||
dialog.hide();
|
||||
});
|
||||
},
|
||||
|
||||
weight_to_validate: function (frm) {
|
||||
|
||||
@@ -312,9 +312,6 @@ class Item(Document):
|
||||
if self.valuation_rate is None and not self.is_customer_provided_item:
|
||||
frappe.throw(_("Valuation Rate is mandatory if Opening Stock entered"))
|
||||
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
|
||||
# default warehouse, or Stores
|
||||
for default in self.item_defaults or [
|
||||
frappe._dict({"company": frappe.defaults.get_defaults().company})
|
||||
]:
|
||||
@@ -329,39 +326,54 @@ class Item(Document):
|
||||
"Warehouse", {"warehouse_name": _("Stores"), "company": default.company}
|
||||
)
|
||||
|
||||
if default_warehouse:
|
||||
stock_entry = make_stock_entry(
|
||||
item_code=self.name,
|
||||
target=default_warehouse,
|
||||
qty=self.opening_stock,
|
||||
rate=self.valuation_rate,
|
||||
company=default.company,
|
||||
posting_date=getdate(),
|
||||
posting_time=nowtime(),
|
||||
do_not_save=True,
|
||||
opening_account = frappe.db.get_value(
|
||||
"Account",
|
||||
{"company": default.company, "account_type": "Temporary", "is_group": 0},
|
||||
"name",
|
||||
)
|
||||
|
||||
if not opening_account:
|
||||
frappe.throw(
|
||||
_(
|
||||
"Please set a Temporary Opening account for company {0} to create an Opening Stock entry."
|
||||
).format(frappe.bold(default.company))
|
||||
)
|
||||
|
||||
if self.valuation_rate == 0:
|
||||
for item in stock_entry.items:
|
||||
item.allow_zero_valuation_rate = 1
|
||||
if default_warehouse:
|
||||
stock_reco = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Stock Reconciliation",
|
||||
"purpose": "Opening Stock",
|
||||
"company": default.company,
|
||||
"expense_account": opening_account,
|
||||
"items": [
|
||||
{
|
||||
"item_code": self.name,
|
||||
"warehouse": default_warehouse,
|
||||
"qty": self.opening_stock,
|
||||
"valuation_rate": self.valuation_rate,
|
||||
"allow_zero_valuation_rate": 1 if flt(self.valuation_rate) == 0 else 0,
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
stock_entry.insert()
|
||||
stock_entry.submit()
|
||||
stock_entry.load_from_db()
|
||||
stock_entry.add_comment("Comment", _("Opening Stock"))
|
||||
stock_reco.insert()
|
||||
stock_reco.submit()
|
||||
stock_reco.add_comment("Comment", _("Opening Stock"))
|
||||
|
||||
stock_entry_link = frappe.utils.get_link_to_form("Stock Entry", stock_entry.name)
|
||||
stock_reco_link = frappe.utils.get_link_to_form("Stock Reconciliation", stock_reco.name)
|
||||
if self.valuation_rate == 0:
|
||||
frappe.msgprint(
|
||||
_("Opening Stock entry created with zero valuation rate: {0}").format(
|
||||
stock_entry_link
|
||||
stock_reco_link
|
||||
),
|
||||
indicator="orange",
|
||||
alert=True,
|
||||
)
|
||||
else:
|
||||
frappe.msgprint(
|
||||
_("Opening Stock entry created: {0}").format(stock_entry_link),
|
||||
_("Opening Stock entry created: {0}").format(stock_reco_link),
|
||||
indicator="green",
|
||||
alert=True,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user