Feature: Product Sale Report printing.

This commit is contained in:
Amritanshu Agrawal 2021-06-27 08:08:20 +05:30
parent a1a1c10dff
commit 7247ac34f4
7 changed files with 114 additions and 2 deletions

View 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

View File

@ -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" f"{report.start_date:%d-%b-%Y} To {report.finish_date:%d-%b-%Y}".center(42)
s += "\n\r" + "-" * 42 s += "\n\r" + "-" * 42
for item in report.amounts: 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 s += "\n\r" + "=" * 42
return s return s

View File

@ -1,6 +1,8 @@
import uuid
from datetime import date, datetime, time, timedelta 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 import func, or_, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@ -14,6 +16,7 @@ from ...models.product_version import ProductVersion
from ...models.sale_category import SaleCategory from ...models.sale_category import SaleCategory
from ...models.voucher import Voucher from ...models.voucher import Voucher
from ...models.voucher_type import VoucherType from ...models.voucher_type import VoucherType
from ...printing.product_sale_report import print_product_sale_report
from ...schemas import to_camel from ...schemas import to_camel
from ...schemas.user_token import UserToken from ...schemas.user_token import UserToken
from . import check_audit_permission, report_finish_date, report_start_date 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 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

View File

@ -2,3 +2,7 @@
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
} }
.spacer {
flex: 1 1 auto;
}

View File

@ -1,9 +1,13 @@
<mat-card> <mat-card>
<mat-card-title-group> <mat-card-title-group>
<mat-card-title>Product Sale Report</mat-card-title> <mat-card-title>Product Sale Report</mat-card-title>
<span class="spacer"></span>
<button mat-button mat-icon-button (click)="exportCsv()"> <button mat-button mat-icon-button (click)="exportCsv()">
<mat-icon>save_alt</mat-icon> <mat-icon>save_alt</mat-icon>
</button> </button>
<button mat-button mat-icon-button (click)="print()">
<mat-icon>print</mat-icon>
</button>
</mat-card-title-group> </mat-card-title-group>
<mat-card-content> <mat-card-content>
<form [formGroup]="form" fxLayout="column"> <form [formGroup]="form" fxLayout="column">

View File

@ -3,10 +3,12 @@ import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import * as moment from 'moment'; import * as moment from 'moment';
import { ToasterService } from '../core/toaster.service';
import { ToCsvService } from '../shared/to-csv.service'; import { ToCsvService } from '../shared/to-csv.service';
import { ProductSaleReport } from './product-sale-report'; import { ProductSaleReport } from './product-sale-report';
import { ProductSaleReportDataSource } from './product-sale-report-datasource'; import { ProductSaleReportDataSource } from './product-sale-report-datasource';
import { ProductSaleReportService } from './product-sale-report.service';
@Component({ @Component({
selector: 'app-product-sale-report', selector: 'app-product-sale-report',
@ -26,6 +28,8 @@ export class ProductSaleReportComponent implements OnInit {
private router: Router, private router: Router,
private fb: FormBuilder, private fb: FormBuilder,
private toCsv: ToCsvService, private toCsv: ToCsvService,
private toaster: ToasterService,
private ser: ProductSaleReportService,
) { ) {
// Create form // Create form
this.form = this.fb.group({ 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() { exportCsv() {
const headers = { const headers = {
Name: 'name', Name: 'name',

View File

@ -28,4 +28,18 @@ export class ProductSaleReportService {
.get<ProductSaleReport>(url, options) .get<ProductSaleReport>(url, options)
.pipe(catchError(this.log.handleError(serviceName, 'get'))) as Observable<ProductSaleReport>; .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>;
}
} }