All Reports done!!

This commit is contained in:
2020-06-17 09:57:41 +05:30
parent 938bb67e0a
commit 7b6c09cea3
19 changed files with 401 additions and 342 deletions

View File

@ -10,9 +10,14 @@ POSTGRES_USER=
POSTGRES_PASSWORD= POSTGRES_PASSWORD=
POSTGRES_DB= POSTGRES_DB=
# openssl rand -hex 32
SECRET_KEY= SECRET_KEY=
# openssl rand -hex 5
MIDDLEWARE_SECRET_KEY=
ALGORITHM=HS256 ALGORITHM=HS256
JWT_TOKEN_EXPIRE_MINUTES=30 JWT_TOKEN_EXPIRE_MINUTES=30
NEW_DAY_OFFSET_MINUTES =420
ALEMBIC_LOG_LEVEL=INFO ALEMBIC_LOG_LEVEL=INFO
ALEMBIC_SQLALCHEMY_LOG_LEVEL=WARN ALEMBIC_SQLALCHEMY_LOG_LEVEL=WARN

View File

@ -3,62 +3,28 @@ from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware from starlette.middleware.sessions import SessionMiddleware
from .routers import ( 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, menu_category,
modifier, modifier,
modifier_category, modifier_category,
printer, printer,
product, product,
# rebase,
# reset_stock,
# recipe,
login, login,
sale_category, sale_category,
section, section,
section_printer, section_printer,
table, table,
tax, tax,
# journal,
# purchase,
# purchase_return,
# voucher,
) )
from .routers.auth import client, user, role from .routers.auth import client, user, role
# from .routers.reports import ( from .routers.reports import (
# ledger, beer_consumption_report,
# balance_sheet, bill_settlement_report,
# profit_loss, cashier_report,
# closing_stock, discount_report,
# cash_flow, product_sale_report,
# daybook, sale_report,
# net_transactions, tax_report
# product_ledger, )
# purchase_entries,
# purchases,
# raw_material_cost,
# reconcile,
# stock_movement,
# trial_balance,
# unposted,
# )
from .db.base_class import Base from .db.base_class import Base
from .core.config import settings from .core.config import settings
@ -69,54 +35,36 @@ Base.metadata.create_all(bind=engine)
app = FastAPI() app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="29e4c76b6c") app.add_middleware(SessionMiddleware, secret_key=settings.MIDDLEWARE_SECRET_KEY)
# 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.include_router(cost_centre.router, prefix="/api/cost-centres", tags=["cost-centres"]) app.include_router(login.router, tags=["login"])
# app.include_router(employee.router, prefix="/api/employees", tags=["employees"]) app.include_router(client.router, prefix="/api/clients", tags=["clients"])
# app.include_router(fingerprint.router, prefix="/api/fingerprint", tags=["employees"]) 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(printer.router, prefix="/api/printers", tags=["printers"])
app.include_router(menu_category.router, prefix="/api/menu-categories", tags=["products"]) 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(product.router, prefix="/api/products", tags=["products"])
app.include_router(sale_category.router, prefix="/api/sale-categories", 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.router, prefix="/api/sections", tags=["sections"])
app.include_router(section_printer.router, prefix="/api/section-printers", tags=["section-printers"]) 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(table.router, prefix="/api/tables", tags=["tables"])
app.include_router(client.router, prefix="/api/clients", tags=["clients"]) app.include_router(beer_consumption_report.router, prefix="/api/beer-consumption-report", tags=["reports"])
app.include_router(role.router, prefix="/api/roles", tags=["users"]) app.include_router(bill_settlement_report.router, prefix="/api/bill-settlement-report", tags=["reports"])
app.include_router(user.router, prefix="/api/users", tags=["users"]) 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(ledger.router, prefix="/api/ledger", tags=["reports"]) app.include_router(product_sale_report.router, prefix="/api/product-sale-report", tags=["reports"])
# app.include_router(balance_sheet.router, prefix="/api/balance-sheet", tags=["reports"]) app.include_router(sale_report.router, prefix="/api/sale-report", tags=["reports"])
# app.include_router(profit_loss.router, prefix="/api/profit-loss", tags=["reports"]) app.include_router(tax_report.router, prefix="/api/tax-report", 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(issue_grid.router, prefix="/api/issue-grid", tags=["vouchers"]) # app.include_router(issue_grid.router, prefix="/api/issue-grid", tags=["vouchers"])
# app.include_router(batch.router, prefix="/api/batch", tags=["vouchers"]) # app.include_router(batch.router, prefix="/api/batch", tags=["vouchers"])

