From bbb7be8070eaaa3329bae604e05ab07eb92819dd Mon Sep 17 00:00:00 2001 From: Amritanshu Date: Tue, 17 Dec 2024 08:23:18 +0530 Subject: [PATCH] Sale report now can be section wise --- barker/barker/routers/reports/sale_report.py | 24 ++++--- barker/barker/schemas/sale_report.py | 3 + .../sale-report/sale-report.component.html | 17 ++++- .../app/sale-report/sale-report.component.ts | 71 ++++++++----------- .../app/sale-report/sale-report.resolver.ts | 3 +- .../src/app/sale-report/sale-report.routes.ts | 2 + .../app/sale-report/sale-report.service.ts | 10 ++- bookie/src/app/sale-report/sale-report.ts | 2 + .../app/sales/discount/discount.component.ts | 1 - .../receive-payment.component.html | 9 ++- .../receive-payment.component.ts | 1 - .../user-detail/user-detail.component.ts | 1 - 12 files changed, 85 insertions(+), 59 deletions(-) diff --git a/barker/barker/routers/reports/sale_report.py b/barker/barker/routers/reports/sale_report.py index ffc0f56..6e9e791 100644 --- a/barker/barker/routers/reports/sale_report.py +++ b/barker/barker/routers/reports/sale_report.py @@ -2,14 +2,16 @@ import uuid from datetime import date, datetime, time, timedelta from decimal import Decimal +from typing import Annotated -from fastapi import APIRouter, Cookie, Depends, Security +from fastapi import APIRouter, Cookie, Depends, Query, Security from sqlalchemy import func, or_, select from sqlalchemy.orm import Session from ...core.config import settings from ...core.security import get_current_active_user as get_user from ...db.session import SessionFuture +from ...models.food_table import FoodTable from ...models.inventory import Inventory from ...models.kot import Kot from ...models.product import Product @@ -34,6 +36,7 @@ router = APIRouter() def get_sale_report( start_date: date = Depends(report_start_date), finish_date: date = Depends(report_finish_date), + section: Annotated[uuid.UUID | None, Query()] = None, user: UserToken = Security(get_user, scopes=["sale-report"]), ) -> SaleReport: check_audit_permission(start_date, user.permissions) @@ -41,8 +44,9 @@ def get_sale_report( return SaleReport( start_date=start_date, finish_date=finish_date, + section_id=section, amounts=( - get_sale(start_date, finish_date, db) + get_sale(start_date, finish_date, section, db) + [SaleReportItem(name="--", amount=Decimal(0))] + get_settlements(start_date, finish_date, db) + [SaleReportItem(name="--", amount=Decimal(0))] @@ -52,7 +56,7 @@ def get_sale_report( ) -def get_sale(s: date, f: date, db: Session) -> list[SaleReportItem]: +def get_sale(s: date, f: date, id_: uuid.UUID | None, db: Session) -> list[SaleReportItem]: start_date = datetime.combine(s, time()) + timedelta( minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES ) @@ -61,13 +65,14 @@ def get_sale(s: date, f: date, db: Session) -> list[SaleReportItem]: ) day = func.date_trunc("day", Voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).label("day") - list_ = db.execute( + query = ( select(SaleCategory.name, func.sum(Inventory.net)) .join(Inventory.kot) .join(Kot.voucher) .join(Inventory.product) .join(Product.versions) .join(ProductVersion.sale_category) + .join(Voucher.food_table) .where( Voucher.date >= start_date, Voucher.date <= finish_date, @@ -82,9 +87,11 @@ def get_sale(s: date, f: date, db: Session) -> list[SaleReportItem]: ProductVersion.valid_till >= day, ), ) - .group_by(SaleCategory.name) - .order_by(SaleCategory.name) - ).all() + ) + if id_: + query = query.where(FoodTable.section_id == id_) + query = query.group_by(SaleCategory.name).order_by(SaleCategory.name) + list_ = db.execute(query).all() total = Decimal(0) info = [] for gt, am in list_: @@ -121,6 +128,7 @@ def get_settlements(s: date, f: date, db: Session) -> list[SaleReportItem]: def print_report( start_date: date = Depends(report_start_date), finish_date: date = Depends(report_finish_date), + section: Annotated[uuid.UUID | None, Query()] = None, device_id: uuid.UUID = Cookie(None), user: UserToken = Security(get_user, scopes=["sale-report"]), ) -> bool: @@ -130,7 +138,7 @@ def print_report( start_date=start_date, finish_date=finish_date, amounts=( - get_sale(start_date, finish_date, db) + get_sale(start_date, finish_date, section, db) + [SaleReportItem(name="--", amount=Decimal(0))] + get_settlements(start_date, finish_date, db) + [SaleReportItem(name="--", amount=Decimal(0))] diff --git a/barker/barker/schemas/sale_report.py b/barker/barker/schemas/sale_report.py index b71314b..9bc90cd 100644 --- a/barker/barker/schemas/sale_report.py +++ b/barker/barker/schemas/sale_report.py @@ -1,3 +1,5 @@ +import uuid + from datetime import date, datetime from pydantic import BaseModel, ConfigDict, field_serializer, field_validator @@ -15,6 +17,7 @@ class SaleReportItem(BaseModel): class SaleReport(BaseModel): start_date: date finish_date: date + section_id: uuid.UUID | None amounts: list[SaleReportItem] user: UserLink model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/bookie/src/app/sale-report/sale-report.component.html b/bookie/src/app/sale-report/sale-report.component.html index ffa5381..1e3eef7 100644 --- a/bookie/src/app/sale-report/sale-report.component.html +++ b/bookie/src/app/sale-report/sale-report.component.html @@ -14,7 +14,7 @@
- + Start Date - + Finish Date - + + Section + + -- All -- + @for (p of sections; track p.id) { + + {{ p.name }} + + } + + +
diff --git a/bookie/src/app/sale-report/sale-report.component.ts b/bookie/src/app/sale-report/sale-report.component.ts index 00171c7..87dac61 100644 --- a/bookie/src/app/sale-report/sale-report.component.ts +++ b/bookie/src/app/sale-report/sale-report.component.ts @@ -2,26 +2,18 @@ import { CurrencyPipe } from '@angular/common'; import { Component, OnInit } from '@angular/core'; import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { MatIconButton, MatButton } from '@angular/material/button'; -import { MatCard, MatCardHeader, MatCardTitleGroup, MatCardTitle, MatCardContent } from '@angular/material/card'; -import { MatDatepickerInput, MatDatepickerToggle, MatDatepicker } from '@angular/material/datepicker'; +import { MatCardModule } from '@angular/material/card'; +import { MatOptionModule } from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatFormField, MatLabel, MatSuffix } from '@angular/material/form-field'; import { MatIcon } from '@angular/material/icon'; import { MatInput } from '@angular/material/input'; -import { - MatTable, - MatColumnDef, - MatHeaderCellDef, - MatHeaderCell, - MatCellDef, - MatCell, - MatHeaderRowDef, - MatHeaderRow, - MatRowDef, - MatRow, -} from '@angular/material/table'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTableModule } from '@angular/material/table'; import { ActivatedRoute, Router } from '@angular/router'; import moment from 'moment'; +import { Section } from '../core/section'; import { ToasterService } from '../core/toaster.service'; import { ToCsvService } from '../shared/to-csv.service'; @@ -34,41 +26,30 @@ import { SaleReportService } from './sale-report.service'; templateUrl: './sale-report.component.html', styleUrls: ['./sale-report.component.css'], imports: [ - MatCard, - MatCardHeader, - MatCardTitleGroup, - MatCardTitle, + MatCardModule, MatIconButton, MatIcon, - MatCardContent, ReactiveFormsModule, MatFormField, MatLabel, MatInput, - MatDatepickerInput, - MatDatepickerToggle, + MatDatepickerModule, MatSuffix, - MatDatepicker, MatButton, - MatTable, - MatColumnDef, - MatHeaderCellDef, - MatHeaderCell, - MatCellDef, - MatCell, - MatHeaderRowDef, - MatHeaderRow, - MatRowDef, - MatRow, + MatTableModule, CurrencyPipe, + MatOptionModule, + MatSelectModule, ], }) export class SaleReportComponent implements OnInit { + sections: Section[] = []; info: SaleReport = new SaleReport(); dataSource: SaleReportDatasource = new SaleReportDatasource(this.info.amounts); form: FormGroup<{ startDate: FormControl; finishDate: FormControl; + section: FormControl; }>; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ @@ -85,16 +66,19 @@ export class SaleReportComponent implements OnInit { this.form = new FormGroup({ startDate: new FormControl(new Date(), { nonNullable: true }), finishDate: new FormControl(new Date(), { nonNullable: true }), + section: new FormControl(null), }); } ngOnInit() { this.route.data.subscribe((value) => { - const data = value as { info: SaleReport }; + const data = value as { sections: Section[]; info: SaleReport }; + this.sections = data.sections; this.info = data.info; this.form.setValue({ startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(), finishDate: moment(this.info.finishDate, 'DD-MMM-YYYY').toDate(), + section: this.info.sectionId || null, }); this.dataSource = new SaleReportDatasource(this.info.amounts); }); @@ -102,25 +86,32 @@ export class SaleReportComponent implements OnInit { show() { const info = this.getInfo(); + const params = { + startDate: info.startDate, + finishDate: info.finishDate, + } as { startDate: string; finishDate: string; section?: string }; + if (info.sectionId) { + params['section'] = info.sectionId; + } this.router.navigate(['sale-report'], { - queryParams: { - startDate: info.startDate, - finishDate: info.finishDate, - }, + queryParams: params, }); } getInfo(): SaleReport { const formModel = this.form.value; - - return new SaleReport({ + const data = new SaleReport({ startDate: moment(formModel.startDate).format('DD-MMM-YYYY'), finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'), }); + if (formModel.section) { + data.sectionId = formModel.section; + } + return data; } print() { - this.ser.print(this.info.startDate, this.info.finishDate).subscribe({ + this.ser.print(this.info.startDate, this.info.finishDate, this.info.sectionId).subscribe({ next: () => { this.toaster.show('', 'Successfully Printed'); }, diff --git a/bookie/src/app/sale-report/sale-report.resolver.ts b/bookie/src/app/sale-report/sale-report.resolver.ts index 8ca5ddd..9f9555e 100644 --- a/bookie/src/app/sale-report/sale-report.resolver.ts +++ b/bookie/src/app/sale-report/sale-report.resolver.ts @@ -7,5 +7,6 @@ import { SaleReportService } from './sale-report.service'; export const saleReportResolver: ResolveFn = (route) => { const startDate = route.queryParamMap.get('startDate') ?? null; const finishDate = route.queryParamMap.get('finishDate') ?? null; - return inject(SaleReportService).get(startDate, finishDate); + const section = route.queryParamMap.get('section') ?? null; + return inject(SaleReportService).get(startDate, finishDate, section); }; diff --git a/bookie/src/app/sale-report/sale-report.routes.ts b/bookie/src/app/sale-report/sale-report.routes.ts index c0129b1..606ebd0 100644 --- a/bookie/src/app/sale-report/sale-report.routes.ts +++ b/bookie/src/app/sale-report/sale-report.routes.ts @@ -1,6 +1,7 @@ import { Routes } from '@angular/router'; import { authGuard } from '../auth/auth-guard.service'; +import { sectionListResolver } from '../sections/section-list.resolver'; import { SaleReportComponent } from './sale-report.component'; import { saleReportResolver } from './sale-report.resolver'; @@ -14,6 +15,7 @@ export const routes: Routes = [ permission: 'Sale Report', }, resolve: { + sections: sectionListResolver, info: saleReportResolver, }, runGuardsAndResolvers: 'always', diff --git a/bookie/src/app/sale-report/sale-report.service.ts b/bookie/src/app/sale-report/sale-report.service.ts index af41ae3..941a7b7 100644 --- a/bookie/src/app/sale-report/sale-report.service.ts +++ b/bookie/src/app/sale-report/sale-report.service.ts @@ -19,7 +19,7 @@ export class SaleReportService { private log: ErrorLoggerService, ) {} - get(startDate: string | null, finishDate: string | null): Observable { + get(startDate: string | null, finishDate: string | null, section: string | null): Observable { const options = { params: new HttpParams() }; if (startDate !== null) { options.params = options.params.set('s', startDate); @@ -27,12 +27,15 @@ export class SaleReportService { if (finishDate !== null) { options.params = options.params.set('f', finishDate); } + if (section !== null) { + options.params = options.params.set('section', section); + } return this.http .get(url, options) .pipe(catchError(this.log.handleError(serviceName, 'get'))) as Observable; } - print(startDate: string | null, finishDate: string | null): Observable { + print(startDate: string | null, finishDate: string | null, section: string | null): Observable { const printUrl = `${url}/print`; const options = { params: new HttpParams() }; if (startDate !== null) { @@ -41,6 +44,9 @@ export class SaleReportService { if (finishDate !== null) { options.params = options.params.set('f', finishDate); } + if (section !== null) { + options.params = options.params.set('section', section); + } return this.http .get(printUrl, options) .pipe(catchError(this.log.handleError(serviceName, 'print'))) as Observable; diff --git a/bookie/src/app/sale-report/sale-report.ts b/bookie/src/app/sale-report/sale-report.ts index de7b134..e3b5fcf 100644 --- a/bookie/src/app/sale-report/sale-report.ts +++ b/bookie/src/app/sale-report/sale-report.ts @@ -3,11 +3,13 @@ import { SaleReportItem } from './sale-report-item'; export class SaleReport { startDate: string; finishDate: string; + sectionId: string | null; amounts: SaleReportItem[]; public constructor(init?: Partial) { this.startDate = ''; this.finishDate = ''; + this.sectionId = null; this.amounts = []; Object.assign(this, init); } diff --git a/bookie/src/app/sales/discount/discount.component.ts b/bookie/src/app/sales/discount/discount.component.ts index b42642c..43d8bfc 100644 --- a/bookie/src/app/sales/discount/discount.component.ts +++ b/bookie/src/app/sales/discount/discount.component.ts @@ -92,7 +92,6 @@ export class DiscountComponent { this.data.subscribe((list: DiscountItem[]) => { this.list = list; - console.log(list); this.form.controls.discounts.clear(); this.list.forEach((x) => { diff --git a/bookie/src/app/sales/receive-payment/receive-payment.component.html b/bookie/src/app/sales/receive-payment/receive-payment.component.html index a38939f..71f5013 100644 --- a/bookie/src/app/sales/receive-payment/receive-payment.component.html +++ b/bookie/src/app/sales/receive-payment/receive-payment.component.html @@ -1,7 +1,12 @@

Receive Payment

- + Amount @@ -24,7 +29,7 @@ - + Reason this.listenToAmountChange(x.amounts)); } diff --git a/bookie/src/app/users/user-detail/user-detail.component.ts b/bookie/src/app/users/user-detail/user-detail.component.ts index a81ac95..1b5e97b 100644 --- a/bookie/src/app/users/user-detail/user-detail.component.ts +++ b/bookie/src/app/users/user-detail/user-detail.component.ts @@ -103,7 +103,6 @@ export class UserDetailComponent implements OnInit, AfterViewInit { this.ser.saveOrUpdate(this.getItem()).subscribe({ next: () => { this.toaster.show('Success', ''); - console.log(this.item.id); if ((this.item.id as string) === 'me') { this.router.navigateByUrl('/'); } else {