fix: change frappe.db.sql to frappe.qb
This commit is contained in:
parent
e576f7f07e
commit
289e6cd4ce
@ -372,9 +372,10 @@ class StockController(AccountsController):
|
|||||||
return sl_dict
|
return sl_dict
|
||||||
|
|
||||||
def update_inventory_dimensions(self, row, sl_dict) -> None:
|
def update_inventory_dimensions(self, row, sl_dict) -> None:
|
||||||
dimension = get_evaluated_inventory_dimension(row, sl_dict, parent_doc=self)
|
dimensions = get_evaluated_inventory_dimension(row, sl_dict, parent_doc=self)
|
||||||
if dimension and row.get(dimension.source_fieldname):
|
for dimension in dimensions:
|
||||||
sl_dict[dimension.target_fieldname] = row.get(dimension.source_fieldname)
|
if dimension and row.get(dimension.source_fieldname):
|
||||||
|
sl_dict[dimension.target_fieldname] = row.get(dimension.source_fieldname)
|
||||||
|
|
||||||
def make_sl_entries(self, sl_entries, allow_negative_stock=False, via_landed_cost_voucher=False):
|
def make_sl_entries(self, sl_entries, allow_negative_stock=False, via_landed_cost_voucher=False):
|
||||||
from erpnext.stock.stock_ledger import make_sl_entries
|
from erpnext.stock.stock_ledger import make_sl_entries
|
||||||
|
@ -85,7 +85,7 @@
|
|||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "apply_to_all_doctypes",
|
"fieldname": "apply_to_all_doctypes",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Apply to All Document Types"
|
"label": "Apply to All Inventory Document Types"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@ -144,7 +144,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-07-05 15:33:37.270373",
|
"modified": "2022-07-19 21:06:11.824976",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Inventory Dimension",
|
"name": "Inventory Dimension",
|
||||||
|
@ -11,6 +11,14 @@ class DoNotChangeError(frappe.ValidationError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CanNotBeChildDoc(frappe.ValidationError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CanNotBeDefaultDimension(frappe.ValidationError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InventoryDimension(Document):
|
class InventoryDimension(Document):
|
||||||
def onload(self):
|
def onload(self):
|
||||||
if not self.is_new() and frappe.db.has_column("Stock Ledger Entry", self.target_fieldname):
|
if not self.is_new() and frappe.db.has_column("Stock Ledger Entry", self.target_fieldname):
|
||||||
@ -51,11 +59,11 @@ class InventoryDimension(Document):
|
|||||||
def validate_reference_document(self):
|
def validate_reference_document(self):
|
||||||
if frappe.get_cached_value("DocType", self.reference_document, "istable") == 1:
|
if frappe.get_cached_value("DocType", self.reference_document, "istable") == 1:
|
||||||
msg = f"The reference document {self.reference_document} can not be child table."
|
msg = f"The reference document {self.reference_document} can not be child table."
|
||||||
frappe.throw(_(msg))
|
frappe.throw(_(msg), CanNotBeChildDoc)
|
||||||
|
|
||||||
if self.reference_document in ["Batch", "Serial No", "Warehouse", "Item"]:
|
if self.reference_document in ["Batch", "Serial No", "Warehouse", "Item"]:
|
||||||
msg = f"The reference document {self.reference_document} can not be an Inventory Dimension."
|
msg = f"The reference document {self.reference_document} can not be an Inventory Dimension."
|
||||||
frappe.throw(_(msg))
|
frappe.throw(_(msg), CanNotBeDefaultDimension)
|
||||||
|
|
||||||
def set_source_and_target_fieldname(self) -> None:
|
def set_source_and_target_fieldname(self) -> None:
|
||||||
if not self.source_fieldname:
|
if not self.source_fieldname:
|
||||||
@ -122,8 +130,9 @@ def get_inventory_documents(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_evaluated_inventory_dimension(doc, sl_dict, parent_doc=None) -> dict:
|
def get_evaluated_inventory_dimension(doc, sl_dict, parent_doc=None):
|
||||||
dimensions = get_document_wise_inventory_dimensions(doc.doctype)
|
dimensions = get_document_wise_inventory_dimensions(doc.doctype)
|
||||||
|
filter_dimensions = []
|
||||||
for row in dimensions:
|
for row in dimensions:
|
||||||
if (
|
if (
|
||||||
row.type_of_transaction == "Inward"
|
row.type_of_transaction == "Inward"
|
||||||
@ -142,8 +151,12 @@ def get_evaluated_inventory_dimension(doc, sl_dict, parent_doc=None) -> dict:
|
|||||||
if parent_doc:
|
if parent_doc:
|
||||||
evals["parent"] = parent_doc
|
evals["parent"] = parent_doc
|
||||||
|
|
||||||
if frappe.safe_eval(row.condition, evals):
|
if row.condition and frappe.safe_eval(row.condition, evals):
|
||||||
return row
|
filter_dimensions.append(row)
|
||||||
|
else:
|
||||||
|
filter_dimensions.append(row)
|
||||||
|
|
||||||
|
return filter_dimensions
|
||||||
|
|
||||||
|
|
||||||
def get_document_wise_inventory_dimensions(doctype) -> dict:
|
def get_document_wise_inventory_dimensions(doctype) -> dict:
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.tests.utils import FrappeTestCase
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
|
from erpnext.stock.doctype.inventory_dimension.inventory_dimension import (
|
||||||
|
CanNotBeChildDoc,
|
||||||
|
CanNotBeDefaultDimension,
|
||||||
|
DoNotChangeError,
|
||||||
|
)
|
||||||
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.doctype.warehouse.test_warehouse import create_warehouse
|
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||||
|
|
||||||
@ -12,11 +17,36 @@ class TestInventoryDimension(FrappeTestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
prepare_test_data()
|
prepare_test_data()
|
||||||
|
|
||||||
|
def test_validate_inventory_dimension(self):
|
||||||
|
# Can not be child doc
|
||||||
|
inv_dim1 = create_inventory_dimension(
|
||||||
|
reference_document="Stock Entry Detail",
|
||||||
|
type_of_transaction="Outward",
|
||||||
|
dimension_name="Stock Entry",
|
||||||
|
apply_to_all_doctypes=0,
|
||||||
|
istable=0,
|
||||||
|
document_type="Stock Entry",
|
||||||
|
do_not_save=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertRaises(CanNotBeChildDoc, inv_dim1.insert)
|
||||||
|
|
||||||
|
inv_dim1 = create_inventory_dimension(
|
||||||
|
reference_document="Batch",
|
||||||
|
type_of_transaction="Outward",
|
||||||
|
dimension_name="Batch",
|
||||||
|
apply_to_all_doctypes=0,
|
||||||
|
document_type="Stock Entry Detail",
|
||||||
|
do_not_save=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertRaises(CanNotBeDefaultDimension, inv_dim1.insert)
|
||||||
|
|
||||||
def test_inventory_dimension(self):
|
def test_inventory_dimension(self):
|
||||||
warehouse = "Shelf Warehouse - _TC"
|
warehouse = "Shelf Warehouse - _TC"
|
||||||
item_code = "_Test Item"
|
item_code = "_Test Item"
|
||||||
|
|
||||||
create_inventory_dimension(
|
inv_dim1 = create_inventory_dimension(
|
||||||
reference_document="Shelf",
|
reference_document="Shelf",
|
||||||
type_of_transaction="Outward",
|
type_of_transaction="Outward",
|
||||||
dimension_name="Shelf",
|
dimension_name="Shelf",
|
||||||
@ -47,7 +77,6 @@ class TestInventoryDimension(FrappeTestCase):
|
|||||||
inward.save()
|
inward.save()
|
||||||
inward.submit()
|
inward.submit()
|
||||||
inward.load_from_db()
|
inward.load_from_db()
|
||||||
print(inward.name)
|
|
||||||
|
|
||||||
sle_data = frappe.db.get_value(
|
sle_data = frappe.db.get_value(
|
||||||
"Stock Ledger Entry", {"voucher_no": inward.name}, ["shelf", "warehouse"], as_dict=1
|
"Stock Ledger Entry", {"voucher_no": inward.name}, ["shelf", "warehouse"], as_dict=1
|
||||||
@ -74,6 +103,12 @@ class TestInventoryDimension(FrappeTestCase):
|
|||||||
sle_shelf = frappe.db.get_value("Stock Ledger Entry", {"voucher_no": outward.name}, "shelf")
|
sle_shelf = frappe.db.get_value("Stock Ledger Entry", {"voucher_no": outward.name}, "shelf")
|
||||||
self.assertEqual(sle_shelf, "Shelf 1")
|
self.assertEqual(sle_shelf, "Shelf 1")
|
||||||
|
|
||||||
|
inv_dim1.load_from_db()
|
||||||
|
inv_dim1.apply_to_all_doctypes = 1
|
||||||
|
|
||||||
|
self.assertTrue(inv_dim1.has_stock_ledger())
|
||||||
|
self.assertRaises(DoNotChangeError, inv_dim1.save)
|
||||||
|
|
||||||
|
|
||||||
def prepare_test_data():
|
def prepare_test_data():
|
||||||
if not frappe.db.exists("DocType", "Shelf"):
|
if not frappe.db.exists("DocType", "Shelf"):
|
||||||
@ -107,6 +142,8 @@ def create_inventory_dimension(**args):
|
|||||||
|
|
||||||
doc = frappe.new_doc("Inventory Dimension")
|
doc = frappe.new_doc("Inventory Dimension")
|
||||||
doc.update(args)
|
doc.update(args)
|
||||||
doc.insert(ignore_permissions=True)
|
|
||||||
|
if not args.do_not_save:
|
||||||
|
doc.insert(ignore_permissions=True)
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
@ -478,10 +478,10 @@ class StockEntry(StockController):
|
|||||||
if not d.s_warehouse:
|
if not d.s_warehouse:
|
||||||
frappe.throw(_("Source warehouse is mandatory for row {0}").format(d.idx))
|
frappe.throw(_("Source warehouse is mandatory for row {0}").format(d.idx))
|
||||||
|
|
||||||
if (
|
if cstr(d.s_warehouse) == cstr(d.t_warehouse) and self.purpose not in [
|
||||||
cstr(d.s_warehouse) == cstr(d.t_warehouse)
|
"Material Transfer for Manufacture",
|
||||||
and not self.purpose == "Material Transfer for Manufacture"
|
"Material Transfer",
|
||||||
):
|
]:
|
||||||
frappe.throw(_("Source and target warehouse cannot be same for row {0}").format(d.idx))
|
frappe.throw(_("Source and target warehouse cannot be same for row {0}").format(d.idx))
|
||||||
|
|
||||||
if not (d.s_warehouse or d.t_warehouse):
|
if not (d.s_warehouse or d.t_warehouse):
|
||||||
|
@ -329,7 +329,7 @@ def get_stock_ledger_entries(filters: StockBalanceFilter, items: List[str]) -> L
|
|||||||
query = query.where(sle.item_code.isin(items))
|
query = query.where(sle.item_code.isin(items))
|
||||||
|
|
||||||
query = apply_conditions(query, filters)
|
query = apply_conditions(query, filters)
|
||||||
return query.run(as_dict=True, debug=1)
|
return query.run(as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
def get_inventory_dimension_fields():
|
def get_inventory_dimension_fields():
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from frappe.query_builder.functions import CombineDatetime
|
||||||
from frappe.utils import cint, flt
|
from frappe.utils import cint, flt
|
||||||
|
from pypika.terms import ExistsCriterion
|
||||||
|
|
||||||
from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
|
from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
@ -70,7 +72,7 @@ def update_available_serial_nos(available_serial_nos, sle):
|
|||||||
key = (sle.item_code, sle.warehouse)
|
key = (sle.item_code, sle.warehouse)
|
||||||
if key not in available_serial_nos:
|
if key not in available_serial_nos:
|
||||||
stock_balance = get_stock_balance_for(
|
stock_balance = get_stock_balance_for(
|
||||||
sle.item_code, sle.warehouse, sle.date.split(" ")[0], sle.date.split(" ")[1]
|
sle.item_code, sle.warehouse, sle.posting_date, sle.posting_time
|
||||||
)
|
)
|
||||||
serials = get_serial_nos(stock_balance["serial_nos"]) if stock_balance["serial_nos"] else []
|
serials = get_serial_nos(stock_balance["serial_nos"]) if stock_balance["serial_nos"] else []
|
||||||
available_serial_nos.setdefault(key, serials)
|
available_serial_nos.setdefault(key, serials)
|
||||||
@ -109,116 +111,6 @@ def get_columns(filters):
|
|||||||
"options": "UOM",
|
"options": "UOM",
|
||||||
"width": 90,
|
"width": 90,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"label": _("In Qty"),
|
|
||||||
"fieldname": "in_qty",
|
|
||||||
"fieldtype": "Float",
|
|
||||||
"width": 80,
|
|
||||||
"convertible": "qty",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Out Qty"),
|
|
||||||
"fieldname": "out_qty",
|
|
||||||
"fieldtype": "Float",
|
|
||||||
"width": 80,
|
|
||||||
"convertible": "qty",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Balance Qty"),
|
|
||||||
"fieldname": "qty_after_transaction",
|
|
||||||
"fieldtype": "Float",
|
|
||||||
"width": 100,
|
|
||||||
"convertible": "qty",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Voucher #"),
|
|
||||||
"fieldname": "voucher_no",
|
|
||||||
"fieldtype": "Dynamic Link",
|
|
||||||
"options": "voucher_type",
|
|
||||||
"width": 150,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Warehouse"),
|
|
||||||
"fieldname": "warehouse",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Warehouse",
|
|
||||||
"width": 150,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Item Group"),
|
|
||||||
"fieldname": "item_group",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Item Group",
|
|
||||||
"width": 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Brand"),
|
|
||||||
"fieldname": "brand",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Brand",
|
|
||||||
"width": 100,
|
|
||||||
},
|
|
||||||
{"label": _("Description"), "fieldname": "description", "width": 200},
|
|
||||||
{
|
|
||||||
"label": _("Incoming Rate"),
|
|
||||||
"fieldname": "incoming_rate",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"width": 110,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"convertible": "rate",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Valuation Rate"),
|
|
||||||
"fieldname": "valuation_rate",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"width": 110,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"convertible": "rate",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Balance Value"),
|
|
||||||
"fieldname": "stock_value",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"width": 110,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Value Change"),
|
|
||||||
"fieldname": "stock_value_difference",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"width": 110,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
},
|
|
||||||
{"label": _("Voucher Type"), "fieldname": "voucher_type", "width": 110},
|
|
||||||
{
|
|
||||||
"label": _("Voucher #"),
|
|
||||||
"fieldname": "voucher_no",
|
|
||||||
"fieldtype": "Dynamic Link",
|
|
||||||
"options": "voucher_type",
|
|
||||||
"width": 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Batch"),
|
|
||||||
"fieldname": "batch_no",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Batch",
|
|
||||||
"width": 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Serial No"),
|
|
||||||
"fieldname": "serial_no",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Serial No",
|
|
||||||
"width": 100,
|
|
||||||
},
|
|
||||||
{"label": _("Balance Serial No"), "fieldname": "balance_serial_no", "width": 100},
|
|
||||||
{
|
|
||||||
"label": _("Project"),
|
|
||||||
"fieldname": "project",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Project",
|
|
||||||
"width": 100,
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
for dimension in get_inventory_dimensions():
|
for dimension in get_inventory_dimensions():
|
||||||
@ -232,72 +124,197 @@ def get_columns(filters):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
columns.append(
|
columns.extend(
|
||||||
{
|
[
|
||||||
"label": _("Company"),
|
{
|
||||||
"fieldname": "company",
|
"label": _("In Qty"),
|
||||||
"fieldtype": "Link",
|
"fieldname": "in_qty",
|
||||||
"options": "Company",
|
"fieldtype": "Float",
|
||||||
"width": 110,
|
"width": 80,
|
||||||
}
|
"convertible": "qty",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Out Qty"),
|
||||||
|
"fieldname": "out_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 80,
|
||||||
|
"convertible": "qty",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Balance Qty"),
|
||||||
|
"fieldname": "qty_after_transaction",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 100,
|
||||||
|
"convertible": "qty",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Voucher #"),
|
||||||
|
"fieldname": "voucher_no",
|
||||||
|
"fieldtype": "Dynamic Link",
|
||||||
|
"options": "voucher_type",
|
||||||
|
"width": 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Warehouse"),
|
||||||
|
"fieldname": "warehouse",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Warehouse",
|
||||||
|
"width": 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Item Group"),
|
||||||
|
"fieldname": "item_group",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Item Group",
|
||||||
|
"width": 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Brand"),
|
||||||
|
"fieldname": "brand",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Brand",
|
||||||
|
"width": 100,
|
||||||
|
},
|
||||||
|
{"label": _("Description"), "fieldname": "description", "width": 200},
|
||||||
|
{
|
||||||
|
"label": _("Incoming Rate"),
|
||||||
|
"fieldname": "incoming_rate",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 110,
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"convertible": "rate",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Valuation Rate"),
|
||||||
|
"fieldname": "valuation_rate",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 110,
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"convertible": "rate",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Balance Value"),
|
||||||
|
"fieldname": "stock_value",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 110,
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Value Change"),
|
||||||
|
"fieldname": "stock_value_difference",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 110,
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
},
|
||||||
|
{"label": _("Voucher Type"), "fieldname": "voucher_type", "width": 110},
|
||||||
|
{
|
||||||
|
"label": _("Voucher #"),
|
||||||
|
"fieldname": "voucher_no",
|
||||||
|
"fieldtype": "Dynamic Link",
|
||||||
|
"options": "voucher_type",
|
||||||
|
"width": 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Batch"),
|
||||||
|
"fieldname": "batch_no",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Batch",
|
||||||
|
"width": 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Serial No"),
|
||||||
|
"fieldname": "serial_no",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Serial No",
|
||||||
|
"width": 100,
|
||||||
|
},
|
||||||
|
{"label": _("Balance Serial No"), "fieldname": "balance_serial_no", "width": 100},
|
||||||
|
{
|
||||||
|
"label": _("Project"),
|
||||||
|
"fieldname": "project",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Project",
|
||||||
|
"width": 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Company"),
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"width": 110,
|
||||||
|
},
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
return columns
|
return columns
|
||||||
|
|
||||||
|
|
||||||
def get_stock_ledger_entries(filters, items):
|
def get_stock_ledger_entries(filters, items):
|
||||||
item_conditions_sql = ""
|
sle = frappe.qb.DocType("Stock Ledger Entry")
|
||||||
if items:
|
query = (
|
||||||
item_conditions_sql = "and sle.item_code in ({})".format(
|
frappe.qb.from_(sle)
|
||||||
", ".join(frappe.db.escape(i) for i in items)
|
.select(
|
||||||
|
sle.item_code,
|
||||||
|
CombineDatetime(sle.posting_date, sle.posting_time).as_("date"),
|
||||||
|
sle.warehouse,
|
||||||
|
sle.posting_date,
|
||||||
|
sle.posting_time,
|
||||||
|
sle.actual_qty,
|
||||||
|
sle.incoming_rate,
|
||||||
|
sle.valuation_rate,
|
||||||
|
sle.company,
|
||||||
|
sle.voucher_type,
|
||||||
|
sle.qty_after_transaction,
|
||||||
|
sle.stock_value_difference,
|
||||||
|
sle.voucher_no,
|
||||||
|
sle.stock_value,
|
||||||
|
sle.batch_no,
|
||||||
|
sle.serial_no,
|
||||||
|
sle.project,
|
||||||
)
|
)
|
||||||
|
.where(
|
||||||
sl_entries = frappe.db.sql(
|
(sle.docstatus < 2)
|
||||||
"""
|
& (sle.is_cancelled == 0)
|
||||||
SELECT
|
& (sle.posting_date[filters.from_date : filters.to_date])
|
||||||
concat_ws(' ', posting_date, posting_time) AS date,
|
)
|
||||||
item_code,
|
.orderby(CombineDatetime(sle.posting_date, sle.posting_time))
|
||||||
warehouse,
|
.orderby(sle.creation)
|
||||||
actual_qty,
|
|
||||||
qty_after_transaction,
|
|
||||||
incoming_rate,
|
|
||||||
valuation_rate,
|
|
||||||
stock_value,
|
|
||||||
voucher_type,
|
|
||||||
voucher_no,
|
|
||||||
batch_no,
|
|
||||||
serial_no,
|
|
||||||
company,
|
|
||||||
project,
|
|
||||||
stock_value_difference {get_dimension_fields}
|
|
||||||
FROM
|
|
||||||
`tabStock Ledger Entry` sle
|
|
||||||
WHERE
|
|
||||||
company = %(company)s
|
|
||||||
AND is_cancelled = 0 AND posting_date BETWEEN %(from_date)s AND %(to_date)s
|
|
||||||
{sle_conditions}
|
|
||||||
{item_conditions_sql}
|
|
||||||
ORDER BY
|
|
||||||
posting_date asc, posting_time asc, creation asc
|
|
||||||
""".format(
|
|
||||||
sle_conditions=get_sle_conditions(filters),
|
|
||||||
item_conditions_sql=item_conditions_sql,
|
|
||||||
get_dimension_fields=get_dimension_fields(),
|
|
||||||
),
|
|
||||||
filters,
|
|
||||||
as_dict=1,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return sl_entries
|
inventory_dimension_fields = get_inventory_dimension_fields()
|
||||||
|
if inventory_dimension_fields:
|
||||||
|
for fieldname in inventory_dimension_fields:
|
||||||
|
query = query.select(fieldname)
|
||||||
|
if fieldname in filters and filters.get(fieldname):
|
||||||
|
query = query.where(sle[fieldname].isin(filters.get(fieldname)))
|
||||||
|
|
||||||
|
if items:
|
||||||
|
query = query.where(sle.item_code.isin(items))
|
||||||
|
|
||||||
|
for field in ["voucher_no", "batch_no", "project", "company"]:
|
||||||
|
if filters.get(field):
|
||||||
|
query = query.where(sle[field] == filters.get(field))
|
||||||
|
|
||||||
|
if warehouse := filters.get("warehouse"):
|
||||||
|
lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
|
||||||
|
|
||||||
|
warehouse_table = frappe.qb.DocType("Warehouse")
|
||||||
|
chilren_subquery = (
|
||||||
|
frappe.qb.from_(warehouse_table)
|
||||||
|
.select(warehouse_table.name)
|
||||||
|
.where(
|
||||||
|
(warehouse_table.lft >= lft)
|
||||||
|
& (warehouse_table.rgt <= rgt)
|
||||||
|
& (warehouse_table.name == sle.warehouse)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
query = query.where(ExistsCriterion(chilren_subquery))
|
||||||
|
|
||||||
|
return query.run(as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
def get_dimension_fields() -> str:
|
def get_inventory_dimension_fields():
|
||||||
fields = ""
|
return [dimension.fieldname for dimension in get_inventory_dimensions()]
|
||||||
|
|
||||||
for dimension in get_inventory_dimensions():
|
|
||||||
fields += f", {dimension.fieldname}"
|
|
||||||
|
|
||||||
return fields
|
|
||||||
|
|
||||||
|
|
||||||
def get_items(filters):
|
def get_items(filters):
|
||||||
@ -395,7 +412,7 @@ def get_opening_balance(filters, columns, sl_entries):
|
|||||||
for sle in sl_entries:
|
for sle in sl_entries:
|
||||||
if (
|
if (
|
||||||
sle.get("voucher_type") == "Stock Reconciliation"
|
sle.get("voucher_type") == "Stock Reconciliation"
|
||||||
and sle.get("date").split()[0] == filters.from_date
|
and sle.posting_date == filters.from_date
|
||||||
and frappe.db.get_value("Stock Reconciliation", sle.voucher_no, "purpose") == "Opening Stock"
|
and frappe.db.get_value("Stock Reconciliation", sle.voucher_no, "purpose") == "Opening Stock"
|
||||||
):
|
):
|
||||||
last_entry = sle
|
last_entry = sle
|
||||||
|
Loading…
x
Reference in New Issue
Block a user