From 7b6c09cea3bf49fbde89642a13f07684439d5e2c Mon Sep 17 00:00:00 2001 From: tanshu Date: Wed, 17 Jun 2020 09:57:41 +0530 Subject: [PATCH] All Reports done!! --- barker/.env | 5 + barker/main.py | 106 ++++---------- barker/routers/reports/__init__.py | 17 --- .../reports/beer_consumption_report.py | 63 +++++---- .../routers/reports/bill_settlement_report.py | 64 ++++++--- barker/routers/reports/cashier_report.py | 132 +++++++++++------- barker/routers/reports/discount_report.py | 57 +++++--- barker/routers/reports/product_sale_report.py | 75 +++++----- barker/routers/reports/sale_report.py | 125 ++++++----------- barker/routers/reports/tax_report.py | 70 ++++++++++ barker/routers/tax.py | 10 +- barker/schemas/__init__.py | 2 +- .../beer-consumption-report.service.ts | 2 +- .../bill-settlement-report.service.ts | 2 +- .../cashier-report/cashier-report.service.ts | 5 +- .../discount-report.service.ts | 2 +- .../product-sale-report.service.ts | 2 +- .../app/sale-report/sale-report.service.ts | 2 +- .../src/app/tax-report/tax-report.service.ts | 2 +- 19 files changed, 401 insertions(+), 342 deletions(-) create mode 100644 barker/routers/reports/tax_report.py diff --git a/barker/.env b/barker/.env index ebe500e..dedd4e9 100644 --- a/barker/.env +++ b/barker/.env @@ -10,9 +10,14 @@ POSTGRES_USER= POSTGRES_PASSWORD= POSTGRES_DB= +# openssl rand -hex 32 SECRET_KEY= +# openssl rand -hex 5 +MIDDLEWARE_SECRET_KEY= ALGORITHM=HS256 JWT_TOKEN_EXPIRE_MINUTES=30 +NEW_DAY_OFFSET_MINUTES =420 + ALEMBIC_LOG_LEVEL=INFO ALEMBIC_SQLALCHEMY_LOG_LEVEL=WARN diff --git a/barker/main.py b/barker/main.py index dde7be9..a5dc8d5 100644 --- a/barker/main.py +++ b/barker/main.py @@ -3,62 +3,28 @@ from fastapi import FastAPI from starlette.middleware.sessions import SessionMiddleware from .routers import ( -# account, -# account_types, -# attendance_report, -# attendance_types, -# attendance, -# batch, -# cost_centre, -# credit_salary, -# db_image, -# db_integrity, -# employee, -# employee_attendance, -# employee_benefit, -# fingerprint, -# incentive, -# issue, -# issue_grid, -# lock_information, -# maintenance, menu_category, modifier, modifier_category, printer, product, -# rebase, -# reset_stock, -# recipe, login, sale_category, section, section_printer, table, tax, -# journal, -# purchase, -# purchase_return, -# voucher, ) from .routers.auth import client, user, role -# from .routers.reports import ( -# ledger, -# balance_sheet, -# profit_loss, -# closing_stock, -# cash_flow, -# daybook, -# net_transactions, -# product_ledger, -# purchase_entries, -# purchases, -# raw_material_cost, -# reconcile, -# stock_movement, -# trial_balance, -# unposted, -# ) +from .routers.reports import ( + beer_consumption_report, + bill_settlement_report, + cashier_report, + discount_report, + product_sale_report, + sale_report, + tax_report +) from .db.base_class import Base from .core.config import settings @@ -69,54 +35,36 @@ Base.metadata.create_all(bind=engine) app = FastAPI() -app.add_middleware(SessionMiddleware, secret_key="29e4c76b6c") -# app.include_router(db_image.router, prefix="/db-image", tags=["db-image"]) -app.include_router(login.router, tags=["login"]) -# app.include_router(account.router, prefix="/api/accounts", tags=["accounts"]) -# app.include_router(account_types.router, prefix="/api/account-types", tags=["accounts"]) -# app.include_router(attendance.router, prefix="/api/attendance", tags=["attendance"]) -# app.include_router(attendance_types.router, prefix="/api/attendance-types", tags=["attendance"]) -# app.include_router(employee_attendance.router, prefix="/api/employee-attendance", tags=["attendance"]) -# app.include_router(employee_attendance.router, prefix="/api/employee-attendance", tags=["attendance"]) -# app.include_router(attendance_report.router, prefix="/attendance-report", tags=["attendance"]) +app.add_middleware(SessionMiddleware, secret_key=settings.MIDDLEWARE_SECRET_KEY) -# app.include_router(cost_centre.router, prefix="/api/cost-centres", tags=["cost-centres"]) -# app.include_router(employee.router, prefix="/api/employees", tags=["employees"]) -# app.include_router(fingerprint.router, prefix="/api/fingerprint", tags=["employees"]) +app.include_router(login.router, tags=["login"]) +app.include_router(client.router, prefix="/api/clients", tags=["clients"]) +app.include_router(role.router, prefix="/api/roles", tags=["users"]) +app.include_router(user.router, prefix="/api/users", tags=["users"]) + +app.include_router(modifier.router, prefix="/api/modifiers", tags=["modifiers"]) +app.include_router(modifier_category.router, prefix="/api/modifier-categories", tags=["modifiers"]) app.include_router(printer.router, prefix="/api/printers", tags=["printers"]) app.include_router(menu_category.router, prefix="/api/menu-categories", tags=["products"]) app.include_router(product.router, prefix="/api/products", tags=["products"]) app.include_router(sale_category.router, prefix="/api/sale-categories", tags=["products"]) -app.include_router(tax.router, prefix="/api/taxes", tags=["products"]) - -app.include_router(modifier.router, prefix="/api/modifiers", tags=["modifiers"]) -app.include_router(modifier_category.router, prefix="/api/modifier-categories", tags=["modifiers"]) app.include_router(section.router, prefix="/api/sections", tags=["sections"]) app.include_router(section_printer.router, prefix="/api/section-printers", tags=["section-printers"]) + +app.include_router(tax.router, prefix="/api/taxes", tags=["taxes"]) + app.include_router(table.router, prefix="/api/tables", tags=["tables"]) -app.include_router(client.router, prefix="/api/clients", tags=["clients"]) -app.include_router(role.router, prefix="/api/roles", tags=["users"]) -app.include_router(user.router, prefix="/api/users", tags=["users"]) - -# app.include_router(ledger.router, prefix="/api/ledger", tags=["reports"]) -# app.include_router(balance_sheet.router, prefix="/api/balance-sheet", tags=["reports"]) -# app.include_router(profit_loss.router, prefix="/api/profit-loss", tags=["reports"]) -# app.include_router(closing_stock.router, prefix="/api/closing-stock", tags=["reports"]) -# app.include_router(cash_flow.router, prefix="/api/cash-flow", tags=["reports"]) -# app.include_router(daybook.router, prefix="/api/daybook", tags=["reports"]) -# app.include_router(net_transactions.router, prefix="/api/net-transactions", tags=["reports"]) -# app.include_router(product_ledger.router, prefix="/api/product-ledger", tags=["reports"]) -# app.include_router(purchase_entries.router, prefix="/api/purchase-entries", tags=["reports"]) -# app.include_router(purchases.router, prefix="/api/purchases", tags=["reports"]) -# app.include_router(raw_material_cost.router, prefix="/api/raw-material-cost", tags=["reports"]) -# app.include_router(reconcile.router, prefix="/api/reconcile", tags=["reports"]) -# app.include_router(stock_movement.router, prefix="/api/stock-movement", tags=["reports"]) -# app.include_router(trial_balance.router, prefix="/api/trial-balance", tags=["reports"]) -# app.include_router(unposted.router, prefix="/api/unposted", tags=["reports"]) +app.include_router(beer_consumption_report.router, prefix="/api/beer-consumption-report", tags=["reports"]) +app.include_router(bill_settlement_report.router, prefix="/api/bill-settlement-report", tags=["reports"]) +app.include_router(cashier_report.router, prefix="/api/cashier-report", tags=["reports"]) +app.include_router(discount_report.router, prefix="/api/discount-report", tags=["reports"]) +app.include_router(product_sale_report.router, prefix="/api/product-sale-report", tags=["reports"]) +app.include_router(sale_report.router, prefix="/api/sale-report", tags=["reports"]) +app.include_router(tax_report.router, prefix="/api/tax-report", tags=["reports"]) # app.include_router(issue_grid.router, prefix="/api/issue-grid", tags=["vouchers"]) # app.include_router(batch.router, prefix="/api/batch", tags=["vouchers"]) diff --git a/barker/routers/reports/__init__.py b/barker/routers/reports/__init__.py index 415c491..e69de29 100644 --- a/barker/routers/reports/__init__.py +++ b/barker/routers/reports/__init__.py @@ -1,17 +0,0 @@ -from datetime import datetime, timedelta - -__author__ = "tanshu" - - -def get_start_date(s): - if not s: - return datetime.today().replace(hour=7) - else: - return datetime.strptime(s, "%d-%b-%Y").replace(hour=7) - - -def get_finish_date(f): - if not f: - return datetime.today().replace(hour=7) + timedelta(days=1) - else: - return datetime.strptime(f, "%d-%b-%Y").replace(hour=7) + timedelta(days=1) diff --git a/barker/routers/reports/beer_consumption_report.py b/barker/routers/reports/beer_consumption_report.py index 338e1b1..384bebf 100644 --- a/barker/routers/reports/beer_consumption_report.py +++ b/barker/routers/reports/beer_consumption_report.py @@ -1,32 +1,43 @@ -from datetime import datetime, timedelta +from datetime import datetime, timedelta, date -from pyramid.view import view_config -from sqlalchemy import func +from fastapi import APIRouter, Depends, Security +from sqlalchemy.orm import Session +from sqlalchemy.sql.expression import func -from barker.models import Inventory, Kot, Product, Voucher, VoucherType -from barker.models.validation_exception import ValidationError -from barker.views.reports import get_start_date, get_finish_date +from barker.core.config import settings +from ...models import Inventory, Product, Kot, Voucher, VoucherType +from ...schemas.auth import UserToken +from ...core.security import get_current_active_user as get_user +from ...db.session import SessionLocal + +router = APIRouter() -@view_config( - request_method="GET", - route_name="v1_beer_consumption_report", - renderer="json", - permission="Beer Consumption Report", -) -def beer_consumption(request): - start_date = get_start_date(request.GET.get("s", None)) - timedelta(hours=7) - finish_date = get_finish_date(request.GET.get("f", None)) - timedelta(hours=7) +# Dependency +def get_db() -> Session: + try: + db = SessionLocal() + yield db + finally: + db.close() - if ( - datetime.today() - start_date.replace(hour=0) - ).days > 5 and "Accounts Audit" not in request.effective_principals: - raise ValidationError("Accounts Audit") - day = func.date_trunc("day", Voucher.date - timedelta(hours=7)).label("day") +@router.get("") +def beer_consumption( + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["beer-consumption-report"]), +): + start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions: + raise ValueError("Accounts Audit") + + day = func.date_trunc("day", Voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).label("day") sum_ = func.sum(Inventory.quantity * Product.quantity).label("sum") list_ = ( - request.dbsession.query(day, Product.name, sum_) + db.query(day, Product.name, sum_) .join(Voucher.kots) .join(Kot.inventories) .join(Inventory.product) @@ -44,17 +55,17 @@ def beer_consumption(request): ) headers = [] data = [] - for date, name, quantity in list_: + for date_, name, quantity in list_: if name not in headers: headers.append(name) - old = [d for d in data if d["date"] == date.strftime("%d-%b-%Y")] + old = [d for d in data if d["date"] == date_.strftime("%d-%b-%Y")] if len(old): old[0][name] = quantity else: - data.append({"date": date.strftime("%d-%b-%Y"), name: quantity}) + data.append({"date": date_.strftime("%d-%b-%Y"), name: quantity}) return { - "startDate": start_date.date().strftime("%d-%b-%Y"), - "finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), + "startDate": start_date.strftime("%d-%b-%Y"), + "finishDate": finish_date.strftime("%d-%b-%Y"), "headers": headers, "data": data, } diff --git a/barker/routers/reports/bill_settlement_report.py b/barker/routers/reports/bill_settlement_report.py index be46a3f..08c6d50 100644 --- a/barker/routers/reports/bill_settlement_report.py +++ b/barker/routers/reports/bill_settlement_report.py @@ -1,35 +1,51 @@ -from datetime import datetime, timedelta +from datetime import datetime, timedelta, date -from pyramid.view import view_config +from fastapi import APIRouter, Depends, Security +from sqlalchemy.orm import Session -from barker.models import Settlement, SettleOption, Voucher, VoucherType, Reprint -from barker.models.validation_exception import ValidationError -from barker.views.reports import get_start_date, get_finish_date +from barker.core.config import settings +from ...models import Voucher, VoucherType, Settlement, Reprint, SettleOption +from ...schemas.auth import UserToken +from ...core.security import get_current_active_user as get_user +from ...db.session import SessionLocal + +router = APIRouter() -@view_config( - request_method="GET", route_name="v1_bill_settlement_report", renderer="json", permission="Bill Settlement Report", -) -def bill_details(request): - start_date = get_start_date(request.GET.get("s", None)) - finish_date = get_finish_date(request.GET.get("f", None)) +# Dependency +def get_db() -> Session: + try: + db = SessionLocal() + yield db + finally: + db.close() - if ( - datetime.today() - start_date.replace(hour=0) - ).days > 5 and "Accounts Audit" not in request.effective_principals: - raise ValidationError("Accounts Audit") + +@router.get("") +def bill_details( + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["bill-settlement-report"]), +): + start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions: + raise ValueError("Accounts Audit") return { - "startDate": start_date.date().strftime("%d-%b-%Y"), - "finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), - "amounts": settlements(start_date, finish_date, request.dbsession) - + reprints(start_date, finish_date, request.dbsession), + "startDate": start_date.strftime("%d-%b-%Y"), + "finishDate": finish_date.strftime("%d-%b-%Y"), + "amounts": settlements(start_date, finish_date, db) + + reprints(start_date, finish_date, db), } -def settlements(start_date, finish_date, dbsession): +def settlements(s: date, f: date, db: Session): + start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES) + finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES) vouchers = ( - dbsession.query(Voucher) + db.query(Voucher) .join(Voucher.settlements) .join(Settlement.settle_option) .filter(Voucher.date >= start_date, Voucher.date <= finish_date) @@ -60,7 +76,9 @@ def settlements(start_date, finish_date, dbsession): return report -def reprints(start_date, finish_date, dbsession): +def reprints(s: date, f: date, db: Session): + start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES) + finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES) return [ { "date": item.date.strftime("%d-%b-%Y %H:%M:%S"), @@ -70,5 +88,5 @@ def reprints(start_date, finish_date, dbsession): next(s.amount for s in item.voucher.settlements if s.settled == SettleOption.AMOUNT()) * -1, 2, ), } - for item in dbsession.query(Reprint).filter(Reprint.date >= start_date, Reprint.date <= finish_date).all() + for item in db.query(Reprint).filter(Reprint.date >= start_date, Reprint.date <= finish_date).all() ] diff --git a/barker/routers/reports/cashier_report.py b/barker/routers/reports/cashier_report.py index 6871aec..9d1ee60 100644 --- a/barker/routers/reports/cashier_report.py +++ b/barker/routers/reports/cashier_report.py @@ -1,65 +1,78 @@ import uuid +from datetime import datetime, timedelta, date -from datetime import datetime, timedelta -from barker.models import Voucher, User, Settlement -from pyramid.view import view_config -from sqlalchemy.orm import joinedload +from fastapi import APIRouter, Depends, Security +from sqlalchemy import distinct +from sqlalchemy.orm import Session, joinedload -from barker.views.reports import get_start_date, get_finish_date +from ...core.config import settings +from ...models import Voucher, Settlement, User +from ...schemas.auth import UserToken +from ...core.security import get_current_active_user as get_user +from ...db.session import SessionLocal -__author__ = "tanshu" +router = APIRouter() -@view_config( - request_method="GET", route_name="v1_active_cashiers", renderer="json", permission="Cashier Report", -) -def active_cashiers(request): - start_date = get_start_date(request.GET.get("s", None)) - finish_date = get_finish_date(request.GET.get("f", None)) +# Dependency +def get_db() -> Session: + try: + db = SessionLocal() + yield db + finally: + db.close() - user_ids = ( - request.dbsession.query(Voucher.user_id) - .filter(Voucher.date >= start_date, Voucher.date <= finish_date) - .distinct() + +@router.get("/active") +def active_cashiers( + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["cashier-report"]), +): + start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions: + raise ValueError("Accounts Audit") + + users = ( + db.query(User) + .filter( + User.id.in_( + db.query(distinct(Voucher.user_id)).filter( + Voucher.date >= start_date + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES), + Voucher.date <= finish_date + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES), + ) + ) + ) + .order_by(User.name) + .all() ) - users = request.dbsession.query(User).filter(User.id.in_(user_ids)).order_by(User.name).all() - return [{"id": u.id, "name": u.name} for u in users] -@view_config( - request_method="GET", route_name="v1_cashier_report", renderer="json", permission="Cashier Report", -) -def blank_out(request): - start_date = request.GET.get("s", datetime.today().strftime("%d-%b-%Y")) - finish_date = request.GET.get("f", datetime.today().strftime("%d-%b-%Y")) - - return { - "startDate": start_date, - "finishDate": finish_date, - "user": {"id": ""}, - "amounts": [], - "info": [], - } - - -@view_config( - request_method="GET", - route_name="v1_cashier_report_id", - renderer="json", - permission="Cashier Report", - request_param=("s", "f"), -) -def check_me_out(request): - id_ = uuid.UUID(request.matchdict["id"]) - start_date = get_start_date(request.GET.get("s", None)) - finish_date = get_finish_date(request.GET.get("f", None)) +@router.get("/{id_}") +def show_id( + id_: uuid.UUID, + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["cashier-report"]), +): + start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions: + raise ValueError("Accounts Audit") vouchers = ( - request.dbsession.query(Voucher) + db.query(Voucher) .options(joinedload(Voucher.settlements, innerjoin=True).joinedload(Settlement.settle_option, innerjoin=True)) - .filter(Voucher.date >= start_date, Voucher.date <= finish_date, Voucher.user_id == id_,) + .filter( + Voucher.date >= start_date + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES), + Voucher.date <= finish_date + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES), + Voucher.user_id == id_, + ) .order_by(Voucher.voucher_type) .order_by(Voucher.bill_id) .all() @@ -82,9 +95,30 @@ def check_me_out(request): ) amounts[so.settle_option.name] += so.amount return { - "startDate": start_date.date().strftime("%d-%b-%Y"), - "finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), + "startDate": start_date.strftime("%d-%b-%Y"), + "finishDate": finish_date.strftime("%d-%b-%Y"), "user": {"id": id_}, "amounts": [{"name": key, "amount": value} for key, value in amounts.items()], "info": info, } + + +@router.get("") +def show_blank( + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["cashier-report"]), +): + start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions: + raise ValueError("Accounts Audit") + + return { + "startDate": start_date.strftime("%d-%b-%Y"), + "finishDate": finish_date.strftime("%d-%b-%Y"), + "user": {"id": ""}, + "amounts": [], + "info": [], + } diff --git a/barker/routers/reports/discount_report.py b/barker/routers/reports/discount_report.py index dfcb73e..8931b3f 100644 --- a/barker/routers/reports/discount_report.py +++ b/barker/routers/reports/discount_report.py @@ -1,36 +1,53 @@ -from datetime import datetime, timedelta +from datetime import datetime, timedelta, date -from pyramid.view import view_config +from fastapi import APIRouter, Depends, Security from sqlalchemy import func +from sqlalchemy.orm import Session -from barker.models import Inventory, Kot, Product, Voucher, SaleCategory, VoucherType -from barker.models.validation_exception import ValidationError -from barker.views.reports import get_start_date, get_finish_date +from barker.core.config import settings +from ...models import Voucher, VoucherType, Settlement, Reprint, SettleOption, Inventory, SaleCategory, Kot, Product +from ...schemas.auth import UserToken +from ...core.security import get_current_active_user as get_user +from ...db.session import SessionLocal + +router = APIRouter() -@view_config( - request_method="GET", route_name="v1_discount_report", renderer="json", permission="Discount Report", -) -def discount_report_view(request): - start_date = get_start_date(request.GET.get("s", None)) - finish_date = get_finish_date(request.GET.get("f", None)) +# Dependency +def get_db() -> Session: + try: + db = SessionLocal() + yield db + finally: + db.close() - if ( - datetime.today() - start_date.replace(hour=0) - ).days > 5 and "Accounts Audit" not in request.effective_principals: - raise ValidationError("Accounts Audit") + +@router.get("") +def discount_report_view( + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["discount-report"]), +): + start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions: + raise ValueError("Accounts Audit") return { - "startDate": start_date.date().strftime("%d-%b-%Y"), - "finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), - "amounts": discount_report(start_date, finish_date, request.dbsession), + "startDate": start_date.strftime("%d-%b-%Y"), + "finishDate": finish_date.strftime("%d-%b-%Y"), + "amounts": discount_report(start_date, finish_date, db), } -def discount_report(start_date, finish_date, dbsession): +def discount_report(s: date, f: date, db: Session): + start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES) + finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES) + amount = func.sum(Inventory.quantity * Inventory.effective_price * Inventory.discount).label("Amount") list_ = ( - dbsession.query(SaleCategory.name, amount) + db.query(SaleCategory.name, amount) .join(Voucher.kots) .join(Kot.inventories) .join(Inventory.product) diff --git a/barker/routers/reports/product_sale_report.py b/barker/routers/reports/product_sale_report.py index aeccc8b..f107457 100644 --- a/barker/routers/reports/product_sale_report.py +++ b/barker/routers/reports/product_sale_report.py @@ -1,42 +1,54 @@ -from datetime import datetime, timedelta -from pyramid.view import view_config +from datetime import datetime, timedelta, date + +from fastapi import APIRouter, Depends, Security from sqlalchemy import func +from sqlalchemy.orm import Session -from barker.models import ( - Inventory, - Kot, - Product, - Voucher, - SaleCategory, - VoucherType, - MenuCategory, -) -from barker.models.validation_exception import ValidationError -from barker.views.reports import get_start_date, get_finish_date +from barker.core.config import settings +from ...models import Voucher, VoucherType, Product, Inventory, Kot, SaleCategory, \ + MenuCategory +from ...schemas import to_camel +from ...schemas.auth import UserToken +from ...core.security import get_current_active_user as get_user +from ...db.session import SessionLocal + +router = APIRouter() -@view_config( - request_method="GET", route_name="v1_product_sale_report", renderer="json", permission="Product Sale Report", -) -def product_sale_report_view(request): - start_date = get_start_date(request.GET.get("s", None)) - finish_date = get_finish_date(request.GET.get("f", None)) +# Dependency +def get_db() -> Session: + try: + db = SessionLocal() + yield db + finally: + db.close() - if ( - datetime.today() - start_date.replace(hour=0) - ).days > 5 and "Accounts Audit" not in request.effective_principals: - raise ValidationError("Accounts Audit") + +@router.get("") +def product_sale_report_view( + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["product-sale-report"]), +): + start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions: + raise ValueError("Accounts Audit") return { - "startDate": start_date.date().strftime("%d-%b-%Y"), - "finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), - "amounts": product_sale_report(start_date, finish_date, request.dbsession), + "startDate": start_date.strftime("%d-%b-%Y"), + "finishDate": finish_date.strftime("%d-%b-%Y"), + "amounts": product_sale_report(start_date, finish_date, db), } -def product_sale_report(start_date, finish_date, dbsession): +def product_sale_report(s: date, f: date, db: Session): + start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES) + finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES) + list_ = ( - dbsession.query( + db.query( Product.id, Product.full_name, Voucher.voucher_type, Inventory.is_happy_hour, func.sum(Inventory.quantity), ) .join(Inventory.kot) @@ -58,7 +70,7 @@ def product_sale_report(start_date, finish_date, dbsession): ) info = [] for id_, name, type_, hh, quantity in list_: - type_ = to_camel_case(VoucherType(type_).name) + type_ = to_camel(VoucherType(type_).name) old = [i for i in info if i["id"] == id_ and i["isHappyHour"] == hh] if len(old): old[0][type_] = quantity @@ -69,8 +81,3 @@ def product_sale_report(start_date, finish_date, dbsession): return info -def to_camel_case(snake_str): - components = snake_str.split("_") - # We capitalize the first letter of each component except the first one - # with the 'title' method and join them together. - return components[0].lower() + "".join(x.title() for x in components[1:]) diff --git a/barker/routers/reports/sale_report.py b/barker/routers/reports/sale_report.py index 8bb1a81..43235b5 100644 --- a/barker/routers/reports/sale_report.py +++ b/barker/routers/reports/sale_report.py @@ -1,50 +1,59 @@ -from datetime import datetime, timedelta -from pyramid.view import view_config +from datetime import datetime, timedelta, date + +from fastapi import APIRouter, Depends, Security from sqlalchemy import func +from sqlalchemy.orm import Session -from barker.models import ( - Inventory, - Kot, - Product, - Settlement, - SettleOption, - Tax, - Voucher, - SaleCategory, - VoucherType, -) -from barker.models.validation_exception import ValidationError -from barker.views.reports import get_start_date, get_finish_date +from barker.core.config import settings +from .tax_report import get_tax +from ...models import Voucher, VoucherType, Settlement, SettleOption, Product, Inventory, Kot, SaleCategory +from ...schemas.auth import UserToken +from ...core.security import get_current_active_user as get_user +from ...db.session import SessionLocal + +router = APIRouter() -@view_config( - request_method="GET", route_name="v1_sale_report", renderer="json", permission="Sale Report", -) -def get_sale_analysis(request): - start_date = get_start_date(request.GET.get("s", None)) - finish_date = get_finish_date(request.GET.get("f", None)) +# Dependency +def get_db() -> Session: + try: + db = SessionLocal() + yield db + finally: + db.close() - if ( - datetime.today() - start_date.replace(hour=0) - ).days > 5 and "Accounts Audit" not in request.effective_principals: - raise ValidationError("Accounts Audit") + +@router.get("") +def get_sale_analysis( + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["sale-report"]), +): + start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions: + raise ValueError("Accounts Audit") return { - "startDate": start_date.date().strftime("%d-%b-%Y"), - "finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), + "startDate": start_date.strftime("%d-%b-%Y"), + "finishDate": finish_date.strftime("%d-%b-%Y"), "amounts": ( - get_sale(start_date, finish_date, request.dbsession) + get_sale(start_date, finish_date, db) + [{"name": "--", "amount": 0}] - + get_settlements(start_date, finish_date, request.dbsession) + + get_settlements(start_date, finish_date, db) + [{"name": "--", "amount": 0}] - + get_tax(start_date, finish_date, request.dbsession) + + get_tax(start_date, finish_date, db) ), } -def get_sale(start_date, finish_date, dbsession): +def get_sale(s: date, f: date, db: Session): + start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES) + finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES) + list_ = ( - dbsession.query(SaleCategory.name, func.sum(Inventory.net)) + db.query(SaleCategory.name, func.sum(Inventory.net)) .join(Inventory.kot) .join(Kot.voucher) .join(Inventory.product) @@ -66,9 +75,12 @@ def get_sale(start_date, finish_date, dbsession): return info + [{"name": "Total Settled", "amount": total}] -def get_settlements(start_date, finish_date, dbsession): +def get_settlements(s: date, f: date, db: Session): + start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES) + finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES) + list_ = ( - dbsession.query(SettleOption.name, func.sum(Settlement.amount)) + db.query(SettleOption.name, func.sum(Settlement.amount)) .join(Voucher.settlements) .join(Settlement.settle_option) .filter(Voucher.date >= start_date, Voucher.date <= finish_date) @@ -82,48 +94,3 @@ def get_settlements(start_date, finish_date, dbsession): total += am info.append({"name": gt, "amount": am}) return info + [{"name": "Total", "amount": total}] - - -@view_config( - request_method="GET", route_name="v1_tax_report", renderer="json", permission="Tax Report", -) -def get_tax_view(request): - start_date = get_start_date(request.GET.get("s", None)) - finish_date = get_finish_date(request.GET.get("f", None)) - - if ( - datetime.today() - start_date.replace(hour=0) - ).days > 5 and "Accounts Audit" not in request.effective_principals: - raise ValidationError("Accounts Audit") - - return { - "startDate": start_date.date().strftime("%d-%b-%Y"), - "finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), - "amounts": get_tax(start_date, finish_date, request.dbsession), - } - - -def get_tax(start_date, finish_date, dbsession): - amounts = ( - dbsession.query( - Tax.name, - Inventory.tax_rate, - func.coalesce(func.sum(Inventory.net), 0), - func.coalesce(func.sum(Inventory.tax_amount), 0), - ) - .join(Voucher.kots) - .join(Kot.inventories) - .join(Inventory.tax) - .filter( - Voucher.date >= start_date, - Voucher.date <= finish_date, - Voucher.voucher_type == VoucherType.REGULAR_BILL.value, - ) - .group_by(Tax.name, Inventory.tax_rate) - .order_by(Tax.name, Inventory.tax_rate) - .all() - ) - return [ - {"name": "{0} - {1:.2%}".format(i[0], i[1]), "taxRate": i[1], "saleAmount": i[2], "amount": i[3],} - for i in amounts - ] diff --git a/barker/routers/reports/tax_report.py b/barker/routers/reports/tax_report.py new file mode 100644 index 0000000..42f1f92 --- /dev/null +++ b/barker/routers/reports/tax_report.py @@ -0,0 +1,70 @@ +from datetime import datetime, timedelta, date + +from fastapi import APIRouter, Depends, Security +from sqlalchemy import func +from sqlalchemy.orm import Session + +from barker.core.config import settings +from ...models import Voucher, VoucherType, Inventory, Kot, Tax +from ...schemas.auth import UserToken +from ...core.security import get_current_active_user as get_user +from ...db.session import SessionLocal + +router = APIRouter() + + +# Dependency +def get_db() -> Session: + try: + db = SessionLocal() + yield db + finally: + db.close() + + +@router.get("") +def get_tax_report( + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["tax-report"]), +): + start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions: + raise ValueError("Accounts Audit") + + return { + "startDate": start_date.strftime("%d-%b-%Y"), + "finishDate": finish_date.strftime("%d-%b-%Y"), + "amounts": get_tax(start_date, finish_date, db), + } + + +def get_tax(s: date, f: date, db: Session): + start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES) + finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES) + + amounts = ( + db.query( + Tax.name, + Inventory.tax_rate, + func.coalesce(func.sum(Inventory.net), 0), + func.coalesce(func.sum(Inventory.tax_amount), 0), + ) + .join(Voucher.kots) + .join(Kot.inventories) + .join(Inventory.tax) + .filter( + Voucher.date >= start_date, + Voucher.date <= finish_date, + Voucher.voucher_type == VoucherType.REGULAR_BILL.value, + ) + .group_by(Tax.name, Inventory.tax_rate) + .order_by(Tax.name, Inventory.tax_rate) + .all() + ) + return [ + {"name": "{0} - {1:.2%}".format(i[0], i[1]), "taxRate": i[1], "saleAmount": i[2], "amount": i[3],} + for i in amounts + ] diff --git a/barker/routers/tax.py b/barker/routers/tax.py index 0ff24db..5107ebd 100644 --- a/barker/routers/tax.py +++ b/barker/routers/tax.py @@ -25,7 +25,7 @@ def get_db(): @router.post("/", response_model=schemas.Tax) def save( - data: schemas.TaxIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]), + data: schemas.TaxIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["taxes"]), ): try: item = Tax(name=data.name, rate=data.rate) @@ -47,7 +47,7 @@ def update( id_: uuid.UUID, data: schemas.TaxIn, db: Session = Depends(get_db), - user: UserToken = Security(get_user, scopes=["products"]), + user: UserToken = Security(get_user, scopes=["taxes"]), ): try: item: Tax = db.query(Tax).filter(Tax.id == id_).first() @@ -71,7 +71,7 @@ def update( @router.delete("/{id_}") def delete( - id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]), + id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["taxes"]), ): try: item: Tax = db.query(Tax).filter(Tax.id == id_).first() @@ -94,7 +94,7 @@ def delete( @router.get("/") def show_blank( - db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]), + db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["taxes"]), ): return tax_info(None) @@ -109,7 +109,7 @@ def show_list(db: Session = Depends(get_db), user: UserToken = Depends(get_user) @router.get("/{id_}") def show_id( - id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]), + id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["taxes"]), ): item: Tax = db.query(Tax).filter(Tax.id == id_).first() return tax_info(item) diff --git a/barker/schemas/__init__.py b/barker/schemas/__init__.py index 2a02c89..1b7e4a2 100644 --- a/barker/schemas/__init__.py +++ b/barker/schemas/__init__.py @@ -1,3 +1,3 @@ def to_camel(string: str) -> str: first, *others = string.split("_") - return "".join([first] + [word.capitalize() for word in others]) + return "".join([first.lower()] + [word.capitalize() for word in others]) diff --git a/bookie/src/app/beer-consumption-report/beer-consumption-report.service.ts b/bookie/src/app/beer-consumption-report/beer-consumption-report.service.ts index e6cb6e5..b289845 100644 --- a/bookie/src/app/beer-consumption-report/beer-consumption-report.service.ts +++ b/bookie/src/app/beer-consumption-report/beer-consumption-report.service.ts @@ -9,7 +9,7 @@ const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) }; -const url = '/v1/beer-consumption-report'; +const url = '/api/beer-consumption-report'; const serviceName = 'BeerConsumptionReportService'; @Injectable({ diff --git a/bookie/src/app/bill-settlement-report/bill-settlement-report.service.ts b/bookie/src/app/bill-settlement-report/bill-settlement-report.service.ts index f040059..0f65648 100644 --- a/bookie/src/app/bill-settlement-report/bill-settlement-report.service.ts +++ b/bookie/src/app/bill-settlement-report/bill-settlement-report.service.ts @@ -9,7 +9,7 @@ const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) }; -const url = '/v1/bill-settlement-report'; +const url = '/api/bill-settlement-report'; const serviceName = 'BillSettlementReportService'; @Injectable({ diff --git a/bookie/src/app/cashier-report/cashier-report.service.ts b/bookie/src/app/cashier-report/cashier-report.service.ts index 57ad801..7ca5f47 100644 --- a/bookie/src/app/cashier-report/cashier-report.service.ts +++ b/bookie/src/app/cashier-report/cashier-report.service.ts @@ -10,8 +10,7 @@ const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) }; -const url = '/v1/cashier-report'; -const urlActiveCashiers = '/v1/active-cashiers'; +const url = '/api/cashier-report'; const serviceName = 'CashierReportService'; @Injectable({ @@ -45,7 +44,7 @@ export class CashierReportService { if (finishDate !== null) { options.params = options.params.set('f', finishDate); } - return >this.http.get(urlActiveCashiers, options) + return >this.http.get(`${url}/active`, options) .pipe( catchError(this.log.handleError(serviceName, 'activeCashiers')) diff --git a/bookie/src/app/discount-report/discount-report.service.ts b/bookie/src/app/discount-report/discount-report.service.ts index 74da45f..ca5c182 100644 --- a/bookie/src/app/discount-report/discount-report.service.ts +++ b/bookie/src/app/discount-report/discount-report.service.ts @@ -9,7 +9,7 @@ const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) }; -const url = '/v1/discount-report'; +const url = '/api/discount-report'; const serviceName = 'DiscountReportService'; @Injectable({ diff --git a/bookie/src/app/product-sale-report/product-sale-report.service.ts b/bookie/src/app/product-sale-report/product-sale-report.service.ts index 6bbcde8..817d43e 100644 --- a/bookie/src/app/product-sale-report/product-sale-report.service.ts +++ b/bookie/src/app/product-sale-report/product-sale-report.service.ts @@ -9,7 +9,7 @@ const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) }; -const url = '/v1/product-sale-report'; +const url = '/api/product-sale-report'; const serviceName = 'ProductSaleReportService'; @Injectable({ diff --git a/bookie/src/app/sale-report/sale-report.service.ts b/bookie/src/app/sale-report/sale-report.service.ts index 1ad3ed2..aded4cf 100644 --- a/bookie/src/app/sale-report/sale-report.service.ts +++ b/bookie/src/app/sale-report/sale-report.service.ts @@ -9,7 +9,7 @@ const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) }; -const url = '/v1/sale-report'; +const url = '/api/sale-report'; const serviceName = 'SaleReportService'; @Injectable({ diff --git a/bookie/src/app/tax-report/tax-report.service.ts b/bookie/src/app/tax-report/tax-report.service.ts index 87e9f94..f4d9d8a 100644 --- a/bookie/src/app/tax-report/tax-report.service.ts +++ b/bookie/src/app/tax-report/tax-report.service.ts @@ -9,7 +9,7 @@ const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) }; -const url = '/v1/tax-report'; +const url = '/api/tax-report'; const serviceName = 'TaxReportService'; @Injectable({