fix: consider previous balance is missing
Also remove `total`, total of total is a meaningless value.
This commit is contained in:
parent
d81422fb58
commit
6ab0046e9c
@ -1,6 +1,7 @@
|
|||||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
import datetime
|
import datetime
|
||||||
|
from typing import List
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _, scrub
|
from frappe import _, scrub
|
||||||
@ -148,11 +149,19 @@ def get_periodic_data(entry, filters):
|
|||||||
- Warehouse A : bal_qty/value
|
- Warehouse A : bal_qty/value
|
||||||
- Warehouse B : bal_qty/value
|
- Warehouse B : bal_qty/value
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
expected_ranges = get_period_date_ranges(filters)
|
||||||
|
expected_periods = []
|
||||||
|
for _start_date, end_date in expected_ranges:
|
||||||
|
expected_periods.append(get_period(end_date, filters))
|
||||||
|
|
||||||
periodic_data = {}
|
periodic_data = {}
|
||||||
for d in entry:
|
for d in entry:
|
||||||
period = get_period(d.posting_date, filters)
|
period = get_period(d.posting_date, filters)
|
||||||
bal_qty = 0
|
bal_qty = 0
|
||||||
|
|
||||||
|
fill_intermediate_periods(periodic_data, d.item_code, period, expected_periods)
|
||||||
|
|
||||||
# if period against item does not exist yet, instantiate it
|
# if period against item does not exist yet, instantiate it
|
||||||
# insert existing balance dict against period, and add/subtract to it
|
# insert existing balance dict against period, and add/subtract to it
|
||||||
if periodic_data.get(d.item_code) and not periodic_data.get(d.item_code).get(period):
|
if periodic_data.get(d.item_code) and not periodic_data.get(d.item_code).get(period):
|
||||||
@ -186,6 +195,36 @@ def get_periodic_data(entry, filters):
|
|||||||
return periodic_data
|
return periodic_data
|
||||||
|
|
||||||
|
|
||||||
|
def fill_intermediate_periods(
|
||||||
|
periodic_data, item_code: str, current_period: str, all_periods: List[str]
|
||||||
|
) -> None:
|
||||||
|
"""There might be intermediate periods where no stock ledger entry exists, copy previous previous data.
|
||||||
|
|
||||||
|
Previous data is ONLY copied if period falls in report range and before period being processed currently.
|
||||||
|
|
||||||
|
args:
|
||||||
|
current_period: process till this period (exclusive)
|
||||||
|
all_periods: all periods expected in report via filters
|
||||||
|
periodic_data: report's periodic data
|
||||||
|
item_code: item_code being processed
|
||||||
|
"""
|
||||||
|
|
||||||
|
previous_period_data = None
|
||||||
|
for period in all_periods:
|
||||||
|
if period == current_period:
|
||||||
|
return
|
||||||
|
|
||||||
|
if (
|
||||||
|
periodic_data.get(item_code)
|
||||||
|
and not periodic_data.get(item_code).get(period)
|
||||||
|
and previous_period_data
|
||||||
|
):
|
||||||
|
# This period should exist since it's in report range, assign previous period data
|
||||||
|
periodic_data[item_code][period] = previous_period_data.copy()
|
||||||
|
|
||||||
|
previous_period_data = periodic_data.get(item_code, {}).get(period)
|
||||||
|
|
||||||
|
|
||||||
def get_data(filters):
|
def get_data(filters):
|
||||||
data = []
|
data = []
|
||||||
items = get_items(filters)
|
items = get_items(filters)
|
||||||
@ -202,14 +241,15 @@ def get_data(filters):
|
|||||||
"uom": item_data.stock_uom,
|
"uom": item_data.stock_uom,
|
||||||
"brand": item_data.brand,
|
"brand": item_data.brand,
|
||||||
}
|
}
|
||||||
total = 0
|
previous_period_value = 0.0
|
||||||
for dummy, end_date in ranges:
|
for _start_date, end_date in ranges:
|
||||||
period = get_period(end_date, filters)
|
period = get_period(end_date, filters)
|
||||||
period_data = periodic_data.get(item_data.name, {}).get(period)
|
period_data = periodic_data.get(item_data.name, {}).get(period)
|
||||||
amount = sum(period_data.values()) if period_data else 0
|
if period_data:
|
||||||
row[scrub(period)] = amount
|
row[scrub(period)] = previous_period_value = sum(period_data.values())
|
||||||
total += amount
|
else:
|
||||||
row["total"] = total
|
row[scrub(period)] = previous_period_value
|
||||||
|
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -102,3 +102,15 @@ class TestStockAnalyticsReport(FrappeTestCase):
|
|||||||
(20, add_to_date(today, months=3).replace(day=15)),
|
(20, add_to_date(today, months=3).replace(day=15)),
|
||||||
]
|
]
|
||||||
self.assert_single_item_report(movement, [100, 50, 50, 70])
|
self.assert_single_item_report(movement, [100, 50, 50, 70])
|
||||||
|
|
||||||
|
def test_multi_month_missings(self):
|
||||||
|
today = getdate()
|
||||||
|
movement = [
|
||||||
|
(100, add_to_date(today, months=0).replace(day=15)),
|
||||||
|
(-50, add_to_date(today, months=1).replace(day=15)),
|
||||||
|
# Skip a month
|
||||||
|
(20, add_to_date(today, months=3).replace(day=15)),
|
||||||
|
# Skip another month
|
||||||
|
(-10, add_to_date(today, months=5).replace(day=15)),
|
||||||
|
]
|
||||||
|
self.assert_single_item_report(movement, [100, 50, 50, 70, 70, 60])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user