diff --git a/.vscode/settings.json b/.vscode/settings.json index 15e29af..976caed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,5 +11,6 @@ "**/.mypy_cache": true, ".idea": true, "**/node_modules": true, + "**/package-lock.json": true, } } diff --git a/barker/barker/models/permission.py b/barker/barker/models/permission.py index e666158..445947e 100644 --- a/barker/barker/models/permission.py +++ b/barker/barker/models/permission.py @@ -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: diff --git a/barker/barker/models/product_version.py b/barker/barker/models/product_version.py index 2b47a12..ff0428b 100644 --- a/barker/barker/models/product_version.py +++ b/barker/barker/models/product_version.py @@ -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, "" diff --git a/barker/barker/routers/guest_book.py b/barker/barker/routers/guest_book.py index a5fedbd..53b7341 100644 --- a/barker/barker/routers/guest_book.py +++ b/barker/barker/routers/guest_book.py @@ -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) diff --git a/barker/barker/routers/voucher/change.py b/barker/barker/routers/voucher/change.py index 2254695..1e7b144 100644 --- a/barker/barker/routers/voucher/change.py +++ b/barker/barker/routers/voucher/change.py @@ -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: diff --git a/barker/pyproject.toml b/barker/pyproject.toml index 8cbf70d..6bb8ee0 100644 --- a/barker/pyproject.toml +++ b/barker/pyproject.toml @@ -6,31 +6,31 @@ authors = ["tanshu "] [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" diff --git a/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.html b/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.html index e5dada4..aa15d7e 100644 --- a/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.html +++ b/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.html @@ -54,7 +54,12 @@ Action - + diff --git a/bookie/src/app/sales/bills/bill-resolver.service.ts b/bookie/src/app/sales/bills/bill-resolver.service.ts index e875698..7054046 100644 --- a/bookie/src/app/sales/bills/bill-resolver.service.ts +++ b/bookie/src/app/sales/bills/bill-resolver.service.ts @@ -22,6 +22,9 @@ export class BillResolver implements Resolve { 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'); } } diff --git a/bookie/src/app/sales/bills/voucher.service.ts b/bookie/src/app/sales/bills/voucher.service.ts index f609dc8..0f1634a 100644 --- a/bookie/src/app/sales/bills/voucher.service.ts +++ b/bookie/src/app/sales/bills/voucher.service.ts @@ -52,6 +52,12 @@ export class VoucherService { .pipe(catchError(this.log.handleError(serviceName, `getFromBill billId=${billId}`))) as Observable; } + getFromId(voucherId: string): Observable { + return this.http + .get(`${url}/from-id/${voucherId}`) + .pipe(catchError(this.log.handleError(serviceName, `getFromId voucherId=${voucherId}`))) as Observable; + } + save(voucher: Bill, voucherType: VoucherType, guestBookId: string | null, updateTable: boolean): Observable { const options = { params: new HttpParams().set('p', voucherType.toString()).set('u', updateTable.toString()),