From 7382d487ac490b76694bd76157c8be9805088bee Mon Sep 17 00:00:00 2001 From: Amritanshu Date: Thu, 5 Feb 2026 01:12:56 +0000 Subject: [PATCH] Product Sale Report double counts the Bundle Items as it lists them as well as the bundle. Menu Engineering Report double counts the Bundle Items as it lists them as well as the bundle. All reports fixed. --- barker/barker/routers/__init__.py | 4 +-- .../routers/reports/beer_sale_report.py | 25 +++++-------------- .../barker/routers/reports/discount_report.py | 25 ++++--------------- .../reports/menu_engineering_report.py | 23 +++++------------ .../routers/reports/product_sale_report.py | 22 +++------------- barker/barker/routers/reports/sale_report.py | 23 +++++++---------- barker/barker/routers/reports/tax_report.py | 2 ++ barker/barker/routers/voucher/show.py | 3 +-- barker/barker/routers/voucher/split.py | 3 +-- barker/barker/schemas/voucher.py | 3 +-- 10 files changed, 37 insertions(+), 96 deletions(-) diff --git a/barker/barker/routers/__init__.py b/barker/barker/routers/__init__.py index 5c23500..eff9fde 100644 --- a/barker/barker/routers/__init__.py +++ b/barker/barker/routers/__init__.py @@ -42,14 +42,14 @@ def dates_overlap(start1: date | None, end1: date | None, start2: date | None, e return start1 <= end2 and start2 <= end1 -def _pv_active(date_: date): +def _pv_active(date_: date | Label[Any]): return and_( or_(ProductVersion.valid_from == None, ProductVersion.valid_from <= date_), # noqa: E711 or_(ProductVersion.valid_till == None, ProductVersion.valid_till >= date_), # noqa: E711 ) -def _sv_active(date_: date): +def _sv_active(date_: date | Label[Any]): return and_( or_(SkuVersion.valid_from == None, SkuVersion.valid_from <= date_), # noqa: E711 or_(SkuVersion.valid_till == None, SkuVersion.valid_till >= date_), # noqa: E711 diff --git a/barker/barker/routers/reports/beer_sale_report.py b/barker/barker/routers/reports/beer_sale_report.py index e5bba15..af86aff 100644 --- a/barker/barker/routers/reports/beer_sale_report.py +++ b/barker/barker/routers/reports/beer_sale_report.py @@ -1,16 +1,15 @@ from datetime import date, timedelta -from operator import or_ from fastapi import APIRouter, Depends, Security -from sqlalchemy import Date, and_ +from sqlalchemy import Date from sqlalchemy.sql.expression import func, select from ...core.config import settings from ...core.security import get_current_active_user as get_user from ...db.session import SessionFuture from ...models.inventory import Inventory +from ...models.inventory_type import InventoryType from ...models.kot import Kot -from ...models.product import Product from ...models.product_version import ProductVersion from ...models.sku_version import SkuVersion from ...models.stock_keeping_unit import StockKeepingUnit @@ -18,6 +17,7 @@ from ...models.voucher import Voucher from ...models.voucher_type import VoucherType from ...schemas.beer_consumption_report import BeerConsumptionReport, BeerConsumptionReportItem from ...schemas.user_token import UserToken +from .. import _pv_onclause, _sv_onclause from . import check_audit_permission, report_finish_date, report_start_date @@ -39,22 +39,8 @@ def beer_consumption( Voucher.date + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES), Date ).label("day") sum_ = func.sum(Inventory.quantity * SkuVersion.fraction).label("sum") - product_version_onclause = and_( - ProductVersion.product_id == Product.id, - or_( - ProductVersion.valid_from == None, # noqa: E711 - ProductVersion.valid_from <= day, - ), - or_( - ProductVersion.valid_till == None, # noqa: E711 - ProductVersion.valid_till >= day, - ), - ) - sku_version_onclause = and_( - SkuVersion.sku_id == StockKeepingUnit.id, - or_(SkuVersion.valid_from == None, SkuVersion.valid_from <= day), # noqa: E711 - or_(SkuVersion.valid_till == None, SkuVersion.valid_till >= day), # noqa: E711 - ) + product_version_onclause = _pv_onclause(day) + sku_version_onclause = _sv_onclause(day) query = ( select(day, ProductVersion.name, sum_, ProductVersion.fraction_units) .join(Voucher.kots) @@ -64,6 +50,7 @@ def beer_consumption( .join(StockKeepingUnit.product) .join(ProductVersion, onclause=product_version_onclause) .where( + Inventory.type_ != InventoryType.bundle, day >= start_date, day <= finish_date, ) diff --git a/barker/barker/routers/reports/discount_report.py b/barker/barker/routers/reports/discount_report.py index 1576ca8..3b7c386 100644 --- a/barker/barker/routers/reports/discount_report.py +++ b/barker/barker/routers/reports/discount_report.py @@ -3,24 +3,24 @@ import uuid from datetime import date, timedelta from fastapi import APIRouter, Cookie, Depends, Security -from sqlalchemy import Date, and_, func, or_, select +from sqlalchemy import Date, func, select from sqlalchemy.orm import Session from ...core.config import settings from ...core.security import get_current_active_user as get_user from ...db.session import SessionFuture from ...models.inventory import Inventory +from ...models.inventory_type import InventoryType from ...models.kot import Kot -from ...models.product import Product from ...models.product_version import ProductVersion from ...models.sale_category import SaleCategory -from ...models.sku_version import SkuVersion from ...models.stock_keeping_unit import StockKeepingUnit from ...models.voucher import Voucher from ...models.voucher_type import VoucherType from ...printing.discount_report import print_discount_report from ...schemas.discount_report import DiscountReport, DiscountReportItem from ...schemas.user_token import UserToken +from .. import _pv_onclause from . import check_audit_permission, report_finish_date, report_start_date @@ -47,33 +47,18 @@ def get_discount_report(start_date: date, finish_date: date, db: Session) -> lis Voucher.date + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES), Date ).label("day") amount = func.sum(Inventory.quantity * Inventory.effective_price * Inventory.discount).label("Amount") - product_version_onclause = and_( - ProductVersion.product_id == Product.id, - or_( - ProductVersion.valid_from == None, # noqa: E711 - ProductVersion.valid_from <= day, - ), - or_( - ProductVersion.valid_till == None, # noqa: E711 - ProductVersion.valid_till >= day, - ), - ) - sku_version_onclause = and_( - SkuVersion.sku_id == StockKeepingUnit.id, - or_(SkuVersion.valid_from == None, SkuVersion.valid_from <= day), # noqa: E711 - or_(SkuVersion.valid_till == None, SkuVersion.valid_till >= day), # noqa: E711 - ) + product_version_onclause = _pv_onclause(day) list_ = db.execute( select(SaleCategory.name, amount) .join(Voucher.kots) .join(Kot.inventories) .join(Inventory.sku) - .join(SkuVersion, onclause=sku_version_onclause) .join(StockKeepingUnit.product) .join(ProductVersion, onclause=product_version_onclause) .join(ProductVersion.sale_category) .where( Inventory.discount != 0, + Inventory.type_ != InventoryType.bundle, day >= start_date, day <= finish_date, Voucher.voucher_type.in_([VoucherType.REGULAR_BILL, VoucherType.KOT]), diff --git a/barker/barker/routers/reports/menu_engineering_report.py b/barker/barker/routers/reports/menu_engineering_report.py index 743d3af..4188d6d 100644 --- a/barker/barker/routers/reports/menu_engineering_report.py +++ b/barker/barker/routers/reports/menu_engineering_report.py @@ -4,7 +4,7 @@ from datetime import date, timedelta from decimal import Decimal from fastapi import APIRouter, Depends, Security -from sqlalchemy import Date, and_, func, nulls_last, or_, select +from sqlalchemy import Date, func, nulls_last, select from sqlalchemy.orm import Session from ...core.config import settings @@ -22,6 +22,7 @@ from ...models.voucher import Voucher from ...models.voucher_type import VoucherType from ...schemas.menu_engineering_report import MeItem, MeReport from ...schemas.user_token import UserToken +from .. import _pv_active, _sv_active from . import check_audit_permission, report_finish_date, report_start_date @@ -48,20 +49,8 @@ def menu_engineering_report(start_date: date, finish_date: date, db: Session) -> day = func.cast( Voucher.date + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES), Date ).label("day") - product_version_valid = and_( - or_( - ProductVersion.valid_from == None, # noqa: E711 - ProductVersion.valid_from <= day, - ), - or_( - ProductVersion.valid_till == None, # noqa: E711 - ProductVersion.valid_till >= day, - ), - ) - sku_version_valid = and_( - or_(SkuVersion.valid_from == None, SkuVersion.valid_from <= day), # noqa: E711 - or_(SkuVersion.valid_till == None, SkuVersion.valid_till >= day), # noqa: E711 - ) + product_version_active = _pv_active(day) + sku_version_active = _sv_active(day) list_ = db.execute( select( SaleCategory.name, @@ -87,8 +76,8 @@ def menu_engineering_report(start_date: date, finish_date: date, db: Session) -> day >= start_date, day <= finish_date, Voucher.voucher_type == VoucherType.REGULAR_BILL, - product_version_valid, - sku_version_valid, + product_version_active, + sku_version_active, ) .group_by( SaleCategory.name, diff --git a/barker/barker/routers/reports/product_sale_report.py b/barker/barker/routers/reports/product_sale_report.py index 5c059b6..b6e2020 100644 --- a/barker/barker/routers/reports/product_sale_report.py +++ b/barker/barker/routers/reports/product_sale_report.py @@ -4,7 +4,7 @@ from datetime import date, timedelta from typing import Annotated from fastapi import APIRouter, Cookie, Depends, Query, Security -from sqlalchemy import Date, and_, func, or_, select +from sqlalchemy import Date, func, select from sqlalchemy.orm import Session from ...core.config import settings @@ -14,7 +14,6 @@ from ...models.food_table import FoodTable from ...models.inventory import Inventory from ...models.kot import Kot from ...models.menu_category import MenuCategory -from ...models.product import Product from ...models.product_version import ProductVersion from ...models.sale_category import SaleCategory from ...models.sku_version import SkuVersion @@ -24,6 +23,7 @@ from ...models.voucher_type import VoucherType from ...printing.product_sale_report import print_product_sale_report from ...schemas.product_sale_report import ProductSaleReport, ProductSaleReportItem, UserLink from ...schemas.user_token import UserToken +from .. import _pv_onclause, _sv_onclause from . import check_audit_permission, report_finish_date, report_start_date @@ -54,22 +54,8 @@ def product_sale_report( day = func.cast( Voucher.date + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES), Date ).label("day") - product_version_onclause = and_( - ProductVersion.product_id == Product.id, - or_( - ProductVersion.valid_from == None, # noqa: E711 - ProductVersion.valid_from <= day, - ), - or_( - ProductVersion.valid_till == None, # noqa: E711 - ProductVersion.valid_till >= day, - ), - ) - sku_version_onclause = and_( - SkuVersion.sku_id == StockKeepingUnit.id, - or_(SkuVersion.valid_from == None, SkuVersion.valid_from <= day), # noqa: E711 - or_(SkuVersion.valid_till == None, SkuVersion.valid_till >= day), # noqa: E711 - ) + product_version_onclause = _pv_onclause(day) + sku_version_onclause = _sv_onclause(day) query = ( select( ProductVersion.id, diff --git a/barker/barker/routers/reports/sale_report.py b/barker/barker/routers/reports/sale_report.py index 23ea0fe..0969a6b 100644 --- a/barker/barker/routers/reports/sale_report.py +++ b/barker/barker/routers/reports/sale_report.py @@ -5,7 +5,7 @@ from decimal import Decimal from typing import Annotated from fastapi import APIRouter, Cookie, Depends, Query, Security -from sqlalchemy import Date, and_, func, or_, select +from sqlalchemy import Date, func, select from sqlalchemy.orm import Session from ...core.config import settings @@ -13,18 +13,20 @@ from ...core.security import get_current_active_user as get_user from ...db.session import SessionFuture from ...models.food_table import FoodTable from ...models.inventory import Inventory +from ...models.inventory_type import InventoryType from ...models.kot import Kot -from ...models.product import Product from ...models.product_version import ProductVersion from ...models.sale_category import SaleCategory from ...models.settle_option import SettleOption from ...models.settlement import Settlement +from ...models.stock_keeping_unit import StockKeepingUnit from ...models.voucher import Voucher from ...models.voucher_type import VoucherType from ...printing.sale_report import print_sale_report from ...schemas.sale_report import SaleReport, SaleReportItem from ...schemas.user import UserLink from ...schemas.user_token import UserToken +from .. import _pv_onclause from . import check_audit_permission, report_finish_date, report_start_date from .tax_report import get_tax @@ -60,26 +62,19 @@ def get_sale(start_date: date, finish_date: date, id_: uuid.UUID | None, db: Ses day = func.cast( Voucher.date + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES), Date ).label("day") - product_version_onclause = and_( - ProductVersion.product_id == Product.id, - or_( - ProductVersion.valid_from == None, # noqa: E711 - ProductVersion.valid_from <= day, - ), - or_( - ProductVersion.valid_till == None, # noqa: E711 - ProductVersion.valid_till >= day, - ), - ) + product_version_onclause = _pv_onclause(day) query = ( select(SaleCategory.name, func.sum(Inventory.net)) + .select_from(Inventory) .join(Inventory.kot) .join(Kot.voucher) - .join(Inventory.product) + .join(Inventory.sku) + .join(StockKeepingUnit.product) .join(ProductVersion, onclause=product_version_onclause) .join(ProductVersion.sale_category) .join(Voucher.food_table) .where( + Inventory.type_ != InventoryType.bundle, day >= start_date, day <= finish_date, Voucher.voucher_type == VoucherType.REGULAR_BILL, diff --git a/barker/barker/routers/reports/tax_report.py b/barker/barker/routers/reports/tax_report.py index a1aed21..184a3cb 100644 --- a/barker/barker/routers/reports/tax_report.py +++ b/barker/barker/routers/reports/tax_report.py @@ -13,6 +13,7 @@ from ...core.security import get_current_active_user as get_user from ...db.session import SessionFuture from ...models.food_table import FoodTable from ...models.inventory import Inventory +from ...models.inventory_type import InventoryType from ...models.kot import Kot from ...models.tax import Tax from ...models.voucher import Voucher @@ -60,6 +61,7 @@ def get_tax(s: date, f: date, id_: uuid.UUID | None, db: Session) -> list[TaxRep .join(Inventory.tax) .join(Voucher.food_table) .where( + Inventory.type_ != InventoryType.bundle, Voucher.date >= start_date, Voucher.date <= finish_date, Voucher.voucher_type == VoucherType.REGULAR_BILL, diff --git a/barker/barker/routers/voucher/show.py b/barker/barker/routers/voucher/show.py index 2095f61..3de07e3 100644 --- a/barker/barker/routers/voucher/show.py +++ b/barker/barker/routers/voucher/show.py @@ -7,8 +7,6 @@ from fastapi import APIRouter, HTTPException, Security, status from sqlalchemy import Date, func, select from sqlalchemy.orm import Session, contains_eager -from barker.models.inventory_type import InventoryType - from ...core.config import settings from ...core.security import get_current_active_user as get_user from ...db.session import SessionFuture @@ -16,6 +14,7 @@ from ...models.bill import Bill from ...models.food_table import FoodTable from ...models.guest_book import GuestBook from ...models.inventory import Inventory +from ...models.inventory_type import InventoryType from ...models.kot import Kot from ...models.overview import Overview from ...models.product import Product diff --git a/barker/barker/routers/voucher/split.py b/barker/barker/routers/voucher/split.py index 806a045..03ce366 100644 --- a/barker/barker/routers/voucher/split.py +++ b/barker/barker/routers/voucher/split.py @@ -9,8 +9,6 @@ from sqlalchemy import Date, delete, func, select from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.orm import Session -from barker.routers import _pv_onclause, _sv_onclause - from ...core.config import settings from ...core.security import get_current_active_user as get_user from ...db.session import SessionFuture @@ -22,6 +20,7 @@ from ...models.overview import Overview from ...models.settle_option import SettleOption from ...models.voucher import Voucher from ...models.voucher_type import VoucherType +from ...routers import _pv_onclause, _sv_onclause from ...routers.voucher import ( check_permissions, do_update_bill_numbers, diff --git a/barker/barker/schemas/voucher.py b/barker/barker/schemas/voucher.py index 0569022..ae40eae 100644 --- a/barker/barker/schemas/voucher.py +++ b/barker/barker/schemas/voucher.py @@ -5,8 +5,7 @@ from typing import Annotated from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator -from barker.models.inventory_type import InventoryType - +from ..models.inventory_type import InventoryType from . import Daf, to_camel from .customer import CustomerLink from .modifier import ModifierLink