Fix: Prevent creation of customer with blank name when adding a guest book item.

Fix: Also prevent creation of customer with blank phone number when adding a guest book.
Feature: Show the old bill of a customer in guest book
Fix: In reprint, allow changing of customer
Chore: Updated dependencies
This commit is contained in:
Amritanshu Agrawal 2023-04-09 15:42:32 +05:30
parent 302ed4a18f
commit 8bc7d66123
9 changed files with 81 additions and 31 deletions

View File

@ -11,5 +11,6 @@
"**/.mypy_cache": true,
".idea": true,
"**/node_modules": true,
"**/package-lock.json": true,
}
}

View File

@ -2,12 +2,12 @@ import uuid
from typing import TYPE_CHECKING, List
from barker.models.role_permission import RolePermission
from sqlalchemy import Unicode, text
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
from ..db.base_class import reg
from .role_permission import RolePermission
if TYPE_CHECKING:

View File

@ -122,6 +122,6 @@ class ProductVersion:
return False, f"{self.name} is a fixture and cannot be edited or deleted."
if self.is_active:
return False, "Product is active"
if len(self.inventories) > 0 and not advanced_delete:
return False, "Product has entries"
# if len(self.inventories) > 0 and not advanced_delete:
# return False, "Product has entries"
return True, ""

View File

