Skip to content

Commit

Permalink
Merge pull request #35348 from rohitwaghchaure/refactor-stock-balance…
Browse files Browse the repository at this point in the history
…-report

refactor: stock balance report
  • Loading branch information
rohitwaghchaure authored May 24, 2023
2 parents 693133d + 3f548ac commit 0bc9c32
Show file tree
Hide file tree
Showing 10 changed files with 980 additions and 426 deletions.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt

frappe.ui.form.on("Closing Stock Balance", {
refresh(frm) {
frm.trigger("generate_closing_balance");
frm.trigger("regenerate_closing_balance");
},

generate_closing_balance(frm) {
if (in_list(["Queued", "Failed"], frm.doc.status)) {
frm.add_custom_button(__("Generate Closing Stock Balance"), () => {
frm.call({
method: "enqueue_job",
doc: frm.doc,
freeze: true,
callback: () => {
frm.reload_doc();
}
})
})
}
},

regenerate_closing_balance(frm) {
if (frm.doc.status == "Completed") {
frm.add_custom_button(__("Regenerate Closing Stock Balance"), () => {
frm.call({
method: "regenerate_closing_balance",
doc: frm.doc,
freeze: true,
callback: () => {
frm.reload_doc();
}
})
})
}
}
});
148 changes: 148 additions & 0 deletions erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "naming_series:",
"creation": "2023-05-17 09:58:42.086911",
"default_view": "List",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"naming_series",
"company",
"status",
"column_break_p0s0",
"from_date",
"to_date",
"filters_section",
"item_code",
"item_group",
"include_uom",
"column_break_rm5w",
"warehouse",
"warehouse_type",
"amended_from"
],
"fields": [
{
"fieldname": "naming_series",
"fieldtype": "Select",
"label": "Naming Series",
"options": "CBAL-.#####"
},
{
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"options": "Company"
},
{
"default": "Draft",
"fieldname": "status",
"fieldtype": "Select",
"in_list_view": 1,
"in_preview": 1,
"label": "Status",
"options": "Draft\nQueued\nIn Progress\nCompleted\nFailed\nCanceled",
"read_only": 1
},
{
"fieldname": "column_break_p0s0",
"fieldtype": "Column Break"
},
{
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date"
},
{
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date"
},
{
"collapsible": 1,
"fieldname": "filters_section",
"fieldtype": "Section Break",
"label": "Filters"
},
{
"fieldname": "item_code",
"fieldtype": "Link",
"label": "Item Code",
"options": "Item"
},
{
"fieldname": "item_group",
"fieldtype": "Link",
"label": "Item Group",
"options": "Item Group"
},
{
"fieldname": "column_break_rm5w",
"fieldtype": "Column Break"
},
{
"fieldname": "warehouse",
"fieldtype": "Link",
"label": "Warehouse",
"options": "Warehouse"
},
{
"fieldname": "warehouse_type",
"fieldtype": "Link",
"label": "Warehouse Type",
"options": "Warehouse Type"
},
{
"fieldname": "amended_from",
"fieldtype": "Link",
"label": "Amended From",
"no_copy": 1,
"options": "Closing Stock Balance",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "amended_from",
"fieldtype": "Link",
"label": "Amended From",
"no_copy": 1,
"options": "Closing Stock Balance",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "include_uom",
"fieldtype": "Link",
"label": "Include UOM",
"options": "UOM"
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2023-05-17 11:46:04.448220",
"modified_by": "Administrator",
"module": "Stock",
"name": "Closing Stock Balance",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
133 changes: 133 additions & 0 deletions erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

import json

import frappe
from frappe import _
from frappe.core.doctype.prepared_report.prepared_report import create_json_gz_file
from frappe.desk.form.load import get_attachments
from frappe.model.document import Document
from frappe.utils import get_link_to_form, gzip_decompress, parse_json
from frappe.utils.background_jobs import enqueue

from erpnext.stock.report.stock_balance.stock_balance import execute


class ClosingStockBalance(Document):
def before_save(self):
self.set_status()

def set_status(self, save=False):
self.status = "Queued"
if self.docstatus == 2:
self.status = "Canceled"

if self.docstatus == 0:
self.status = "Draft"

if save:
self.db_set("status", self.status)

def validate(self):
self.validate_duplicate()

def validate_duplicate(self):
table = frappe.qb.DocType("Closing Stock Balance")

query = (
frappe.qb.from_(table)
.select(table.name)
.where(
(table.docstatus == 1)
& (table.company == self.company)
& (
(table.from_date.between(self.from_date, self.to_date))
| (table.to_date.between(self.from_date, self.to_date))
| (table.from_date >= self.from_date and table.to_date <= self.to_date)
)
)
)

for fieldname in ["warehouse", "item_code", "item_group", "warehouse_type"]:
if self.get(fieldname):
query = query.where(table.get(fieldname) == self.get(fieldname))

query = query.run(as_dict=True)

if query and query[0].name:
name = get_link_to_form("Closing Stock Balance", query[0].name)
msg = f"Closing Stock Balance {name} already exists for the selected date range"
frappe.throw(_(msg), title=_("Duplicate Closing Stock Balance"))

def on_submit(self):
self.set_status(save=True)
self.enqueue_job()

def on_cancel(self):
self.set_status(save=True)
self.clear_attachment()

@frappe.whitelist()
def enqueue_job(self):
self.db_set("status", "In Progress")
self.clear_attachment()
enqueue(prepare_closing_stock_balance, name=self.name, queue="long", timeout=1500)

@frappe.whitelist()
def regenerate_closing_balance(self):
self.enqueue_job()

def clear_attachment(self):
if attachments := get_attachments(self.doctype, self.name):
attachment = attachments[0]
frappe.delete_doc("File", attachment.name)

def create_closing_stock_balance_entries(self):
columns, data = execute(
filters=frappe._dict(
{
"company": self.company,
"from_date": self.from_date,
"to_date": self.to_date,
"warehouse": self.warehouse,
"item_code": self.item_code,
"item_group": self.item_group,
"warehouse_type": self.warehouse_type,
"include_uom": self.include_uom,
"ignore_closing_balance": 1,
"show_variant_attributes": 1,
"show_stock_ageing_data": 1,
}
)
)

create_json_gz_file({"columns": columns, "data": data}, self.doctype, self.name)

def get_prepared_data(self):
if attachments := get_attachments(self.doctype, self.name):
attachment = attachments[0]
attached_file = frappe.get_doc("File", attachment.name)

data = gzip_decompress(attached_file.get_content())
if data := json.loads(data.decode("utf-8")):
data = data

return parse_json(data)

return frappe._dict({})


def prepare_closing_stock_balance(name):
doc = frappe.get_doc("Closing Stock Balance", name)

doc.db_set("status", "In Progress")

try:
doc.create_closing_stock_balance_entries()
doc.db_set("status", "Completed")
except Exception as e:
doc.db_set("status", "Failed")
traceback = frappe.get_traceback()

frappe.log_error("Closing Stock Balance Failed", traceback, doc.doctype, doc.name)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt

# import frappe
from frappe.tests.utils import FrappeTestCase


class TestClosingStockBalance(FrappeTestCase):
pass
2 changes: 1 addition & 1 deletion erpnext/stock/report/stock_ageing/stock_ageing.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def __compute_incoming_stock(
# consume transfer data and add stock to fifo queue
self.__adjust_incoming_transfer_qty(transfer_data, fifo_queue, row)
else:
if not serial_nos:
if not serial_nos and not row.get("has_serial_no"):
if fifo_queue and flt(fifo_queue[0][0]) <= 0:
# neutralize 0/negative stock by adding positive stock
fifo_queue[0][0] += flt(row.actual_qty)
Expand Down
Loading

0 comments on commit 0bc9c32

Please sign in to comment.