diff --git a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.js b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.js index 42d0723d4276..5f81679bade8 100644 --- a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.js +++ b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.js @@ -2,7 +2,22 @@ // For license information, please see license.txt frappe.ui.form.on('Stock Reposting Settings', { - // refresh: function(frm) { + refresh: function(frm) { + frm.trigger('convert_to_item_based_reposting'); + }, - // } + convert_to_item_based_reposting: function(frm) { + frm.add_custom_button(__('Convert to Item Based Reposting'), function() { + frm.call({ + method: 'convert_to_item_wh_reposting', + frezz: true, + doc: frm.doc, + callback: function(r) { + if (!r.exc) { + frm.reload_doc(); + } + } + }) + }) + } }); diff --git a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py index e0c8ed12e7d5..51fb5ac4c409 100644 --- a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py +++ b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py @@ -1,6 +1,8 @@ # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt +import frappe +from frappe import _ from frappe.model.document import Document from frappe.utils import add_to_date, get_datetime, get_time_str, time_diff_in_hours @@ -24,3 +26,62 @@ def set_minimum_reposting_time_slot(self): if diff < 10: self.end_time = get_time_str(add_to_date(self.start_time, hours=10, as_datetime=True)) + + @frappe.whitelist() + def convert_to_item_wh_reposting(self): + """Convert Transaction reposting to Item Warehouse based reposting if Item Based Reposting has enabled.""" + + reposting_data = get_reposting_entries() + + vouchers = [d.voucher_no for d in reposting_data] + + item_warehouses = {} + + for ledger in get_stock_ledgers(vouchers): + key = (ledger.item_code, ledger.warehouse) + if key not in item_warehouses: + item_warehouses[key] = ledger.posting_date + elif frappe.utils.getdate(item_warehouses.get(key)) > frappe.utils.getdate(ledger.posting_date): + item_warehouses[key] = ledger.posting_date + + for key, posting_date in item_warehouses.items(): + item_code, warehouse = key + create_repost_item_valuation(item_code, warehouse, posting_date) + + for row in reposting_data: + frappe.db.set_value("Repost Item Valuation", row.name, "status", "Skipped") + + self.db_set("item_based_reposting", 1) + frappe.msgprint(_("Item Warehouse based reposting has been enabled.")) + + +def get_reposting_entries(): + return frappe.get_all( + "Repost Item Valuation", + fields=["voucher_no", "name"], + filters={"status": ("in", ["Queued", "In Progress"]), "docstatus": 1, "based_on": "Transaction"}, + ) + + +def get_stock_ledgers(vouchers): + return frappe.get_all( + "Stock Ledger Entry", + fields=["item_code", "warehouse", "posting_date"], + filters={"voucher_no": ("in", vouchers)}, + ) + + +def create_repost_item_valuation(item_code, warehouse, posting_date): + frappe.get_doc( + { + "doctype": "Repost Item Valuation", + "company": frappe.get_cached_value("Warehouse", warehouse, "company"), + "posting_date": posting_date, + "based_on": "Item and Warehouse", + "posting_time": "00:00:01", + "item_code": item_code, + "warehouse": warehouse, + "allow_negative_stock": True, + "status": "Queued", + } + ).submit()