fix: consider previous balance is missing

Also remove `total`, total of total is a meaningless value.
This commit is contained in:
Ankush Menat 2022-05-10 12:32:56 +05:30
parent d81422fb58
commit 6ab0046e9c
2 changed files with 58 additions and 6 deletions

View File

@ -1,6 +1,7 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import datetime
from typing import List
import frappe
from frappe import _, scrub
@ -148,11 +149,19 @@ def get_periodic_data(entry, filters):
- Warehouse A : 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 = {}
for d in entry:
period = get_period(d.posting_date, filters)
bal_qty = 0
fill_intermediate_periods(periodic_data, d.item_code, period, expected_periods)
# if period against item does not exist yet, instantiate 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):
@ -186,6 +195,36 @@ def get_periodic_data(entry, filters):
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):
data = []
items = get_items(filters)
@ -202,14 +241,15 @@ def get_data(filters):
"uom": item_data.stock_uom,
"brand": item_data.brand,
}
total = 0
for dummy, end_date in ranges:
previous_period_value = 0.0
for _start_date, end_date in ranges:
period = get_period(end_date, filters)
period_data = periodic_data.get(item_data.name, {}).get(period)
amount = sum(period_data.values()) if period_data else 0
row[scrub(period)] = amount
total += amount
row["total"] = total
if period_data:
row[scrub(period)] = previous_period_value = sum(period_data.values())
else:
row[scrub(period)] = previous_period_value
data.append(row)
return data

View File

@ -102,3 +102,15 @@ class TestStockAnalyticsReport(FrappeTestCase):
(20, add_to_date(today, months=3).replace(day=15)),
]
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])