Bump to version 3.0.0
Printing done on: Cashier Report Discount Report Sale Report
This commit is contained in:
@ -1 +1 @@
|
||||
__version__ = "2.0.0"
|
||||
__version__ = "3.0.0"
|
||||
|
||||
@ -252,7 +252,7 @@ class Settlement(Base):
|
||||
nullable=False,
|
||||
index=True,
|
||||
)
|
||||
settled = Column("settled", ForeignKey("settle_options.id"), nullable=False)
|
||||
settled = Column("settled", Integer, ForeignKey("settle_options.id"), nullable=False)
|
||||
amount = Column("amount", Numeric, nullable=False)
|
||||
|
||||
settle_option = relationship("SettleOption")
|
||||
|
||||
42
barker/barker/printing/cashier_report.py
Normal file
42
barker/barker/printing/cashier_report.py
Normal file
@ -0,0 +1,42 @@
|
||||
import asyncio
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from arq import ArqRedis, create_pool
|
||||
from barker.schemas.cashier_report import CashierReport
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..core.arq import settings as redis_settings
|
||||
from ..models import Printer, SectionPrinter
|
||||
|
||||
|
||||
def print_cashier_report(report: CashierReport, db: Session):
|
||||
data = design_cashier_report(report)
|
||||
printer = (
|
||||
db.query(Printer)
|
||||
.join(SectionPrinter.printer)
|
||||
# .filter(SectionPrinter.section_id == voucher.food_table.section_id) TODO: Use device's section_id
|
||||
.filter(SectionPrinter.menu_category_id == None) # noqa: E711
|
||||
.first()
|
||||
)
|
||||
|
||||
redis: ArqRedis = asyncio.run(create_pool(redis_settings))
|
||||
asyncio.run(redis.enqueue_job("sent_to_printer", data, printer.address, printer.cut_code))
|
||||
|
||||
|
||||
def design_cashier_report(report: CashierReport):
|
||||
s = f"{report.cashier.name} Checkout By {report.user.name} @ {datetime.now():%d-%b-%Y %H:%M}".center(42)
|
||||
s += "\n\r" + "-" * 42
|
||||
s += "\n\r" f"{report.start_date:%d-%b-%Y} To {report.finish_date:%d-%b-%Y}".center(42)
|
||||
s += "\n\r" + "-" * 42
|
||||
for item in report.amounts:
|
||||
s += f"\n\r{item.name} : {item.amount: >26.2f}"
|
||||
s += "\n\r" + "=" * 42
|
||||
s += f"\n\rActive Cashiers : {report.cashiers}"
|
||||
for so, it in report.info.items():
|
||||
s += f"\n\r" f"--- {so} ".ljust(42, "-")
|
||||
for i in it:
|
||||
s += f"\n\r{i.date} {i.bill_id} {i.customer}"
|
||||
s += f"\n\rAmount: {i.amount:9.2f}"
|
||||
s += "\n\r" + "-" * 42
|
||||
return s
|
||||
32
barker/barker/printing/discount_report.py
Normal file
32
barker/barker/printing/discount_report.py
Normal file
@ -0,0 +1,32 @@
|
||||
import asyncio
|
||||
|
||||
from arq import ArqRedis, create_pool
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..core.arq import settings as redis_settings
|
||||
from ..models import Printer, SectionPrinter
|
||||
from ..schemas.discount_report import DiscountReport
|
||||
|
||||
|
||||
def print_discount_report(report: DiscountReport, db: Session):
|
||||
data = design_discount_report(report)
|
||||
printer = (
|
||||
db.query(Printer)
|
||||
.join(SectionPrinter.printer)
|
||||
# .filter(SectionPrinter.section_id == voucher.food_table.section_id) TODO: Use device's section_id
|
||||
.filter(SectionPrinter.menu_category_id == None) # noqa: E711
|
||||
.first()
|
||||
)
|
||||
|
||||
redis: ArqRedis = asyncio.run(create_pool(redis_settings))
|
||||
asyncio.run(redis.enqueue_job("sent_to_printer", data, printer.address, printer.cut_code))
|
||||
|
||||
|
||||
def design_discount_report(report: DiscountReport):
|
||||
s = f"{report.start_date:%d-%b-%Y} To {report.finish_date:%d-%b-%Y}".center(42)
|
||||
s += "\n\r" + "-" * 42
|
||||
s += f"\n\r{'Name': <29.29} {'Amount': >12.12}"
|
||||
for item in report.amounts:
|
||||
s += f"\n\r{item.name: <29.29} {item.amount: >12.2f}"
|
||||
s += "\n\r" + "=" * 42
|
||||
return s
|
||||
35
barker/barker/printing/sale_report.py
Normal file
35
barker/barker/printing/sale_report.py
Normal file
@ -0,0 +1,35 @@
|
||||
import asyncio
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from arq import ArqRedis, create_pool
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..core.arq import settings as redis_settings
|
||||
from ..models import Printer, SectionPrinter
|
||||
from ..schemas.sale_report import SaleReport
|
||||
|
||||
|
||||
def print_sale_report(report: SaleReport, db: Session):
|
||||
data = design_sale_report(report)
|
||||
printer = (
|
||||
db.query(Printer)
|
||||
.join(SectionPrinter.printer)
|
||||
# .filter(SectionPrinter.section_id == voucher.food_table.section_id) TODO: Use device's section_id
|
||||
.filter(SectionPrinter.menu_category_id == None) # noqa: E711
|
||||
.first()
|
||||
)
|
||||
|
||||
redis: ArqRedis = asyncio.run(create_pool(redis_settings))
|
||||
asyncio.run(redis.enqueue_job("sent_to_printer", data, printer.address, printer.cut_code))
|
||||
|
||||
|
||||
def design_sale_report(report: SaleReport):
|
||||
s = f"{report.user.name} @ {datetime.now():%d-%b-%Y %H:%M}".center(42)
|
||||
s += "\n\r" + "-" * 42
|
||||
s += "\n\r" f"{report.start_date:%d-%b-%Y} To {report.finish_date:%d-%b-%Y}".center(42)
|
||||
s += "\n\r" + "-" * 42
|
||||
for item in report.amounts:
|
||||
s += f"\n\r{item.name: <29.22} {item.amount: >12.2f}"
|
||||
s += "\n\r" + "=" * 42
|
||||
return s
|
||||
@ -1,4 +1,5 @@
|
||||
from datetime import date, datetime, timedelta
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Security, status
|
||||
from sqlalchemy.orm import Session
|
||||
@ -8,6 +9,7 @@ from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from ...models import Reprint, Settlement, SettleOption, Voucher, VoucherType
|
||||
from ...schemas.auth import UserToken
|
||||
from ...schemas.bill_settlement_report import BillSettlement, BillSettlementItem
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
@ -22,13 +24,13 @@ def get_db() -> Session:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("")
|
||||
@router.get("", response_model=BillSettlement)
|
||||
def bill_details(
|
||||
s: str = None,
|
||||
f: str = None,
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["bill-settlement-report"]),
|
||||
):
|
||||
) -> BillSettlement:
|
||||
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:
|
||||
@ -37,14 +39,14 @@ def bill_details(
|
||||
detail="Accounts Audit",
|
||||
)
|
||||
|
||||
return {
|
||||
"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),
|
||||
}
|
||||
return BillSettlement(
|
||||
startDate=start_date,
|
||||
finishDate=finish_date,
|
||||
amounts=settlements(start_date, finish_date, db) + reprints(start_date, finish_date, db),
|
||||
)
|
||||
|
||||
|
||||
def settlements(s: date, f: date, db: Session):
|
||||
def settlements(s: date, f: date, db: Session) -> List[BillSettlementItem]:
|
||||
start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
vouchers = (
|
||||
@ -69,28 +71,30 @@ def settlements(s: date, f: date, db: Session):
|
||||
else:
|
||||
details = so.settle_option.name
|
||||
report.append(
|
||||
{
|
||||
"date": item.date.strftime("%d-%b-%Y %H:%M:%S"),
|
||||
"billId": item.full_bill_id,
|
||||
"settlement": details,
|
||||
"amount": round(so.amount, 2),
|
||||
}
|
||||
BillSettlementItem(
|
||||
date=item.date,
|
||||
billId=item.full_bill_id,
|
||||
settlement=details,
|
||||
amount=round(so.amount, 2),
|
||||
)
|
||||
)
|
||||
for i in report:
|
||||
print(i.json())
|
||||
return report
|
||||
|
||||
|
||||
def reprints(s: date, f: date, db: Session):
|
||||
def reprints(s: date, f: date, db: Session) -> List[BillSettlementItem]:
|
||||
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"),
|
||||
"billId": item.voucher.full_bill_id,
|
||||
"settlement": f"Reprinted by {item.user.name}",
|
||||
"Amount": round(
|
||||
BillSettlementItem(
|
||||
date=item.date,
|
||||
billId=item.voucher.full_bill_id,
|
||||
settlement=f"Reprinted by {item.user.name}",
|
||||
amount=round(
|
||||
next(s.amount for s in item.voucher.settlements if s.settled == SettleOption.AMOUNT()) * -1,
|
||||
2,
|
||||
),
|
||||
}
|
||||
)
|
||||
for item in db.query(Reprint).filter(Reprint.date >= start_date, Reprint.date <= finish_date).all()
|
||||
]
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import uuid
|
||||
|
||||
from datetime import date, datetime, timedelta
|
||||
from typing import Dict, List
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Security, status
|
||||
from sqlalchemy import distinct
|
||||
@ -10,7 +11,14 @@ from ...core.config import settings
|
||||
from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from ...models import Settlement, User, Voucher
|
||||
from ...schemas.auth import UserToken
|
||||
from ...printing.cashier_report import print_cashier_report
|
||||
from ...schemas.auth import UserLink, UserToken
|
||||
from ...schemas.cashier_report import (
|
||||
CashierReport,
|
||||
InfoItem,
|
||||
NameAmount,
|
||||
SettleOptionSchema,
|
||||
)
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
@ -39,7 +47,10 @@ def active_cashiers(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Accounts Audit",
|
||||
)
|
||||
return get_active_cashiers(start_date, finish_date, db)
|
||||
|
||||
|
||||
def get_active_cashiers(start_date: date, finish_date: date, db: Session) -> List[UserLink]:
|
||||
users = (
|
||||
db.query(User)
|
||||
.filter(
|
||||
@ -53,18 +64,17 @@ def active_cashiers(
|
||||
.order_by(User.name)
|
||||
.all()
|
||||
)
|
||||
|
||||
return [{"id": u.id, "name": u.name} for u in users]
|
||||
return [UserLink(id=u.id, name=u.name) for u in users]
|
||||
|
||||
|
||||
@router.get("/{id_}")
|
||||
@router.get("/{id_}", response_model=CashierReport)
|
||||
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"]),
|
||||
):
|
||||
) -> CashierReport:
|
||||
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:
|
||||
@ -72,7 +82,12 @@ def show_id(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Accounts Audit",
|
||||
)
|
||||
user = UserLink(id=user.id_, name=user.name)
|
||||
return get_id(id_, start_date, finish_date, user, db)
|
||||
|
||||
|
||||
def get_id(id_: uuid.UUID, start_date: date, finish_date: date, user: UserLink, db: Session) -> CashierReport:
|
||||
cashier: str = db.query(User.name).filter(User.id == id_).scalar()
|
||||
vouchers = (
|
||||
db.query(Voucher)
|
||||
.options(joinedload(Voucher.settlements, innerjoin=True).joinedload(Settlement.settle_option, innerjoin=True))
|
||||
@ -86,38 +101,61 @@ def show_id(
|
||||
.all()
|
||||
)
|
||||
|
||||
info = {}
|
||||
info: Dict[SettleOptionSchema, List[InfoItem]] = {}
|
||||
amounts = {}
|
||||
for item in vouchers:
|
||||
for so in (so for so in item.settlements if so.settle_option.show_in_choices):
|
||||
if so.settled not in info:
|
||||
info[so.settled] = []
|
||||
for so in (so for so in item.settlements if so.settle_option.show_in_choices or so.settle_option.is_print):
|
||||
if so.settle_option.name not in info:
|
||||
info[so.settle_option.name] = []
|
||||
amounts[so.settle_option.name] = 0
|
||||
info[so.settled].append(
|
||||
{
|
||||
"date": item.date.strftime("%d-%b-%Y %H:%M:%S"),
|
||||
"billId": item.full_bill_id,
|
||||
"customer": item.customer.name if item.customer is not None else "",
|
||||
"amount": so.amount,
|
||||
}
|
||||
)
|
||||
amounts[so.settle_option.name] += so.amount
|
||||
return {
|
||||
"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,
|
||||
}
|
||||
if so.settle_option.is_print:
|
||||
info[so.settle_option.name].append(
|
||||
InfoItem(
|
||||
date=item.date,
|
||||
billId=item.full_bill_id,
|
||||
customer=item.customer.name if item.customer is not None else "",
|
||||
amount=so.amount,
|
||||
)
|
||||
)
|
||||
return CashierReport(
|
||||
startDate=start_date,
|
||||
finishDate=finish_date,
|
||||
cashier=UserLink(id=id_, name=cashier),
|
||||
cashiers=", ".join(x.name for x in get_active_cashiers(start_date, finish_date, db)),
|
||||
amounts=[NameAmount(name=key, amount=value) for key, value in amounts.items()],
|
||||
info=info,
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@router.get("")
|
||||
@router.get("/print/{id_}", response_model=bool)
|
||||
def print_report(
|
||||
id_: uuid.UUID,
|
||||
s: str = None,
|
||||
f: str = None,
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["cashier-report"]),
|
||||
) -> bool:
|
||||
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 HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Accounts Audit",
|
||||
)
|
||||
report = get_id(id_, start_date, finish_date, user, db)
|
||||
print_cashier_report(report, db)
|
||||
return True
|
||||
|
||||
|
||||
@router.get("", response_model=CashierReport)
|
||||
def show_blank(
|
||||
s: str = None,
|
||||
f: str = None,
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["cashier-report"]),
|
||||
):
|
||||
) -> CashierReport:
|
||||
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:
|
||||
@ -126,10 +164,12 @@ def show_blank(
|
||||
detail="Accounts Audit",
|
||||
)
|
||||
|
||||
return {
|
||||
"startDate": start_date.strftime("%d-%b-%Y"),
|
||||
"finishDate": finish_date.strftime("%d-%b-%Y"),
|
||||
"user": {"id": ""},
|
||||
"amounts": [],
|
||||
"info": [],
|
||||
}
|
||||
return CashierReport(
|
||||
startDate=start_date,
|
||||
finishDate=finish_date,
|
||||
cashier=UserLink(id=None),
|
||||
cashiers="",
|
||||
amounts=[],
|
||||
info=[],
|
||||
user=UserLink(id=user.id_),
|
||||
)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
from datetime import date, datetime, timedelta
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Security, status
|
||||
from sqlalchemy import func
|
||||
@ -8,7 +9,9 @@ from ...core.config import settings
|
||||
from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from ...models import Inventory, Kot, Product, SaleCategory, Voucher, VoucherType
|
||||
from ...printing.discount_report import print_discount_report
|
||||
from ...schemas.auth import UserToken
|
||||
from ...schemas.discount_report import DiscountReport, DiscountReportItem
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
@ -23,13 +26,13 @@ def get_db() -> Session:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("")
|
||||
def discount_report_view(
|
||||
@router.get("", response_model=DiscountReport)
|
||||
def discount_report(
|
||||
s: str = None,
|
||||
f: str = None,
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["discount-report"]),
|
||||
):
|
||||
) -> DiscountReport:
|
||||
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:
|
||||
@ -37,15 +40,14 @@ def discount_report_view(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Accounts Audit",
|
||||
)
|
||||
|
||||
return {
|
||||
"startDate": start_date.strftime("%d-%b-%Y"),
|
||||
"finishDate": finish_date.strftime("%d-%b-%Y"),
|
||||
"amounts": discount_report(start_date, finish_date, db),
|
||||
}
|
||||
return DiscountReport(
|
||||
startDate=start_date,
|
||||
finishDate=finish_date,
|
||||
amounts=get_discount_report(start_date, finish_date, db),
|
||||
)
|
||||
|
||||
|
||||
def discount_report(s: date, f: date, db: Session):
|
||||
def get_discount_report(s: date, f: date, db: Session) -> List[DiscountReportItem]:
|
||||
start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
|
||||
@ -67,4 +69,27 @@ def discount_report(s: date, f: date, db: Session):
|
||||
.all()
|
||||
)
|
||||
|
||||
return [{"name": pg, "amount": amt} for pg, amt in list_]
|
||||
return [DiscountReportItem(name=pg, amount=amt) for pg, amt in list_]
|
||||
|
||||
|
||||
@router.get("/print", response_model=bool)
|
||||
def print_report(
|
||||
s: str = None,
|
||||
f: str = None,
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["discount-report"]),
|
||||
) -> bool:
|
||||
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 HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Accounts Audit",
|
||||
)
|
||||
report = DiscountReport(
|
||||
startDate=start_date,
|
||||
finishDate=finish_date,
|
||||
amounts=get_discount_report(start_date, finish_date, db),
|
||||
)
|
||||
print_discount_report(report, db)
|
||||
return True
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
from datetime import date, datetime, timedelta
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Security, status
|
||||
from sqlalchemy import func
|
||||
@ -17,7 +18,9 @@ from ...models import (
|
||||
Voucher,
|
||||
VoucherType,
|
||||
)
|
||||
from ...schemas.auth import UserToken
|
||||
from ...printing.sale_report import print_sale_report
|
||||
from ...schemas.auth import UserLink, UserToken
|
||||
from ...schemas.sale_report import SaleReport, SaleReportItem
|
||||
from .tax_report import get_tax
|
||||
|
||||
|
||||
@ -33,13 +36,13 @@ def get_db() -> Session:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("")
|
||||
@router.get("", response_model=SaleReport)
|
||||
def get_sale_analysis(
|
||||
s: str = None,
|
||||
f: str = None,
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["sale-report"]),
|
||||
):
|
||||
) -> SaleReport:
|
||||
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:
|
||||
@ -48,20 +51,21 @@ def get_sale_analysis(
|
||||
detail="Accounts Audit",
|
||||
)
|
||||
|
||||
return {
|
||||
"startDate": start_date.strftime("%d-%b-%Y"),
|
||||
"finishDate": finish_date.strftime("%d-%b-%Y"),
|
||||
"amounts": (
|
||||
return SaleReport(
|
||||
startDate=start_date,
|
||||
finishDate=finish_date,
|
||||
amounts=(
|
||||
get_sale(start_date, finish_date, db)
|
||||
+ [{"name": "--", "amount": 0}]
|
||||
+ [SaleReportItem(name="--", amount=0)]
|
||||
+ get_settlements(start_date, finish_date, db)
|
||||
+ [{"name": "--", "amount": 0}]
|
||||
+ get_tax(start_date, finish_date, db)
|
||||
+ [SaleReportItem(name="--", amount=0)]
|
||||
+ [SaleReportItem(name=i.name, amount=i.amount) for i in get_tax(start_date, finish_date, db)]
|
||||
),
|
||||
}
|
||||
user=UserLink(id=user.id_, name=user.name),
|
||||
)
|
||||
|
||||
|
||||
def get_sale(s: date, f: date, db: Session):
|
||||
def get_sale(s: date, f: date, db: Session) -> List[SaleReportItem]:
|
||||
start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
|
||||
@ -84,11 +88,11 @@ def get_sale(s: date, f: date, db: Session):
|
||||
info = []
|
||||
for gt, am in list_:
|
||||
total += am
|
||||
info.append({"name": gt, "amount": am})
|
||||
return info + [{"name": "Total Settled", "amount": total}]
|
||||
info.append(SaleReportItem(name=gt, amount=am))
|
||||
return info + [SaleReportItem(name="Total Settled", amount=total)]
|
||||
|
||||
|
||||
def get_settlements(s: date, f: date, db: Session):
|
||||
def get_settlements(s: date, f: date, db: Session) -> List[SaleReportItem]:
|
||||
start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
|
||||
@ -105,5 +109,35 @@ def get_settlements(s: date, f: date, db: Session):
|
||||
info = []
|
||||
for gt, am in list_:
|
||||
total += am
|
||||
info.append({"name": gt, "amount": am})
|
||||
return info + [{"name": "Total", "amount": total}]
|
||||
info.append(SaleReportItem(name=gt, amount=am))
|
||||
return info + [SaleReportItem(name="Total", amount=total)]
|
||||
|
||||
|
||||
@router.get("/print", response_model=bool)
|
||||
def print_report(
|
||||
s: str = None,
|
||||
f: str = None,
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["discount-report"]),
|
||||
) -> bool:
|
||||
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 HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Accounts Audit",
|
||||
)
|
||||
report = SaleReport(
|
||||
startDate=start_date,
|
||||
finishDate=finish_date,
|
||||
amounts=(
|
||||
get_sale(start_date, finish_date, db)
|
||||
+ [SaleReportItem(name="--", amount=0)]
|
||||
+ get_settlements(start_date, finish_date, db)
|
||||
+ [SaleReportItem(name="--", amount=0)]
|
||||
+ [SaleReportItem(name=i.name, amount=i.amount) for i in get_tax(start_date, finish_date, db)]
|
||||
),
|
||||
user=UserLink(id=user.id_, name=user.name),
|
||||
)
|
||||
print_sale_report(report, db)
|
||||
return True
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
from datetime import date, datetime, timedelta
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Security, status
|
||||
from sqlalchemy import func
|
||||
@ -9,6 +10,7 @@ from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from ...models import Inventory, Kot, Tax, Voucher, VoucherType
|
||||
from ...schemas.auth import UserToken
|
||||
from ...schemas.tax_report import TaxReport, TaxReportItem
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
@ -23,13 +25,13 @@ def get_db() -> Session:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("")
|
||||
@router.get("", response_model=TaxReport)
|
||||
def get_tax_report(
|
||||
s: str = None,
|
||||
f: str = None,
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["tax-report"]),
|
||||
):
|
||||
) -> TaxReport:
|
||||
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:
|
||||
@ -38,14 +40,14 @@ def get_tax_report(
|
||||
detail="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),
|
||||
}
|
||||
return TaxReport(
|
||||
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):
|
||||
def get_tax(s: date, f: date, db: Session) -> List[TaxReportItem]:
|
||||
start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES)
|
||||
|
||||
@ -68,12 +70,4 @@ def get_tax(s: date, f: date, db: Session):
|
||||
.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
|
||||
]
|
||||
return [TaxReportItem(name=f"{i[0]} - {i[1]:.2%}", taxRate=i[1], saleAmount=i[2], amount=i[3]) for i in amounts]
|
||||
|
||||
@ -89,6 +89,14 @@ class User(UserIn):
|
||||
id_: uuid.UUID
|
||||
|
||||
|
||||
class UserLink(BaseModel):
|
||||
id_: Optional[uuid.UUID]
|
||||
name: Optional[str]
|
||||
|
||||
class Config:
|
||||
alias_generator = to_camel
|
||||
|
||||
|
||||
class UserList(BaseModel):
|
||||
id_: uuid.UUID
|
||||
name: str
|
||||
|
||||
50
barker/barker/schemas/bill_settlement_report.py
Normal file
50
barker/barker/schemas/bill_settlement_report.py
Normal file
@ -0,0 +1,50 @@
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
from . import to_camel
|
||||
|
||||
|
||||
class BillSettlementItem(BaseModel):
|
||||
date: datetime
|
||||
bill_id: str
|
||||
settlement: str
|
||||
amount: Decimal
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"),
|
||||
}
|
||||
|
||||
@validator("date", pre=True)
|
||||
def parse_date(cls, value):
|
||||
if isinstance(value, datetime):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y %H:%M")
|
||||
|
||||
|
||||
class BillSettlement(BaseModel):
|
||||
start_date: date
|
||||
finish_date: date
|
||||
amounts: List[BillSettlementItem]
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), date: lambda v: v.strftime("%d-%b-%Y")}
|
||||
|
||||
@validator("start_date", pre=True)
|
||||
def parse_start_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
|
||||
@validator("finish_date", pre=True)
|
||||
def parse_finish_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
76
barker/barker/schemas/cashier_report.py
Normal file
76
barker/barker/schemas/cashier_report.py
Normal file
@ -0,0 +1,76 @@
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from typing import Dict, List
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
from . import to_camel
|
||||
from .auth import UserLink
|
||||
|
||||
|
||||
class NameAmount(BaseModel):
|
||||
name: str
|
||||
amount: Decimal
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
|
||||
|
||||
class SettleOptionSchema(BaseModel):
|
||||
def __hash__(self):
|
||||
return hash(self.id)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.id == other.id
|
||||
|
||||
id: int
|
||||
name: str
|
||||
|
||||
class Config:
|
||||
fields = {"id": "id"}
|
||||
anystr_strip_whitespace = True
|
||||
|
||||
|
||||
class InfoItem(BaseModel):
|
||||
date: datetime
|
||||
bill_id: str
|
||||
customer: str
|
||||
amount: Decimal
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
|
||||
@validator("date", pre=True)
|
||||
def parse_date(cls, value):
|
||||
if isinstance(value, datetime):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y %H:%M")
|
||||
|
||||
|
||||
class CashierReport(BaseModel):
|
||||
start_date: date
|
||||
finish_date: date
|
||||
cashier: UserLink
|
||||
cashiers: str
|
||||
user: UserLink
|
||||
amounts: List[NameAmount]
|
||||
info: Dict[str, List[InfoItem]]
|
||||
|
||||
class Config:
|
||||
fields = {"id_": "id"}
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), date: lambda v: v.strftime("%d-%b-%Y")}
|
||||
|
||||
@validator("start_date", pre=True)
|
||||
def parse_start_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
|
||||
@validator("finish_date", pre=True)
|
||||
def parse_finish_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
39
barker/barker/schemas/discount_report.py
Normal file
39
barker/barker/schemas/discount_report.py
Normal file
@ -0,0 +1,39 @@
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
from . import to_camel
|
||||
|
||||
|
||||
class DiscountReportItem(BaseModel):
|
||||
name: str
|
||||
amount: Decimal
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
|
||||
|
||||
class DiscountReport(BaseModel):
|
||||
start_date: date
|
||||
finish_date: date
|
||||
amounts: List[DiscountReportItem]
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), date: lambda v: v.strftime("%d-%b-%Y")}
|
||||
|
||||
@validator("start_date", pre=True)
|
||||
def parse_start_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
|
||||
@validator("finish_date", pre=True)
|
||||
def parse_finish_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
41
barker/barker/schemas/sale_report.py
Normal file
41
barker/barker/schemas/sale_report.py
Normal file
@ -0,0 +1,41 @@
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
from . import to_camel
|
||||
from .auth import UserLink
|
||||
|
||||
|
||||
class SaleReportItem(BaseModel):
|
||||
name: str
|
||||
amount: Decimal
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
|
||||
|
||||
class SaleReport(BaseModel):
|
||||
start_date: date
|
||||
finish_date: date
|
||||
amounts: List[SaleReportItem]
|
||||
user: UserLink
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), date: lambda v: v.strftime("%d-%b-%Y")}
|
||||
|
||||
@validator("start_date", pre=True)
|
||||
def parse_start_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
|
||||
@validator("finish_date", pre=True)
|
||||
def parse_finish_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
41
barker/barker/schemas/tax_report.py
Normal file
41
barker/barker/schemas/tax_report.py
Normal file
@ -0,0 +1,41 @@
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
from . import to_camel
|
||||
|
||||
|
||||
class TaxReportItem(BaseModel):
|
||||
name: str
|
||||
tax_rate: Decimal
|
||||
sale_amount: Decimal
|
||||
amount: Decimal
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
|
||||
|
||||
class TaxReport(BaseModel):
|
||||
start_date: date
|
||||
finish_date: date
|
||||
amounts: List[TaxReportItem]
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), date: lambda v: v.strftime("%d-%b-%Y")}
|
||||
|
||||
@validator("start_date", pre=True)
|
||||
def parse_start_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
|
||||
@validator("finish_date", pre=True)
|
||||
def parse_finish_date(cls, value):
|
||||
if isinstance(value, date):
|
||||
return value
|
||||
return datetime.strptime(value, "%d-%b-%Y").date()
|
||||
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "barker"
|
||||
version = "2.0.0"
|
||||
version = "3.0.0"
|
||||
description = "Point of Sale for a restaurant"
|
||||
authors = ["tanshu <git@tanshu.com>"]
|
||||
|
||||
|
||||
@ -2,3 +2,7 @@
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
<mat-card>
|
||||
<mat-card-title-group>
|
||||
<mat-card-title>Cashier Report</mat-card-title>
|
||||
<button mat-button mat-icon-button (click)="exportCsv()">
|
||||
<span class="spacer"></span>
|
||||
<button mat-button mat-icon-button [disabled]="!info.cashier.id" (click)="exportCsv()">
|
||||
<mat-icon>save_alt</mat-icon>
|
||||
</button>
|
||||
<button mat-button mat-icon-button [disabled]="!info.cashier.id" (click)="print()">
|
||||
<mat-icon>print</mat-icon>
|
||||
</button>
|
||||
</mat-card-title-group>
|
||||
<mat-card-content>
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
|
||||
@ -3,11 +3,13 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import * as moment from 'moment';
|
||||
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
import { User } from '../core/user';
|
||||
import { ToCsvService } from '../shared/to-csv.service';
|
||||
|
||||
import { CashierReport } from './cashier-report';
|
||||
import { CashierReportDataSource } from './cashier-report-datasource';
|
||||
import { CashierReportService } from './cashier-report.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-cashier-report',
|
||||
@ -28,6 +30,8 @@ export class CashierReportComponent implements OnInit {
|
||||
private router: Router,
|
||||
private fb: FormBuilder,
|
||||
private toCsv: ToCsvService,
|
||||
private toaster: ToasterService,
|
||||
private ser: CashierReportService,
|
||||
) {
|
||||
this.createForm();
|
||||
}
|
||||
@ -37,7 +41,7 @@ export class CashierReportComponent implements OnInit {
|
||||
this.activeCashiers = data.cashiers;
|
||||
this.info = data.info;
|
||||
this.form.setValue({
|
||||
cashier: this.info.user.id,
|
||||
cashier: this.info.cashier.id,
|
||||
startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(),
|
||||
finishDate: moment(this.info.finishDate, 'DD-MMM-YYYY').toDate(),
|
||||
});
|
||||
@ -48,8 +52,8 @@ export class CashierReportComponent implements OnInit {
|
||||
show() {
|
||||
const info = this.getInfo();
|
||||
const url = ['cashier-report'];
|
||||
if (info.user.id) {
|
||||
url.push(info.user.id);
|
||||
if (info.cashier.id) {
|
||||
url.push(info.cashier.id);
|
||||
}
|
||||
this.router.navigate(url, {
|
||||
queryParams: {
|
||||
@ -59,6 +63,17 @@ export class CashierReportComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
print() {
|
||||
this.ser.print(this.info.cashier.id, this.info.startDate, this.info.finishDate).subscribe(
|
||||
() => {
|
||||
this.toaster.show('', 'Successfully Printed');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Error', error.error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
createForm() {
|
||||
this.form = this.fb.group({
|
||||
startDate: '',
|
||||
@ -71,7 +86,8 @@ export class CashierReportComponent implements OnInit {
|
||||
const formModel = this.form.value;
|
||||
|
||||
return {
|
||||
user: new User({ id: formModel.cashier }),
|
||||
cashier: new User({ id: formModel.cashier }),
|
||||
cashiers: this.info.cashiers,
|
||||
startDate: moment(formModel.startDate).format('DD-MMM-YYYY'),
|
||||
finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'),
|
||||
};
|
||||
|
||||
@ -46,4 +46,20 @@ export class CashierReportService {
|
||||
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'activeCashiers')));
|
||||
}
|
||||
|
||||
print(id: string, startDate: string, finishDate): Observable<boolean> {
|
||||
const printUrl = `${url}/print/${id}`;
|
||||
const options = { params: new HttpParams() };
|
||||
if (startDate !== null) {
|
||||
options.params = options.params.set('s', startDate);
|
||||
}
|
||||
if (finishDate !== null) {
|
||||
options.params = options.params.set('f', finishDate);
|
||||
}
|
||||
return <Observable<boolean>>(
|
||||
this.http
|
||||
.get<boolean>(printUrl, options)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'print')))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,8 @@ import { CashierReportPrintItem } from './cashier-report-print-item';
|
||||
export class CashierReport {
|
||||
startDate: string;
|
||||
finishDate: string;
|
||||
user: User;
|
||||
cashier: User;
|
||||
cashiers: string;
|
||||
amounts?: CashierReportDisplayItem[];
|
||||
info?: CashierReportPrintItem[];
|
||||
}
|
||||
|
||||
@ -2,3 +2,7 @@
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
<mat-card>
|
||||
<mat-card-title-group>
|
||||
<mat-card-title>Discount Report</mat-card-title>
|
||||
<span class="spacer"></span>
|
||||
<button mat-button mat-icon-button (click)="exportCsv()">
|
||||
<mat-icon>save_alt</mat-icon>
|
||||
</button>
|
||||
<button mat-button mat-icon-button (click)="print()">
|
||||
<mat-icon>print</mat-icon>
|
||||
</button>
|
||||
</mat-card-title-group>
|
||||
<mat-card-content>
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
|
||||
@ -3,10 +3,12 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import * as moment from 'moment';
|
||||
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
import { ToCsvService } from '../shared/to-csv.service';
|
||||
|
||||
import { DiscountReport } from './discount-report';
|
||||
import { DiscountReportDataSource } from './discount-report-datasource';
|
||||
import { DiscountReportService } from './discount-report.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-discount-report',
|
||||
@ -26,6 +28,8 @@ export class DiscountReportComponent implements OnInit {
|
||||
private router: Router,
|
||||
private fb: FormBuilder,
|
||||
private toCsv: ToCsvService,
|
||||
private toaster: ToasterService,
|
||||
private ser: DiscountReportService,
|
||||
) {
|
||||
this.createForm();
|
||||
}
|
||||
@ -67,6 +71,17 @@ export class DiscountReportComponent implements OnInit {
|
||||
};
|
||||
}
|
||||
|
||||
print() {
|
||||
this.ser.print(this.info.startDate, this.info.finishDate).subscribe(
|
||||
() => {
|
||||
this.toaster.show('', 'Successfully Printed');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Error', error.error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
exportCsv() {
|
||||
const headers = {
|
||||
Name: 'name',
|
||||
|
||||
@ -30,4 +30,20 @@ export class DiscountReportService {
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'get')))
|
||||
);
|
||||
}
|
||||
|
||||
print(startDate: string, finishDate): Observable<boolean> {
|
||||
const printUrl = `${url}/print`;
|
||||
const options = { params: new HttpParams() };
|
||||
if (startDate !== null) {
|
||||
options.params = options.params.set('s', startDate);
|
||||
}
|
||||
if (finishDate !== null) {
|
||||
options.params = options.params.set('f', finishDate);
|
||||
}
|
||||
return <Observable<boolean>>(
|
||||
this.http
|
||||
.get<boolean>(printUrl, options)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'print')))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,3 +2,7 @@
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
<mat-card>
|
||||
<mat-card-title-group>
|
||||
<mat-card-title>Sale Report</mat-card-title>
|
||||
<span class="spacer"></span>
|
||||
<button mat-button mat-icon-button (click)="exportCsv()">
|
||||
<mat-icon>save_alt</mat-icon>
|
||||
</button>
|
||||
<button mat-button mat-icon-button (click)="print()">
|
||||
<mat-icon>print</mat-icon>
|
||||
</button>
|
||||
</mat-card-title-group>
|
||||
<mat-card-content>
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
|
||||
@ -3,10 +3,12 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import * as moment from 'moment';
|
||||
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
import { ToCsvService } from '../shared/to-csv.service';
|
||||
|
||||
import { SaleReport } from './sale-report';
|
||||
import { SaleReportDatasource } from './sale-report-datasource';
|
||||
import { SaleReportService } from './sale-report.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sale-report',
|
||||
@ -26,6 +28,8 @@ export class SaleReportComponent implements OnInit {
|
||||
private router: Router,
|
||||
private fb: FormBuilder,
|
||||
private toCsv: ToCsvService,
|
||||
private toaster: ToasterService,
|
||||
private ser: SaleReportService,
|
||||
) {
|
||||
this.createForm();
|
||||
}
|
||||
@ -67,6 +71,17 @@ export class SaleReportComponent implements OnInit {
|
||||
};
|
||||
}
|
||||
|
||||
print() {
|
||||
this.ser.print(this.info.startDate, this.info.finishDate).subscribe(
|
||||
() => {
|
||||
this.toaster.show('', 'Successfully Printed');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Error', error.error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
exportCsv() {
|
||||
const headers = {
|
||||
Name: 'name',
|
||||
|
||||
@ -30,4 +30,20 @@ export class SaleReportService {
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'get')))
|
||||
);
|
||||
}
|
||||
|
||||
print(startDate: string, finishDate): Observable<boolean> {
|
||||
const printUrl = `${url}/print`;
|
||||
const options = { params: new HttpParams() };
|
||||
if (startDate !== null) {
|
||||
options.params = options.params.set('s', startDate);
|
||||
}
|
||||
if (finishDate !== null) {
|
||||
options.params = options.params.set('f', finishDate);
|
||||
}
|
||||
return <Observable<boolean>>(
|
||||
this.http
|
||||
.get<boolean>(printUrl, options)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'print')))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export const environment = {
|
||||
production: true,
|
||||
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
|
||||
version: "2.0.0",
|
||||
version: '3.0.0',
|
||||
};
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
export const environment = {
|
||||
production: false,
|
||||
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
|
||||
version: "2.0.0",
|
||||
version: '3.0.0',
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user