Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b1fca0260 | |||
| 43a884144b | |||
| 85a939b761 | |||
| 3bfa00364c | |||
| 0b092b5467 | |||
| 82747c4b89 | |||
| e732354671 |
@ -28,8 +28,6 @@ RUN \
|
||||
FROM python:3.12 AS runner
|
||||
LABEL maintainer="Amritanshu <docker@tanshu.com>"
|
||||
|
||||
COPY barker/pyproject.toml /app/pyproject.toml
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y locales && \
|
||||
sed --in-place --expression='s/# en_IN UTF-8/en_IN UTF-8/' /etc/locale.gen && \
|
||||
@ -46,6 +44,8 @@ RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry python
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY barker/pyproject.toml /app/pyproject.toml
|
||||
|
||||
# Allow installing dev dependencies to run tests
|
||||
ARG INSTALL_DEV=false
|
||||
RUN bash -c "if [ $INSTALL_DEV == 'true' ] ; then poetry install --no-root ; else poetry install --no-root --only main ; fi"
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
- hosts: barker
|
||||
become: true
|
||||
vars_files:
|
||||
- default
|
||||
- vars/default.yml
|
||||
- "{{ var_file }}"
|
||||
|
||||
roles:
|
||||
|
||||
@ -1 +1 @@
|
||||
__version__ = "12.1.1"
|
||||
__version__ = "12.1.4"
|
||||
|
||||
@ -3,10 +3,10 @@ import uuid
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from typing import Any
|
||||
|
||||
import jwt
|
||||
|
||||
from fastapi import Depends, HTTPException, Security, status
|
||||
from fastapi.security import OAuth2PasswordBearer, SecurityScopes
|
||||
from jose import jwt
|
||||
from jose.exceptions import ExpiredSignatureError
|
||||
from jwt import PyJWTError
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from sqlalchemy import select
|
||||
@ -82,7 +82,7 @@ async def get_current_user(
|
||||
raise credentials_exception
|
||||
token_scopes = payload.get("scopes", [])
|
||||
token_data = TokenData(scopes=token_scopes, username=username)
|
||||
except (PyJWTError, ValidationError, ExpiredSignatureError):
|
||||
except (PyJWTError, ValidationError):
|
||||
raise credentials_exception
|
||||
user = get_user(
|
||||
username=token_data.username,
|
||||
|
||||
@ -117,5 +117,5 @@ app.include_router(split.router, prefix="/api", tags=["voucher"])
|
||||
app.include_router(change.router, prefix="/api/voucher", tags=["voucher"])
|
||||
|
||||
|
||||
def init():
|
||||
def init() -> None:
|
||||
uvicorn.run(app, host=settings.HOST, port=settings.PORT)
|
||||
|
||||
@ -104,13 +104,12 @@ def update_route(
|
||||
def delete_route(
|
||||
id_: uuid.UUID,
|
||||
user: UserToken = Security(get_user, scopes=["customers"]),
|
||||
) -> schemas.GuestBookIn:
|
||||
) -> None:
|
||||
try:
|
||||
with SessionFuture() as db:
|
||||
item: GuestBook = db.execute(select(GuestBook).where(GuestBook.id == id_)).scalar_one()
|
||||
db.delete(item)
|
||||
db.commit()
|
||||
return blank_guest_book_info()
|
||||
except SQLAlchemyError as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
|
||||
@ -233,7 +233,6 @@ def modifier_category_info(item: ModifierCategory, date_: date, db: Session) ->
|
||||
schemas.MenuCategoryLink(
|
||||
id_=mc.id,
|
||||
name=mc.name,
|
||||
enabled=False,
|
||||
products=[
|
||||
ProductLinkSchema(
|
||||
id_=p.product_id,
|
||||
@ -284,7 +283,6 @@ def modifier_category_blank(date_: date, db: Session) -> schemas.ModifierCategor
|
||||
schemas.MenuCategoryLink(
|
||||
id_=mc.id,
|
||||
name=mc.name,
|
||||
enabled=False,
|
||||
products=[ProductLinkSchema(id_=p.product_id, name=p.name, enabled=False) for p in mc.products],
|
||||
)
|
||||
for mc in menu_categories
|
||||
|
||||
@ -45,7 +45,7 @@ def product_sale_report_view(
|
||||
}
|
||||
|
||||
|
||||
def product_sale_report(s: date, f: date, id_: uuid.UUID, db: Session):
|
||||
def product_sale_report(s: date, f: date, id_: uuid.UUID | None, db: Session):
|
||||
start_date = datetime.combine(s, time()) + timedelta(
|
||||
minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES
|
||||
)
|
||||
@ -128,7 +128,7 @@ def print_report(
|
||||
"startDate": start_date.strftime("%d-%b-%Y"),
|
||||
"finishDate": finish_date.strftime("%d-%b-%Y"),
|
||||
"sectionId": str(section) if section is not None else None,
|
||||
"amounts": product_sale_report(start_date, finish_date, db),
|
||||
"amounts": product_sale_report(start_date, finish_date, section, db),
|
||||
}
|
||||
print_product_sale_report(report, device_id, db)
|
||||
return True
|
||||
|
||||
@ -48,9 +48,9 @@ def get_sale_report(
|
||||
amounts=(
|
||||
get_sale(start_date, finish_date, section, db)
|
||||
+ [SaleReportItem(name="--", amount=Decimal(0))]
|
||||
+ get_settlements(start_date, finish_date, db)
|
||||
+ get_settlements(start_date, finish_date, section, db)
|
||||
+ [SaleReportItem(name="--", amount=Decimal(0))]
|
||||
+ [SaleReportItem(name=i.name, amount=i.amount) for i in get_tax(start_date, finish_date, db)]
|
||||
+ [SaleReportItem(name=i.name, amount=i.amount) for i in get_tax(start_date, finish_date, section, db)]
|
||||
),
|
||||
user=UserLink(id_=user.id_, name=user.name),
|
||||
)
|
||||
@ -100,7 +100,7 @@ def get_sale(s: date, f: date, id_: uuid.UUID | None, db: Session) -> list[SaleR
|
||||
return info + [SaleReportItem(name="Total Settled", amount=total)]
|
||||
|
||||
|
||||
def get_settlements(s: date, f: date, db: Session) -> list[SaleReportItem]:
|
||||
def get_settlements(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
|
||||
)
|
||||
@ -108,14 +108,17 @@ def get_settlements(s: date, f: date, db: Session) -> list[SaleReportItem]:
|
||||
days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES
|
||||
)
|
||||
|
||||
list_ = db.execute(
|
||||
query = (
|
||||
select(SettleOption.name, func.sum(Settlement.amount))
|
||||
.join(Voucher.settlements)
|
||||
.join(Settlement.settle_option)
|
||||
.join(Voucher.food_table)
|
||||
.where(Voucher.date >= start_date, Voucher.date <= finish_date)
|
||||
.group_by(SettleOption.name)
|
||||
.order_by(SettleOption.name)
|
||||
).all()
|
||||
)
|
||||
if id_:
|
||||
query = query.where(FoodTable.section_id == id_)
|
||||
query = query.group_by(SettleOption.name).order_by(SettleOption.name)
|
||||
list_ = db.execute(query).all()
|
||||
total = Decimal(0)
|
||||
info = []
|
||||
for gt, am in list_:
|
||||
@ -141,9 +144,9 @@ def print_report(
|
||||
amounts=(
|
||||
get_sale(start_date, finish_date, section, db)
|
||||
+ [SaleReportItem(name="--", amount=Decimal(0))]
|
||||
+ get_settlements(start_date, finish_date, db)
|
||||
+ get_settlements(start_date, finish_date, section, db)
|
||||
+ [SaleReportItem(name="--", amount=Decimal(0))]
|
||||
+ [SaleReportItem(name=i.name, amount=i.amount) for i in get_tax(start_date, finish_date, db)]
|
||||
+ [SaleReportItem(name=i.name, amount=i.amount) for i in get_tax(start_date, finish_date, section, db)]
|
||||
),
|
||||
user=UserLink(id_=user.id_, name=user.name),
|
||||
)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import re
|
||||
import uuid
|
||||
|
||||
from datetime import date, datetime, time, timedelta
|
||||
from decimal import Decimal
|
||||
@ -10,6 +11,7 @@ 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.tax import Tax
|
||||
@ -34,11 +36,11 @@ def get_tax_report(
|
||||
return TaxReport(
|
||||
start_date=start_date,
|
||||
finish_date=finish_date,
|
||||
amounts=get_tax(start_date, finish_date, db),
|
||||
amounts=get_tax(start_date, finish_date, None, db),
|
||||
)
|
||||
|
||||
|
||||
def get_tax(s: date, f: date, db: Session) -> list[TaxReportItem]:
|
||||
def get_tax(s: date, f: date, id_: uuid.UUID | None, db: Session) -> list[TaxReportItem]:
|
||||
start_date = datetime.combine(s, time()) + timedelta(
|
||||
minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES
|
||||
)
|
||||
@ -46,7 +48,7 @@ def get_tax(s: date, f: date, db: Session) -> list[TaxReportItem]:
|
||||
days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES
|
||||
)
|
||||
|
||||
amounts = db.execute(
|
||||
query = (
|
||||
select(
|
||||
Tax.name,
|
||||
Inventory.tax_rate,
|
||||
@ -56,14 +58,17 @@ def get_tax(s: date, f: date, db: Session) -> list[TaxReportItem]:
|
||||
.join(Voucher.kots)
|
||||
.join(Kot.inventories)
|
||||
.join(Inventory.tax)
|
||||
.join(Voucher.food_table)
|
||||
.where(
|
||||
Voucher.date >= start_date,
|
||||
Voucher.date <= finish_date,
|
||||
Voucher.voucher_type == VoucherType.REGULAR_BILL,
|
||||
)
|
||||
.group_by(Tax.name, Inventory.tax_rate)
|
||||
.order_by(Tax.name, Inventory.tax_rate)
|
||||
).all()
|
||||
)
|
||||
if id_:
|
||||
query = query.where(FoodTable.section_id == id_)
|
||||
query = query.group_by(Tax.name, Inventory.tax_rate).order_by(Tax.name, Inventory.tax_rate)
|
||||
amounts = db.execute(query).all()
|
||||
return sum([get_tax_item(*i) for i in amounts], [])
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import uuid
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from . import Daf, to_camel
|
||||
@ -8,8 +10,8 @@ from . import Daf, to_camel
|
||||
class CustomerDiscount(BaseModel):
|
||||
id_: uuid.UUID
|
||||
name: str
|
||||
discount: Daf = Field(ge=0, default=0, le=1)
|
||||
limit: Daf = Field(ge=0, default=0, le=1)
|
||||
discount: Daf = Field(ge=Decimal(0), default=Decimal(0), le=Decimal(1))
|
||||
limit: Daf = Field(ge=Decimal(0), default=Decimal(0), le=Decimal(1))
|
||||
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import uuid
|
||||
|
||||
from decimal import Decimal
|
||||
from typing import Annotated
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from . import Daf, to_camel
|
||||
@ -8,7 +11,7 @@ from . import Daf, to_camel
|
||||
class DiscountItem(BaseModel):
|
||||
id_: uuid.UUID
|
||||
name: str
|
||||
discount: Daf | None = Field(ge=0, default=0, le=1)
|
||||
discount: Annotated[Daf | None, Field(ge=Decimal(0), default=Decimal(0), le=Decimal(1))]
|
||||
limit: Daf
|
||||
customer: Daf
|
||||
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import uuid
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from . import Daf, to_camel
|
||||
@ -9,7 +11,7 @@ from .modifier_category import ModifierCategoryLink
|
||||
class ModifierIn(BaseModel):
|
||||
name: str = Field(..., min_length=1)
|
||||
show_in_bill: bool
|
||||
price: Daf = Field(ge=0, default=0)
|
||||
price: Daf = Field(ge=Decimal(0), default=Decimal(0))
|
||||
is_active: bool
|
||||
modifier_category: ModifierCategoryLink
|
||||
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import uuid
|
||||
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
|
||||
|
||||
@ -17,7 +18,7 @@ class ProductIn(BaseModel):
|
||||
price: Daf # = Field(ge=0, default=0)
|
||||
has_happy_hour: bool
|
||||
is_not_available: bool
|
||||
quantity: Daf = Field(ge=0, default=0)
|
||||
quantity: Daf = Field(ge=Decimal(0), default=Decimal(0))
|
||||
is_active: bool
|
||||
sort_order: int
|
||||
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import uuid
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from . import Daf, to_camel
|
||||
@ -8,7 +10,7 @@ from .tax import TaxLink
|
||||
|
||||
class SaleCategoryIn(BaseModel):
|
||||
name: str = Field(..., min_length=1)
|
||||
discount_limit: Daf = Field(ge=0, default=0, le=1)
|
||||
discount_limit: Daf = Field(ge=Decimal(0), default=Decimal(0), le=Decimal(1))
|
||||
tax: TaxLink = Field(...)
|
||||
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import uuid
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from . import Daf, to_camel
|
||||
@ -8,7 +10,7 @@ from .regime import RegimeLink
|
||||
|
||||
class TaxIn(BaseModel):
|
||||
name: str = Field(..., min_length=1)
|
||||
rate: Daf = Field(ge=0, default=0)
|
||||
rate: Daf = Field(ge=Decimal(0), default=Decimal(0))
|
||||
regime: RegimeLink = Field(...)
|
||||
is_fixture: bool
|
||||
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)
|
||||
@ -21,7 +23,7 @@ class Tax(TaxIn):
|
||||
|
||||
class TaxBlank(BaseModel):
|
||||
name: str
|
||||
rate: Daf = Field(ge=0, default=0)
|
||||
rate: Daf = Field(ge=Decimal(0), default=Decimal(0))
|
||||
is_fixture: bool
|
||||
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "barker"
|
||||
version = "12.1.1"
|
||||
version = "12.1.4"
|
||||
description = "Point of Sale for a restaurant"
|
||||
authors = ["tanshu <git@tanshu.com>"]
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
gunicorn barker.main:app --worker-class uvicorn.workers.UvicornWorker --config ./barker/gunicorn.conf.py --log-config ./barker/logging.conf
|
||||
gunicorn barker.main:app --worker-class uvicorn.workers.UvicornWorker --config ./gunicorn.conf.py --log-config ./logging.conf
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bookie",
|
||||
"version": "12.1.1",
|
||||
"version": "12.1.4",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
export const environment = {
|
||||
production: true,
|
||||
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
|
||||
version: '12.1.1',
|
||||
version: '12.1.4',
|
||||
};
|
||||
|
||||
export const dateFormat = {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "frank"
|
||||
version = "12.1.1"
|
||||
version = "12.1.4"
|
||||
description = "Point of Sale for a restaurant"
|
||||
authors = ["tanshu <git@tanshu.com>"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user