View File

@ -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)

View File

@ -1,32 +1,43 @@
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 sqlalchemy.sql.expression import func
from barker.models import Inventory, Kot, Product, Voucher, VoucherType from barker.core.config import settings
from barker.models.validation_exception import ValidationError from ...models import Inventory, Product, Kot, Voucher, VoucherType
from barker.views.reports import get_start_date, get_finish_date 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( # Dependency
request_method="GET", def get_db() -> Session:
route_name="v1_beer_consumption_report", try:
renderer="json", db = SessionLocal()
permission="Beer Consumption Report", yield db
) finally:
def beer_consumption(request): db.close()
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)
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") sum_ = func.sum(Inventory.quantity * Product.quantity).label("sum")
list_ = ( list_ = (
request.dbsession.query(day, Product.name, sum_) db.query(day, Product.name, sum_)
.join(Voucher.kots) .join(Voucher.kots)
.join(Kot.inventories) .join(Kot.inventories)
.join(Inventory.product) .join(Inventory.product)
@ -44,17 +55,17 @@ def beer_consumption(request):
) )
headers = [] headers = []
data = [] data = []
for date, name, quantity in list_: for date_, name, quantity in list_:
if name not in headers: if name not in headers:
headers.append(name) 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): if len(old):
old[0][name] = quantity old[0][name] = quantity
else: else:
data.append({"date": date.strftime("%d-%b-%Y"), name: quantity}) data.append({"date": date_.strftime("%d-%b-%Y"), name: quantity})
return { return {
"startDate": start_date.date().strftime("%d-%b-%Y"), "startDate": start_date.strftime("%d-%b-%Y"),
"finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), "finishDate": finish_date.strftime("%d-%b-%Y"),
"headers": headers, "headers": headers,
"data": data, "data": data,
} }

View File

