Feature: Product Sale Report printing.
This commit is contained in:
parent
a1a1c10dff
commit
7247ac34f4
53
barker/barker/printing/product_sale_report.py
Normal file
53
barker/barker/printing/product_sale_report.py
Normal file
@ -0,0 +1,53 @@
|
||||
import asyncio
|
||||
import locale
|
||||
import uuid
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from arq import ArqRedis, create_pool
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..core.arq import settings as redis_settings
|
||||
from ..core.config import settings
|
||||
from ..models.device import Device
|
||||
from ..models.printer import Printer
|
||||
from ..models.section_printer import SectionPrinter
|
||||
|
||||
|
||||
def print_product_sale_report(report, device_id: uuid.UUID, db: Session):
|
||||
locale.setlocale(locale.LC_MONETARY, "en_IN")
|
||||
data = design_product_sale_report(report)
|
||||
section_id = db.execute(select(Device.section_id).where(Device.id == device_id)).scalar_one()
|
||||
printer = db.execute(
|
||||
select(Printer)
|
||||
.join(SectionPrinter.printer)
|
||||
.where(SectionPrinter.section_id == section_id)
|
||||
.where(SectionPrinter.menu_category_id == None) # noqa: E711
|
||||
).scalar_one()
|
||||
|
||||
redis: ArqRedis = asyncio.run(create_pool(redis_settings))
|
||||
asyncio.run(
|
||||
redis.enqueue_job(
|
||||
"sent_to_printer", data, printer.address, printer.cut_code, _queue_name=f"barker:print:{printer.name}"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def design_product_sale_report(report):
|
||||
now = datetime.now() + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES)
|
||||
s = f"{report['userName']} @ {now:%d-%b-%Y %H:%M}".center(42)
|
||||
s += "\n\r" + "-" * 42
|
||||
s += "\n\r" f"{report['startDate']} To {report['finishDate']}".center(42)
|
||||
s += "\n\r" + "-" * 42
|
||||
s += "\n\rUnbilled Sale NC Staff Void"
|
||||
for item in report["amounts"]:
|
||||
s += f"\n\r{item['name']: ^42.42}" f"\n\r" + (f"{item['kot']: >7.2f} " if "kot" in item else " ") + (
|
||||
f"{item['regularBill']: >7.2f} " if "regularBill" in item else " "
|
||||
) + (f"{item['noCharge']: >7.2f} " if "noCharge" in item else " ") + (
|
||||
f"{item['staff']: >7.2f} " if "staff" in item else " "
|
||||
) + (
|
||||
f"{item['void']: >7.2f}" if "void" in item else " "
|
||||
)
|
||||
s += "\n\r" + "=" * 42
|
||||
return s
|
@ -43,6 +43,6 @@ def design_sale_report(report: SaleReport):
|
||||
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} {currency_format(item.amount): >12}"
|
||||
s += f"\n\r{item.name: <29.29} {currency_format(item.amount): >12}"
|
||||
s += "\n\r" + "=" * 42
|
||||
return s
|
||||
|
@ -1,6 +1,8 @@
|
||||
import uuid
|
||||
|
||||
from datetime import date, datetime, time, timedelta
|
||||
|
||||
from fastapi import APIRouter, Depends, Security
|
||||
from fastapi import APIRouter, Cookie, Depends, Security
|
||||
from sqlalchemy import func, or_, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@ -14,6 +16,7 @@ from ...models.product_version import ProductVersion
|
||||
from ...models.sale_category import SaleCategory
|
||||
from ...models.voucher import Voucher
|
||||
from ...models.voucher_type import VoucherType
|
||||
from ...printing.product_sale_report import print_product_sale_report
|
||||
from ...schemas import to_camel
|
||||
from ...schemas.user_token import UserToken
|
||||
from . import check_audit_permission, report_finish_date, report_start_date
|
||||
@ -97,3 +100,22 @@ def product_sale_report(s: date, f: date, db: Session):
|
||||
}
|
||||
)
|
||||
return info
|
||||
|
||||
|
||||
@router.get("/print", response_model=bool)
|
||||
def print_report(
|
||||
start_date: date = Depends(report_start_date),
|
||||
finish_date: date = Depends(report_finish_date),
|
||||
device_id: uuid.UUID = Cookie(None),
|
||||
user: UserToken = Security(get_user, scopes=["product-sale-report"]),
|
||||
) -> bool:
|
||||
check_audit_permission(start_date, user.permissions)
|
||||
with SessionFuture() as db:
|
||||
report = {
|
||||
"userName": user.name,
|
||||
"startDate": start_date.strftime("%d-%b-%Y"),
|
||||
"finishDate": finish_date.strftime("%d-%b-%Y"),
|
||||
"amounts": product_sale_report(start_date, finish_date, db),
|
||||
}
|
||||
print_product_sale_report(report, device_id, db)
|
||||
return True
|
||||
|
@ -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>Product 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 { ProductSaleReport } from './product-sale-report';
|
||||
import { ProductSaleReportDataSource } from './product-sale-report-datasource';
|
||||
import { ProductSaleReportService } from './product-sale-report.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-product-sale-report',
|
||||
@ -26,6 +28,8 @@ export class ProductSaleReportComponent implements OnInit {
|
||||
private router: Router,
|
||||
private fb: FormBuilder,
|
||||
private toCsv: ToCsvService,
|
||||
private toaster: ToasterService,
|
||||
private ser: ProductSaleReportService,
|
||||
) {
|
||||
// Create form
|
||||
this.form = this.fb.group({
|
||||
@ -65,6 +69,17 @@ export class ProductSaleReportComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
print() {
|
||||
this.ser.print(this.info.startDate, this.info.finishDate).subscribe(
|
||||
() => {
|
||||
this.toaster.show('', 'Successfully Printed');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Error', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
exportCsv() {
|
||||
const headers = {
|
||||
Name: 'name',
|
||||
|
@ -28,4 +28,18 @@ export class ProductSaleReportService {
|
||||
.get<ProductSaleReport>(url, options)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'get'))) as Observable<ProductSaleReport>;
|
||||
}
|
||||
|
||||
print(startDate: string | null, finishDate: string | null): 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 this.http
|
||||
.get<boolean>(printUrl, options)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'print'))) as Observable<boolean>;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user