7 Commits

Author SHA1 Message Date
4b1fca0260 Version Bump v12.1.4 2024-12-17 09:47:34 +05:30
43a884144b Fix: Issues flagged by mypy 2024-12-17 09:47:25 +05:30
85a939b761 Fix: Show section wise settlement and tax 2024-12-17 09:46:44 +05:30
3bfa00364c Version Bump v12.1.3 2024-12-17 09:18:43 +05:30
0b092b5467 Fix: login failed as python-jose was removed. 2024-12-17 09:18:33 +05:30
82747c4b89 Version Bump v12.1.2 2024-12-17 09:04:56 +05:30
e732354671 Fix: run was referencing files in a subdirectory.
Fix: Playbook was not importing the default vars.
Improvement: Dockerfile casheing should improve.
2024-12-17 09:04:49 +05:30
21 changed files with 59 additions and 42 deletions

View File

@ -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"

View File

@ -5,7 +5,7 @@
- hosts: barker
become: true
vars_files:
- default
- vars/default.yml
- "{{ var_file }}"
roles:

View File

@ -1 +1 @@
__version__ = "12.1.1"
__version__ = "12.1.4"

View File

@ -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,

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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),
)

View File

@ -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], [])

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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>"]

View File

@ -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

View File

@ -1,6 +1,6 @@
{
"name": "bookie",
"version": "12.1.1",
"version": "12.1.4",
"scripts": {
"ng": "ng",
"start": "ng serve",

View File

@ -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 = {

View File

@ -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>"]