@ -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.core.config import settings
from barker.models.validation_exception import ValidationError from ...models import Voucher, VoucherType, Settlement, Reprint, SettleOption
from barker.views.reports import get_start_date, get_finish_date 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( # Dependency
request_method="GET", route_name="v1_bill_settlement_report", renderer="json", permission="Bill Settlement Report", def get_db() -> Session:
) try:
def bill_details(request): db = SessionLocal()
start_date = get_start_date(request.GET.get("s", None)) yield db
finish_date = get_finish_date(request.GET.get("f", None)) finally:
db.close()
if (
datetime.today() - start_date.replace(hour=0) @router.get("")
).days > 5 and "Accounts Audit" not in request.effective_principals: def bill_details(
raise ValidationError("Accounts Audit") 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 { return {
"startDate": start_date.date().strftime("%d-%b-%Y"), "startDate": start_date.strftime("%d-%b-%Y"),
"finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), "finishDate": finish_date.strftime("%d-%b-%Y"),
"amounts": settlements(start_date, finish_date, request.dbsession) "amounts": settlements(start_date, finish_date, db)
+ reprints(start_date, finish_date, request.dbsession), + 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 = ( vouchers = (
dbsession.query(Voucher) db.query(Voucher)
.join(Voucher.settlements) .join(Voucher.settlements)
.join(Settlement.settle_option) .join(Settlement.settle_option)
.filter(Voucher.date >= start_date, Voucher.date <= finish_date) .filter(Voucher.date >= start_date, Voucher.date <= finish_date)
@ -60,7 +76,9 @@ def settlements(start_date, finish_date, dbsession):
return report 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 [ return [
{ {
"date": item.date.strftime("%d-%b-%Y %H:%M:%S"), "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, 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()
] ]

View File

@ -1,65 +1,78 @@
import uuid import uuid
from datetime import datetime, timedelta, date
from datetime import datetime, timedelta from fastapi import APIRouter, Depends, Security
from barker.models import Voucher, User, Settlement from sqlalchemy import distinct
from pyramid.view import view_config from sqlalchemy.orm import Session, joinedload
from sqlalchemy.orm import 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( # Dependency
request_method="GET", route_name="v1_active_cashiers", renderer="json", permission="Cashier Report", def get_db() -> Session:
) try:
def active_cashiers(request): db = SessionLocal()
start_date = get_start_date(request.GET.get("s", None)) yield db
finish_date = get_finish_date(request.GET.get("f", None)) finally:
db.close()
user_ids = (
request.dbsession.query(Voucher.user_id) @router.get("/active")
.filter(Voucher.date >= start_date, Voucher.date <= finish_date) def active_cashiers(
.distinct() 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] return [{"id": u.id, "name": u.name} for u in users]
@view_config( @router.get("/{id_}")
request_method="GET", route_name="v1_cashier_report", renderer="json", permission="Cashier Report", def show_id(
) id_: uuid.UUID,
def blank_out(request): s: str = None,
start_date = request.GET.get("s", datetime.today().strftime("%d-%b-%Y")) f: str = None,
finish_date = request.GET.get("f", datetime.today().strftime("%d-%b-%Y")) db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["cashier-report"]),
return { ):
"startDate": start_date, start_date = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date()
"finishDate": finish_date, finish_date = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date()
"user": {"id": ""}, if (date.today() - start_date).days > 5 and "accounts-audit" not in user.permissions:
"amounts": [], raise ValueError("Accounts Audit")
"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))
vouchers = ( vouchers = (
request.dbsession.query(Voucher) db.query(Voucher)
.options(joinedload(Voucher.settlements, innerjoin=True).joinedload(Settlement.settle_option, innerjoin=True)) .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.voucher_type)
.order_by(Voucher.bill_id) .order_by(Voucher.bill_id)
.all() .all()
@ -82,9 +95,30 @@ def check_me_out(request):
) )
amounts[so.settle_option.name] += so.amount amounts[so.settle_option.name] += so.amount
return { return {
"startDate": start_date.date().strftime("%d-%b-%Y"), "startDate": start_date.strftime("%d-%b-%Y"),
"finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), "finishDate": finish_date.strftime("%d-%b-%Y"),
"user": {"id": id_}, "user": {"id": id_},
"amounts": [{"name": key, "amount": value} for key, value in amounts.items()], "amounts": [{"name": key, "amount": value} for key, value in amounts.items()],
"info": info, "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": [],
}

View File

@ -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 import func
from sqlalchemy.orm import Session
from barker.models import Inventory, Kot, Product, Voucher, SaleCategory, VoucherType from barker.core.config import settings
from barker.models.validation_exception import ValidationError from ...models import Voucher, VoucherType, Settlement, Reprint, SettleOption, Inventory, SaleCategory, Kot, Product
from barker.views.reports import get_start_date, get_finish_date 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( # Dependency
request_method="GET", route_name="v1_discount_report", renderer="json", permission="Discount Report", def get_db() -> Session:
) try:
def discount_report_view(request): db = SessionLocal()
start_date = get_start_date(request.GET.get("s", None)) yield db
finish_date = get_finish_date(request.GET.get("f", None)) finally:
db.close()
if (
datetime.today() - start_date.replace(hour=0) @router.get("")
).days > 5 and "Accounts Audit" not in request.effective_principals: def discount_report_view(
raise ValidationError("Accounts Audit") 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 { return {
"startDate": start_date.date().strftime("%d-%b-%Y"), "startDate": start_date.strftime("%d-%b-%Y"),
"finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), "finishDate": finish_date.strftime("%d-%b-%Y"),
"amounts": discount_report(start_date, finish_date, request.dbsession), "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") amount = func.sum(Inventory.quantity * Inventory.effective_price * Inventory.discount).label("Amount")
list_ = ( list_ = (
dbsession.query(SaleCategory.name, amount) db.query(SaleCategory.name, amount)
.join(Voucher.kots) .join(Voucher.kots)
.join(Kot.inventories) .join(Kot.inventories)
.join(Inventory.product) .join(Inventory.product)

View File

@ -1,42 +1,54 @@
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 import func
from sqlalchemy.orm import Session
from barker.models import ( from barker.core.config import settings
Inventory, from ...models import Voucher, VoucherType, Product, Inventory, Kot, SaleCategory, \
Kot, MenuCategory
Product, from ...schemas import to_camel
Voucher, from ...schemas.auth import UserToken
SaleCategory, from ...core.security import get_current_active_user as get_user
VoucherType, from ...db.session import SessionLocal
MenuCategory,
) router = APIRouter()
from barker.models.validation_exception import ValidationError
from barker.views.reports import get_start_date, get_finish_date
@view_config( # Dependency
request_method="GET", route_name="v1_product_sale_report", renderer="json", permission="Product Sale Report", def get_db() -> Session:
) try:
def product_sale_report_view(request): db = SessionLocal()
start_date = get_start_date(request.GET.get("s", None)) yield db
finish_date = get_finish_date(request.GET.get("f", None)) finally:
db.close()
if (
datetime.today() - start_date.replace(hour=0) @router.get("")
).days > 5 and "Accounts Audit" not in request.effective_principals: def product_sale_report_view(
raise ValidationError("Accounts Audit") 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 { return {
"startDate": start_date.date().strftime("%d-%b-%Y"), "startDate": start_date.strftime("%d-%b-%Y"),
"finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), "finishDate": finish_date.strftime("%d-%b-%Y"),
"amounts": product_sale_report(start_date, finish_date, request.dbsession), "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_ = ( list_ = (
dbsession.query( db.query(
Product.id, Product.full_name, Voucher.voucher_type, Inventory.is_happy_hour, func.sum(Inventory.quantity), Product.id, Product.full_name, Voucher.voucher_type, Inventory.is_happy_hour, func.sum(Inventory.quantity),
) )
.join(Inventory.kot) .join(Inventory.kot)
@ -58,7 +70,7 @@ def product_sale_report(start_date, finish_date, dbsession):
) )
info = [] info = []
for id_, name, type_, hh, quantity in list_: 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] old = [i for i in info if i["id"] == id_ and i["isHappyHour"] == hh]
if len(old): if len(old):
old[0][type_] = quantity old[0][type_] = quantity
@ -69,8 +81,3 @@ def product_sale_report(start_date, finish_date, dbsession):
return info 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:])

View File

@ -1,50 +1,59 @@
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 import func
from sqlalchemy.orm import Session
from barker.models import ( from barker.core.config import settings
Inventory, from .tax_report import get_tax
Kot, from ...models import Voucher, VoucherType, Settlement, SettleOption, Product, Inventory, Kot, SaleCategory
Product, from ...schemas.auth import UserToken
Settlement, from ...core.security import get_current_active_user as get_user
SettleOption, from ...db.session import SessionLocal
Tax,
Voucher, router = APIRouter()
SaleCategory,
VoucherType,
)
from barker.models.validation_exception import ValidationError
from barker.views.reports import get_start_date, get_finish_date
@view_config( # Dependency
request_method="GET", route_name="v1_sale_report", renderer="json", permission="Sale Report", def get_db() -> Session:
) try:
def get_sale_analysis(request): db = SessionLocal()
start_date = get_start_date(request.GET.get("s", None)) yield db
finish_date = get_finish_date(request.GET.get("f", None)) finally:
db.close()
if (
datetime.today() - start_date.replace(hour=0) @router.get("")
).days > 5 and "Accounts Audit" not in request.effective_principals: def get_sale_analysis(
raise ValidationError("Accounts Audit") 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 { return {
"startDate": start_date.date().strftime("%d-%b-%Y"), "startDate": start_date.strftime("%d-%b-%Y"),
"finishDate": (finish_date - timedelta(days=1)).date().strftime("%d-%b-%Y"), "finishDate": finish_date.strftime("%d-%b-%Y"),
"amounts": ( "amounts": (
get_sale(start_date, finish_date, request.dbsession) get_sale(start_date, finish_date, db)
+ [{"name": "--", "amount": 0}] + [{"name": "--", "amount": 0}]
+ get_settlements(start_date, finish_date, request.dbsession) + get_settlements(start_date, finish_date, db)
+ [{"name": "--", "amount": 0}] + [{"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_ = ( list_ = (
dbsession.query(SaleCategory.name, func.sum(Inventory.net)) db.query(SaleCategory.name, func.sum(Inventory.net))
.join(Inventory.kot) .join(Inventory.kot)
.join(Kot.voucher) .join(Kot.voucher)
.join(Inventory.product) .join(Inventory.product)
@ -66,9 +75,12 @@ def get_sale(start_date, finish_date, dbsession):
return info + [{"name": "Total Settled", "amount": total}] 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_ = ( list_ = (
dbsession.query(SettleOption.name, func.sum(Settlement.amount)) db.query(SettleOption.name, func.sum(Settlement.amount))
.join(Voucher.settlements) .join(Voucher.settlements)
.join(Settlement.settle_option) .join(Settlement.settle_option)
.filter(Voucher.date >= start_date, Voucher.date <= finish_date) .filter(Voucher.date >= start_date, Voucher.date <= finish_date)
@ -82,48 +94,3 @@ def get_settlements(start_date, finish_date, dbsession):
total += am total += am
info.append({"name": gt, "amount": am}) info.append({"name": gt, "amount": am})
return info + [{"name": "Total", "amount": total}] 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
]

View File

@ -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
]

View File

@ -25,7 +25,7 @@ def get_db():
@router.post("/", response_model=schemas.Tax) @router.post("/", response_model=schemas.Tax)
def save( 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: try:
item = Tax(name=data.name, rate=data.rate) item = Tax(name=data.name, rate=data.rate)
@ -47,7 +47,7 @@ def update(
id_: uuid.UUID, id_: uuid.UUID,
data: schemas.TaxIn, data: schemas.TaxIn,
db: Session = Depends(get_db), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["products"]), user: UserToken = Security(get_user, scopes=["taxes"]),
): ):
try: try:
item: Tax = db.query(Tax).filter(Tax.id == id_).first() item: Tax = db.query(Tax).filter(Tax.id == id_).first()
@ -71,7 +71,7 @@ def update(
@router.delete("/{id_}") @router.delete("/{id_}")
def delete( 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: try:
item: Tax = db.query(Tax).filter(Tax.id == id_).first() item: Tax = db.query(Tax).filter(Tax.id == id_).first()
@ -94,7 +94,7 @@ def delete(
@router.get("/") @router.get("/")
def show_blank( 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) return tax_info(None)
@ -109,7 +109,7 @@ def show_list(db: Session = Depends(get_db), user: UserToken = Depends(get_user)
@router.get("/{id_}") @router.get("/{id_}")
def show_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() item: Tax = db.query(Tax).filter(Tax.id == id_).first()
return tax_info(item) return tax_info(item)

View File

@ -1,3 +1,3 @@
def to_camel(string: str) -> str: def to_camel(string: str) -> str:
first, *others = string.split("_") first, *others = string.split("_")
return "".join([first] + [word.capitalize() for word in others]) return "".join([first.lower()] + [word.capitalize() for word in others])

View File

@ -9,7 +9,7 @@ const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'}) headers: new HttpHeaders({'Content-Type': 'application/json'})
}; };
const url = '/v1/beer-consumption-report'; const url = '/api/beer-consumption-report';
const serviceName = 'BeerConsumptionReportService'; const serviceName = 'BeerConsumptionReportService';
@Injectable({ @Injectable({

View File

@ -9,7 +9,7 @@ const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'}) headers: new HttpHeaders({'Content-Type': 'application/json'})
}; };
const url = '/v1/bill-settlement-report'; const url = '/api/bill-settlement-report';
const serviceName = 'BillSettlementReportService'; const serviceName = 'BillSettlementReportService';
@Injectable({ @Injectable({

View File

@ -10,8 +10,7 @@ const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'}) headers: new HttpHeaders({'Content-Type': 'application/json'})
}; };
const url = '/v1/cashier-report'; const url = '/api/cashier-report';
const urlActiveCashiers = '/v1/active-cashiers';
const serviceName = 'CashierReportService'; const serviceName = 'CashierReportService';
@Injectable({ @Injectable({
@ -45,7 +44,7 @@ export class CashierReportService {
if (finishDate !== null) { if (finishDate !== null) {
options.params = options.params.set('f', finishDate); options.params = options.params.set('f', finishDate);
} }
return <Observable<User[]>>this.http.get<User[]>(urlActiveCashiers, options) return <Observable<User[]>>this.http.get<User[]>(`${url}/active`, options)
.pipe( .pipe(
catchError(this.log.handleError(serviceName, 'activeCashiers')) catchError(this.log.handleError(serviceName, 'activeCashiers'))

View File

@ -9,7 +9,7 @@ const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'}) headers: new HttpHeaders({'Content-Type': 'application/json'})
}; };
const url = '/v1/discount-report'; const url = '/api/discount-report';
const serviceName = 'DiscountReportService'; const serviceName = 'DiscountReportService';
@Injectable({ @Injectable({

View File

@ -9,7 +9,7 @@ const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'}) headers: new HttpHeaders({'Content-Type': 'application/json'})
}; };
const url = '/v1/product-sale-report'; const url = '/api/product-sale-report';
const serviceName = 'ProductSaleReportService'; const serviceName = 'ProductSaleReportService';
@Injectable({ @Injectable({

View File

@ -9,7 +9,7 @@ const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'}) headers: new HttpHeaders({'Content-Type': 'application/json'})
}; };
const url = '/v1/sale-report'; const url = '/api/sale-report';
const serviceName = 'SaleReportService'; const serviceName = 'SaleReportService';
@Injectable({ @Injectable({

View File

@ -9,7 +9,7 @@ const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'}) headers: new HttpHeaders({'Content-Type': 'application/json'})
}; };
const url = '/v1/tax-report'; const url = '/api/tax-report';
const serviceName = 'TaxReportService'; const serviceName = 'TaxReportService';
@Injectable({ @Injectable({