mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-15 15:38:39 +00:00
Merge pull request #56033 from mihir-kandoi/pg-zero-date
fix(postgres): db-aware zero-date (0000-00-00) item end-of-life checks
This commit is contained in:
@@ -56,11 +56,12 @@ def _item_master_details(item):
|
||||
|
||||
|
||||
def _item_is_alive(item_table):
|
||||
return (
|
||||
item_table.end_of_life.isnull()
|
||||
| (item_table.end_of_life == "0000-00-00")
|
||||
| (item_table.end_of_life > nowdate())
|
||||
)
|
||||
# "not set" end_of_life is NULL on postgres (the MariaDB zero-date '0000-00-00' is an invalid
|
||||
# date constant there), so only add the zero-date term on MariaDB.
|
||||
is_alive = item_table.end_of_life.isnull() | (item_table.end_of_life > nowdate())
|
||||
if frappe.db.db_type != "postgres":
|
||||
is_alive |= item_table.end_of_life == "0000-00-00"
|
||||
return is_alive
|
||||
|
||||
|
||||
def _default_bom_for_item(item, project):
|
||||
|
||||
@@ -24,14 +24,9 @@ def reorder_item():
|
||||
def _reorder_item():
|
||||
material_requests = {"Purchase": {}, "Transfer": {}, "Material Issue": {}, "Manufacture": {}}
|
||||
warehouse_company = frappe._dict(
|
||||
frappe.db.sql(
|
||||
"""select name, company from `tabWarehouse`
|
||||
where disabled=0"""
|
||||
)
|
||||
)
|
||||
default_company = (
|
||||
erpnext.get_default_company() or frappe.db.sql("""select name from tabCompany limit 1""")[0][0]
|
||||
frappe.get_all("Warehouse", filters={"disabled": 0}, fields=["name", "company"], as_list=True)
|
||||
)
|
||||
default_company = erpnext.get_default_company() or frappe.db.get_value("Company", {}, "name")
|
||||
|
||||
items_to_consider = get_items_for_reorder()
|
||||
|
||||
@@ -110,6 +105,16 @@ def _reorder_item():
|
||||
return create_material_request(material_requests)
|
||||
|
||||
|
||||
def _item_is_alive(item_table):
|
||||
# An item counts as alive when end_of_life is unset, in the future, or the MariaDB zero-date
|
||||
# '0000-00-00'. On postgres '0000-00-00' is an invalid date literal and a "not set" end_of_life
|
||||
# is NULL (already covered by IS NULL), so add the zero-date term on MariaDB only.
|
||||
alive = item_table.end_of_life.isnull() | (item_table.end_of_life > nowdate())
|
||||
if frappe.db.db_type != "postgres":
|
||||
alive |= item_table.end_of_life == "0000-00-00"
|
||||
return alive
|
||||
|
||||
|
||||
def get_items_for_reorder() -> dict[str, list]:
|
||||
reorder_table = frappe.qb.DocType("Item Reorder")
|
||||
item_table = frappe.qb.DocType("Item")
|
||||
@@ -135,15 +140,7 @@ def get_items_for_reorder() -> dict[str, list]:
|
||||
item_table.has_variants,
|
||||
item_table.lead_time_days,
|
||||
)
|
||||
.where(
|
||||
(item_table.disabled == 0)
|
||||
& (item_table.is_stock_item == 1)
|
||||
& (
|
||||
(item_table.end_of_life.isnull())
|
||||
| (item_table.end_of_life > nowdate())
|
||||
| (item_table.end_of_life == "0000-00-00")
|
||||
)
|
||||
)
|
||||
.where((item_table.disabled == 0) & (item_table.is_stock_item == 1) & _item_is_alive(item_table))
|
||||
)
|
||||
|
||||
data = query.run(as_dict=True)
|
||||
@@ -168,11 +165,7 @@ def get_reorder_levels_for_variants(itemwise_reorder):
|
||||
.where(
|
||||
(item_table.disabled == 0)
|
||||
& (item_table.is_stock_item == 1)
|
||||
& (
|
||||
(item_table.end_of_life.isnull())
|
||||
| (item_table.end_of_life > nowdate())
|
||||
| (item_table.end_of_life == "0000-00-00")
|
||||
)
|
||||
& _item_is_alive(item_table)
|
||||
& (item_table.variant_of.notnull())
|
||||
)
|
||||
)
|
||||
@@ -189,13 +182,11 @@ def get_item_warehouse_projected_qty(items_to_consider):
|
||||
item_warehouse_projected_qty = {}
|
||||
items_to_consider = list(items_to_consider.keys())
|
||||
|
||||
for item_code, warehouse, projected_qty in frappe.db.sql(
|
||||
"""select item_code, warehouse, projected_qty
|
||||
from tabBin where item_code in ({})
|
||||
and (warehouse != '' and warehouse is not null)""".format(
|
||||
", ".join(["%s"] * len(items_to_consider))
|
||||
),
|
||||
items_to_consider,
|
||||
for item_code, warehouse, projected_qty in frappe.get_all(
|
||||
"Bin",
|
||||
filters={"item_code": ["in", items_to_consider], "warehouse": ["is", "set"]},
|
||||
fields=["item_code", "warehouse", "projected_qty"],
|
||||
as_list=True,
|
||||
):
|
||||
if item_code not in item_warehouse_projected_qty:
|
||||
item_warehouse_projected_qty.setdefault(item_code, {})
|
||||
|
||||
@@ -284,17 +284,19 @@ def get_item_map(item_code, include_uom):
|
||||
bin = frappe.qb.DocType("Bin")
|
||||
item = frappe.qb.DocType("Item")
|
||||
|
||||
# alive = end_of_life unset / future / MariaDB zero-date '0000-00-00' (an invalid date literal on
|
||||
# postgres, where "not set" is NULL — already covered by IS NULL); zero-date term on MariaDB only.
|
||||
alive = (item.end_of_life > today()) | item.end_of_life.isnull()
|
||||
if frappe.db.db_type != "postgres":
|
||||
alive |= item.end_of_life == "0000-00-00"
|
||||
|
||||
query = (
|
||||
frappe.qb.from_(item)
|
||||
.select(item.name, item.item_name, item.description, item.item_group, item.brand, item.stock_uom)
|
||||
.where(
|
||||
(item.is_stock_item == 1)
|
||||
& (item.disabled == 0)
|
||||
& (
|
||||
(item.end_of_life > today())
|
||||
| (item.end_of_life.isnull())
|
||||
| (item.end_of_life == "0000-00-00")
|
||||
)
|
||||
& alive
|
||||
& (ExistsCriterion(frappe.qb.from_(bin).select(bin.name).where(bin.item_code == item.name)))
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user