@ -5,14 +5,16 @@ from datetime import date, datetime, timedelta
import barker.schemas.guest_book as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import select
from sqlalchemy import desc, select
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import joinedload
from ..core.config import settings
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionFuture
from ..models.customer import Customer
from ..models.guest_book import GuestBook
from ..models.voucher import Voucher
from ..schemas.user_token import UserToken
@ -28,6 +30,13 @@ def save(
with SessionFuture() as db:
customer = db.execute(select(Customer).where(Customer.phone == data.phone)).scalars().one_or_none()
if customer is None:
if len(data.name) == 0:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="New customer name cannot be blank",
)
if len(data.phone) == 0:
data.phone = data.name
customer = Customer(
name=data.name,
phone=data.phone,
@ -127,21 +136,34 @@ def show_list(
guest_book: list[schemas.GuestBookListItem] = []
with SessionFuture() as db:
for i, item in enumerate(db.execute(list_).scalars().all()):
guest_book.insert(
0,
schemas.GuestBookListItem(
id=item.id,
serial=i + 1,
name=item.customer.name,
phone=item.customer.phone,
pax=item.pax,
date=item.date,
status=None if item.status is None else item.status.status,
tableId=None if item.status is None else item.status.food_table.id,
voucherId=None if item.status is None else item.status.voucher_id,
tableName=None if item.status is None else item.status.food_table.name,
),
gbli = schemas.GuestBookListItem(
id=item.id,
serial=i + 1,
name=item.customer.name,
phone=item.customer.phone,
pax=item.pax,
date=item.date,
status=None if item.status is None else item.status.status,
tableId=None if item.status is None else item.status.food_table.id,
voucherId=None if item.status is None else item.status.voucher_id,
tableName=None if item.status is None else item.status.food_table.name,
)
if item.status is None:
last = (
db.execute(
select(Voucher)
.where(Voucher.customer_id == item.customer_id)
.order_by(desc(Voucher.date))
.options(joinedload(Voucher.food_table, innerjoin=True))
)
.scalars()
.first()
)
if last is not None:
gbli.status = "old"
gbli.voucher_id = last.id
gbli.table_name = last.food_table.name
guest_book.insert(0, gbli)
return schemas.GuestBookList(date=d, list=guest_book)

View File

@ -56,6 +56,10 @@ def change(
if bill_changed:
id_ = void_and_issue_new_bill(data, u, g, old, db, user)
else:
if data.customer is not None:
old.customer_id = data.customer.id_
else:
old.customer_id = None
reprint_bill(id_, user.id_, db)
db.commit()
with SessionFuture() as db:

View File

@ -6,31 +6,31 @@ authors = ["tanshu <git@tanshu.com>"]
[tool.poetry.dependencies]
python = "^3.11"
uvicorn = {extras = ["standard"], version = "^0.20.0"}
fastapi = "^0.92.0"
uvicorn = {extras = ["standard"], version = "^0.21.1"}
fastapi = "^0.95.0"
python-jose = {extras = ["cryptography"], version = "^3.3.0"}
passlib = {extras = ["bcrypt"], version = "^1.7.4"}
psycopg2-binary = "^2.9.5"
SQLAlchemy = "^2.0.4"
python-multipart = "^0.0.5"
SQLAlchemy = "^2.0.7"
python-multipart = "^0.0.6"
PyJWT = "^2.6.0"
alembic = "^1.9.4"
alembic = "^1.10.2"
itsdangerous = "^2.1.2"
python-dotenv = "^0.21.1"
pydantic = {extras = ["dotenv"], version = "^1.10.5"}
starlette = "^0.25.0"
python-dotenv = "^1.0.0"
pydantic = {extras = ["dotenv"], version = "^1.10.7"}
starlette = "^0.26.1"
arq = "^0.25.0"
aiohttp = "^3.8.4"
cryptography = "^39.0.1"
cryptography = "^40.0.1"
gunicorn = "^20.1.0"
[tool.poetry.dev-dependencies]
flake8 = "^6.0.0"
black = "^23.1.0"
isort = {extras = ["toml"], version = "^5.12.0"}
pre-commit = "^3.0.4"
mypy = "^1.0.1"
types-python-jose = "^3.3.4.4"
pre-commit = "^3.2.0"
mypy = "^1.1.1"
types-python-jose = "^3.3.4.5"
[tool.poetry.group.dev.dependencies]
tomli = "^2.0.1"

View File

@ -54,7 +54,12 @@
<ng-container matColumnDef="action">
<mat-header-cell *matHeaderCellDef class="center">Action</mat-header-cell>
<mat-cell *matCellDef="let row" class="center">
<button mat-icon-button [routerLink]="['/sales']" [queryParams]="{ guest: row.id }" *ngIf="!row.tableId">
<button
mat-icon-button
[routerLink]="['/sales']"
[queryParams]="{ guest: row.id }"
*ngIf="!row.tableId && !row.voucherId"
>
<mat-icon>chair</mat-icon>
</button>
<button
@ -66,6 +71,15 @@
>
{{ row.tableName }}
</button>
<button
mat-stroked-button
color="primary"
[routerLink]="['/sales', 'bill']"
[queryParams]="{ voucher: row.voucherId }"
*ngIf="!row.tableId && row.voucherId"
>
{{ row.tableName }}
</button>
<button mat-icon-button [routerLink]="['/guest-book/', row.id]">
<mat-icon>edit</mat-icon>
</button>

View File

@ -22,6 +22,9 @@ export class BillResolver implements Resolve<Bill> {
if (tableId !== null) {
return this.ser.getFromTable(tableId as string, voucherId, guestId);
}
if (voucherId !== null) {
return this.ser.getFromId(voucherId);
}
throw new Error('Unable to get bill');
}
}

View File

@ -52,6 +52,12 @@ export class VoucherService {
.pipe(catchError(this.log.handleError(serviceName, `getFromBill billId=${billId}`))) as Observable<Bill>;
}
getFromId(voucherId: string): Observable<Bill> {
return this.http
.get<Bill>(`${url}/from-id/${voucherId}`)
.pipe(catchError(this.log.handleError(serviceName, `getFromId voucherId=${voucherId}`))) as Observable<Bill>;
}
save(voucher: Bill, voucherType: VoucherType, guestBookId: string | null, updateTable: boolean): Observable<boolean> {
const options = {
params: new HttpParams().set('p', voucherType.toString()).set('u', updateTable.toString()),