Chore: Mypy work going on

Fix: Recipes costing of semi items would show very high cost of the whole recipe for per unit as ingredient
This commit is contained in:
tanshu committed 2021-11-14 12:02:22 +05:30
1 parent ddd389a899
commit ee7f036ced
47 files changed
+487 -437

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
[flake8] [flake8]
ignore = E203, W503 ignore = E203, W503, E501
max-line-length = 120 max-line-length = 120
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
+1 -1
View File
@@ -66,7 +66,7 @@ def authenticate_user(username: str, password: str, db: Session) -> Optional[Use
def client_allowed(user: UserModel, client_id: int, otp: Optional[int], db: Session) -> Tuple[bool, Client]: def client_allowed(user: UserModel, client_id: int, otp: Optional[int], db: Session) -> Tuple[bool, Client]:
client: Client = ( client: Optional[Client] = (
db.execute(select(Client).where(Client.code == client_id)).scalar_one_or_none() if client_id else None db.execute(select(Client).where(Client.code == client_id)).scalar_one_or_none() if client_id else None
) )
if client is None: if client is None:
+7 -7
View File
@@ -1,30 +1,30 @@
from datetime import date, timedelta from datetime import date, timedelta
from typing import Union
def get_date(session: dict) -> str: def get_date(session: dict) -> str:
if "date" not in session: if "date" not in session:
session["date"] = date.today().strftime("%d-%b-%Y") session["date"] = date.today().strftime("%d-%b-%Y")
return session["date"] return session["date"] # type: ignore[no-any-return]
def set_date(date_: str, session: dict) -> str: def set_date(date_: Union[str, date], session: dict) -> None:
session["date"] = date_ session["date"] = date_ if isinstance(date_, str) else date_.strftime("%d-%b-%Y")
return session["date"]
def get_start_date(session: dict) -> str: def get_start_date(session: dict) -> str:
if "start" not in session: if "start" not in session:
session["start"] = get_first_day(date.today()).strftime("%d-%b-%Y") session["start"] = get_first_day(date.today()).strftime("%d-%b-%Y")
return session["start"] return session["start"] # type: ignore[no-any-return]
def get_finish_date(session: dict) -> str: def get_finish_date(session: dict) -> str:
if "finish" not in session: if "finish" not in session:
session["finish"] = get_last_day(date.today()).strftime("%d-%b-%Y") session["finish"] = get_last_day(date.today()).strftime("%d-%b-%Y")
return session["finish"] return session["finish"] # type: ignore[no-any-return]
def set_period(start, finish, session: dict): def set_period(start: Union[str, date], finish: Union[str, date], session: dict) -> None:
if start is not None: if start is not None:
session["start"] = start if isinstance(start, str) else start.strftime("%d-%b-%Y") session["start"] = start if isinstance(start, str) else start.strftime("%d-%b-%Y")
if finish is not None: if finish is not None:
+1 -1
View File
@@ -8,5 +8,5 @@ from ..core.config import settings
logging.basicConfig() logging.basicConfig()
logging.getLogger("sqlalchemy.engine").setLevel(settings.LOG_LEVEL) logging.getLogger("sqlalchemy.engine").setLevel(settings.LOG_LEVEL)
engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True, future=True) engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True, future=True) # type: ignore[arg-type]
SessionFuture = sessionmaker(autoflush=False, bind=engine, future=True) SessionFuture = sessionmaker(autoflush=False, bind=engine, future=True)
+1 -32
View File
@@ -1,8 +1,4 @@
import re
import uuid
from datetime import date, timedelta from datetime import date, timedelta
from decimal import Decimal
from typing import List, Optional, Tuple from typing import List, Optional, Tuple
from sqlalchemy import or_, select from sqlalchemy import or_, select
@@ -42,7 +38,7 @@ def get_lock_info(
.scalars() .scalars()
.all() .all()
) )
data = sorted(data, key=lambda d: d["index"], reverse=True) data = sorted(data, key=lambda d: d["index"], reverse=True) # type: ignore[no-any-return]
for it in data: for it in data:
li: LockInformation = LockInformation( li: LockInformation = LockInformation(
voucherTypes=[VoucherTypesSelected(id=vt["id_"], name=vt["name"]) for vt in it["voucher_types"]], voucherTypes=[VoucherTypesSelected(id=vt["id_"], name=vt["name"]) for vt in it["voucher_types"]],
@@ -77,30 +73,3 @@ def get_lock_info(
return True, "Voucher allowed" return True, "Voucher allowed"
return False, "Default Fallthrough" return False, "Default Fallthrough"
def to_uuid(value):
p = re.compile("^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$")
return uuid.UUID(value) if p.match(value) else None
def to_decimal(value, default=0):
import re
_parser = re.compile(
r""" # A numeric string consists of:
(?P<sign>[-+])? # an optional sign, followed by either...
(
(?=\d|\.\d) # ...a number (with at least one digit)
(?P<int>\d*) # having a (possibly empty) integer part
(\.(?P<frac>\d*))? # followed by an optional fractional part
|
(?P<signal>s)? # ...an (optionally signaling)
NaN # NaN
(?P<diag>\d*) # with (possibly empty) diagnostic info.
)
\Z
""",
re.VERBOSE | re.IGNORECASE,
).match
return Decimal(value) if _parser(value.strip()) is not None else default
+15 -14
View File
@@ -1,8 +1,8 @@
import uuid import uuid
from datetime import datetime from datetime import date, datetime
from decimal import Decimal from decimal import Decimal
from typing import List from typing import List, Optional
import brewman.schemas.account as schemas import brewman.schemas.account as schemas
@@ -20,6 +20,7 @@ from ..models.cost_centre import CostCentre
from ..models.journal import Journal from ..models.journal import Journal
from ..models.voucher import Voucher from ..models.voucher import Voucher
from ..models.voucher_type import VoucherType from ..models.voucher_type import VoucherType
from ..schemas.balance import AccountBalance
from ..schemas.user import UserToken from ..schemas.user import UserToken
@@ -121,7 +122,7 @@ async def show_list(user: UserToken = Depends(get_user)) -> List[schemas.Account
] ]
@router.get("/query") @router.get("/query", response_model=List[schemas.AccountLink])
async def show_term( async def show_term(
q: str, q: str,
t: int = None, t: int = None,
@@ -129,26 +130,26 @@ async def show_term(
a: bool = None, a: bool = None,
c: int = None, c: int = None,
current_user: UserToken = Depends(get_user), current_user: UserToken = Depends(get_user),
): ) -> List[schemas.AccountLink]:
count = c count = c
list_ = [] list_: List[schemas.AccountLink] = []
with SessionFuture() as db: with SessionFuture() as db:
for index, item in enumerate(AccountBase.query(q, t, r, a, db)): for index, item in enumerate(AccountBase.query(q, t, r, a, db)):
list_.append({"id": item.id, "name": item.name}) list_.append(schemas.AccountLink(id=item.id, name=item.name))
if count is not None and index == count - 1: if count is not None and index == count - 1:
break break
return list_ return list_
@router.get("/{id_}/balance") @router.get("/{id_}/balance", response_model=AccountBalance)
async def show_balance( async def show_balance(
id_: uuid.UUID, id_: uuid.UUID,
d: str = None, d: str = None,
user: UserToken = Depends(get_user), user: UserToken = Depends(get_user),
): ) -> AccountBalance:
date = None if d is None or d == "" else datetime.strptime(d, "%d-%b-%Y") date_ = None if d is None or d == "" else datetime.strptime(d, "%d-%b-%Y")
with SessionFuture() as db: with SessionFuture() as db:
return {"date": balance(id_, date, db), "total": balance(id_, None, db)} return AccountBalance(date=balance(id_, date_, db), total=balance(id_, None, db))
@router.get("/{id_}", response_model=schemas.Account) @router.get("/{id_}", response_model=schemas.Account)
@@ -161,17 +162,17 @@ def show_id(
return account_info(item) return account_info(item)
def balance(id_: uuid.UUID, date, db: Session) -> Decimal: def balance(id_: uuid.UUID, date_: Optional[date], db: Session) -> Decimal:
account: AccountBase = db.execute(select(AccountBase).where(AccountBase.id == id_)).scalar_one() account: AccountBase = db.execute(select(AccountBase).where(AccountBase.id == id_)).scalar_one()
if not account.type_.balance_sheet: if not account.type_.balance_sheet:
return Decimal(0) return Decimal(0)
bal = select(func.sum(Journal.amount * Journal.debit)).join(Journal.voucher) bal = select(func.sum(Journal.amount * Journal.debit)).join(Journal.voucher)
if date is not None: if date_ is not None:
bal = bal.where(Voucher.date <= date) bal = bal.where(Voucher.date <= date_)
bal = bal.where(Voucher.voucher_type != VoucherType.ISSUE).where(Journal.account_id == id_) bal = bal.where(Voucher.voucher_type != VoucherType.ISSUE).where(Journal.account_id == id_)
result: Decimal = db.execute(bal).scalar_one_or_none() result: Optional[Decimal] = db.execute(bal).scalar_one_or_none()
return Decimal(0) if result is None else result return Decimal(0) if result is None else result
+17 -12
View File
@@ -1,4 +1,5 @@
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from typing import Generator, List
import brewman.schemas.attendance as schemas import brewman.schemas.attendance as schemas
@@ -20,8 +21,10 @@ router = APIRouter()
@router.get("", response_model=schemas.Attendance) @router.get("", response_model=schemas.Attendance)
def attendance_blank(request: Request, user: UserToken = Security(get_user, scopes=["attendance"])): def attendance_blank(
return {"date": get_date(request.session), "body": []} request: Request, user: UserToken = Security(get_user, scopes=["attendance"])
) -> schemas.Attendance:
return schemas.Attendance(date=get_date(request.session), body=[])
@router.get("/{date_}", response_model=schemas.Attendance) @router.get("/{date_}", response_model=schemas.Attendance)
@@ -29,17 +32,17 @@ def attendance_date(
date_: str, date_: str,
request: Request, request: Request,
user: UserToken = Security(get_user, scopes=["attendance"]), user: UserToken = Security(get_user, scopes=["attendance"]),
): ) -> schemas.Attendance:
set_date(date_, request.session) set_date(date_, request.session)
with SessionFuture() as db: with SessionFuture() as db:
return { return schemas.Attendance(
"date": date_, date=date_,
"body": attendance_date_report(datetime.strptime(date_, "%d-%b-%Y"), db), body=attendance_date_report(datetime.strptime(date_, "%d-%b-%Y"), db),
} )
def attendance_date_report(date_: date, db: Session): def attendance_date_report(date_: date, db: Session) -> List[schemas.AttendanceItem]:
body = [] body: List[schemas.AttendanceItem] = []
employees = ( employees = (
db.execute( db.execute(
select(Employee) select(Employee)
@@ -93,7 +96,7 @@ def save(
date_: str, date_: str,
data: schemas.Attendance, data: schemas.Attendance,
user: UserToken = Security(get_user, scopes=["attendance"]), user: UserToken = Security(get_user, scopes=["attendance"]),
): ) -> schemas.Attendance:
try: try:
att_date = datetime.strptime(date_, "%d-%b-%Y").date() att_date = datetime.strptime(date_, "%d-%b-%Y").date()
with SessionFuture() as db: with SessionFuture() as db:
@@ -107,7 +110,7 @@ def save(
) )
attendance.create(db) attendance.create(db)
db.commit() db.commit()
return {"date": date_, "body": attendance_date_report(att_date, db)} return schemas.Attendance(date=date_, body=attendance_date_report(att_date, db))
except SQLAlchemyError as e: except SQLAlchemyError as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -115,7 +118,9 @@ def save(
) )
def date_range(start: date, stop: date, step=timedelta(days=1), inclusive=False): def date_range(
start: date, stop: date, step: timedelta = timedelta(days=1), inclusive: bool = False
) -> Generator[date, None, None]:
# inclusive=False to behave like range by default # inclusive=False to behave like range by default
if step.days > 0: if step.days > 0:
while start < stop: while start < stop:
+3 -3
View File
@@ -18,12 +18,12 @@ from .attendance import date_range
router = APIRouter() router = APIRouter()
@router.get("") @router.get("", response_class=StreamingResponse)
def get_report( def get_report(
s: str, s: str,
f: str, f: str,
# user: UserToken = Security(get_user, scopes=["attendance"]) ## removed as jwt headers are a pain in the ass # user: UserToken = Security(get_user, scopes=["attendance"]) ## removed as jwt headers are a pain in the ass
): ) -> StreamingResponse:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
output = io.StringIO() output = io.StringIO()
@@ -41,7 +41,7 @@ def get_report(
# output.close() # output.close()
def attendance_record(start_date: date, finish_date: date, output, db: Session): def attendance_record(start_date: date, finish_date: date, output: io.StringIO, db: Session) -> None:
header = ["Code", "Name", "Designation", "Department", "Salary", "Points"] header = ["Code", "Name", "Designation", "Department", "Salary", "Points"]
for date_ in date_range(start_date, finish_date, inclusive=True): for date_ in date_range(start_date, finish_date, inclusive=True):
header.append(date_.strftime("%d-%b")) header.append(date_.strftime("%d-%b"))
+8 -4
View File
@@ -1,3 +1,7 @@
from typing import List
import brewman.schemas.attendance_type as schemas
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from ..core.security import get_current_active_user as get_user from ..core.security import get_current_active_user as get_user
@@ -8,10 +12,10 @@ from ..schemas.user import UserToken
router = APIRouter() router = APIRouter()
@router.get("") @router.get("", response_model=List[schemas.AttendanceType])
async def show_list(user: UserToken = Depends(get_user)): async def show_list(user: UserToken = Depends(get_user)) -> List[schemas.AttendanceType]:
list_ = AttendanceType.list() list_ = AttendanceType.list()
attendance_types = [] attendance_types: List[schemas.AttendanceType] = []
for item in list_: for item in list_:
attendance_types.append({"id": item.id, "name": item.name, "value": item.value}) attendance_types.append(schemas.AttendanceType(id=item.id, name=item.name, value=item.value))
return attendance_types return attendance_types
+13 -15
View File
@@ -18,12 +18,12 @@ from ..schemas.user import UserToken
router = APIRouter() router = APIRouter()
@router.put("/{id_}") @router.put("/{id_}", response_model=None)
def update_route( def update_route(
id_: uuid.UUID, id_: uuid.UUID,
data: schemas.ClientIn, data: schemas.ClientIn,
user: UserToken = Security(get_user, scopes=["clients"]), user: UserToken = Security(get_user, scopes=["clients"]),
): ) -> None:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Client = db.execute(select(Client).where(Client.id == id_)).scalar_one() item: Client = db.execute(select(Client).where(Client.id == id_)).scalar_one()
@@ -32,7 +32,6 @@ def update_route(
item.otp = None item.otp = None
item.name = data.name item.name = data.name
db.commit() db.commit()
return {}
except SQLAlchemyError as e: except SQLAlchemyError as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -40,18 +39,17 @@ def update_route(
) )
@router.delete("/{id_}") @router.delete("/{id_}", response_model=None)
def delete_route( def delete_route(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["clients"]), user: UserToken = Security(get_user, scopes=["clients"]),
): ) -> None:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Client = db.execute(select(Client).where(Client.id == id_)).scalar_one() item: Client = db.execute(select(Client).where(Client.id == id_)).scalar_one()
db.execute(delete(LoginHistory).where(LoginHistory.client_id == item.id)) db.execute(delete(LoginHistory).where(LoginHistory.client_id == item.id))
db.delete(item) db.delete(item)
db.commit() db.commit()
return {}
except SQLAlchemyError as e: except SQLAlchemyError as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -82,17 +80,17 @@ async def show_list(
return clients return clients
@router.get("/{id_}") @router.get("/{id_}", response_model=schemas.Client)
def show_id( def show_id(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["clients"]), user: UserToken = Security(get_user, scopes=["clients"]),
): ) -> schemas.Client:
with SessionFuture() as db: with SessionFuture() as db:
item: Client = db.execute(select(Client).where(Client.id == id_)).scalar_one() item: Client = db.execute(select(Client).where(Client.id == id_)).scalar_one()
return { return schemas.Client(
"id": item.id, id=item.id,
"code": item.code, code=item.code,
"name": item.name, name=item.name,
"enabled": item.enabled, enabled=item.enabled,
"otp": item.otp, otp=item.otp,
} )
+2 -2
View File
@@ -61,11 +61,11 @@ def update_route(
) )
@router.delete("/{id_}", response_model=schemas.CostCentreBlank) @router.delete("/{id_}", response_model=None)
def delete_route( def delete_route(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["cost-centres"]), user: UserToken = Security(get_user, scopes=["cost-centres"]),
): ) -> None:
with SessionFuture() as db: with SessionFuture() as db:
item: CostCentre = db.execute(select(CostCentre).where(CostCentre.id == id_)).scalar_one() item: CostCentre = db.execute(select(CostCentre).where(CostCentre.id == id_)).scalar_one()
if item.is_fixture: if item.is_fixture:
+9 -6
View File
@@ -1,5 +1,7 @@
from calendar import monthrange from calendar import monthrange
from datetime import date, datetime from datetime import date, datetime
from decimal import Decimal
from typing import List
from fastapi import APIRouter, Body, HTTPException, Security, status from fastapi import APIRouter, Body, HTTPException, Security, status
from sqlalchemy import or_, select from sqlalchemy import or_, select
@@ -15,17 +17,18 @@ from ..models.employee import Employee
from ..models.journal import Journal from ..models.journal import Journal
from ..models.voucher import Voucher from ..models.voucher import Voucher
from ..models.voucher_type import VoucherType from ..models.voucher_type import VoucherType
from ..schemas.message import Message
from ..schemas.user import UserToken from ..schemas.user import UserToken
router = APIRouter() router = APIRouter()
@router.post("") @router.post("", response_model=Message)
def credit_salary( def credit_salary(
month: str = Body(..., embed=True), month: str = Body(..., embed=True),
user: UserToken = Security(get_user, scopes=["attendance"]), user: UserToken = Security(get_user, scopes=["attendance"]),
): ) -> Message:
month_ = datetime.strptime(month, "%d-%b-%Y").date() month_ = datetime.strptime(month, "%d-%b-%Y").date()
start_date = get_first_day(month_) start_date = get_first_day(month_)
finish_date = get_last_day(month_) finish_date = get_last_day(month_)
@@ -43,13 +46,13 @@ def credit_salary(
voucher.journals.append(item) voucher.journals.append(item)
db.add(item) db.add(item)
db.commit() db.commit()
return {"message": "Salary Entry created"} return Message(message="Salary Entry created")
def salary_journals(start_date: date, finish_date: date, db: Session): def salary_journals(start_date: date, finish_date: date, db: Session) -> List[Journal]:
days = monthrange(start_date.year, start_date.month)[1] days = monthrange(start_date.year, start_date.month)[1]
amount = 0 amount = Decimal(0)
journals = [] journals: List[Journal] = []
employees = ( employees = (
db.execute( db.execute(
select(Employee) select(Employee)
+4 -4
View File
@@ -17,8 +17,8 @@ from ..models.db_image import DbImage
router = APIRouter() router = APIRouter()
@router.get("/{id_}/{type_}") @router.get("/{id_}/{type_}", response_class=StreamingResponse)
def db_image(id_: uuid.UUID, type_: str): def db_image(id_: uuid.UUID, type_: str) -> StreamingResponse:
with SessionFuture() as db: with SessionFuture() as db:
item = db.execute(select(DbImage).where(DbImage.id == id_)).scalar_one() item = db.execute(select(DbImage).where(DbImage.id == id_)).scalar_one()
if type_ == "thumbnail": if type_ == "thumbnail":
@@ -28,7 +28,7 @@ def db_image(id_: uuid.UUID, type_: str):
return StreamingResponse(item, media_type="image/jpeg") return StreamingResponse(item, media_type="image/jpeg")
def save_files(voucher_id: uuid.UUID, i: List[bytes], t: List[bytes], db: Session): def save_files(voucher_id: uuid.UUID, i: List[bytes], t: List[bytes], db: Session) -> None:
i = i or [] i = i or []
t = t or [] t = t or []
for index, value in enumerate(i): for index, value in enumerate(i):
@@ -41,7 +41,7 @@ def update_files(
i: List[bytes], i: List[bytes],
t: List[bytes], t: List[bytes],
db: Session, db: Session,
): ) -> None:
i = i or [] i = i or []
t = t or [] t = t or []
old = [f.id_ for f in data if f.id_] old = [f.id_ for f in data if f.id_]
+5 -7
View File
@@ -5,23 +5,21 @@ from sqlalchemy.orm import Session
from ..core.security import get_current_active_user as get_user from ..core.security import get_current_active_user as get_user
from ..db.session import SessionFuture from ..db.session import SessionFuture
from ..models.attendance import Attendance from ..models.attendance import Attendance
from ..schemas.settings import AttendanceCount
from ..schemas.user import UserToken from ..schemas.user import UserToken
router = APIRouter() router = APIRouter()
@router.post("") @router.post("", response_model=AttendanceCount)
def post_check_db(user: UserToken = Security(get_user)): def post_check_db(user: UserToken = Security(get_user)) -> AttendanceCount:
info = {}
with SessionFuture() as db: with SessionFuture() as db:
duplicate_attendances = get_duplicate_attendances(db) duplicate_attendances = get_duplicate_attendances(db)
if duplicate_attendances > 0: if duplicate_attendances > 0:
fix_duplicate_attendances(db) fix_duplicate_attendances(db)
info["attendanceCount"] = duplicate_attendances
db.commit() db.commit()
return info return AttendanceCount(attendanceCount=duplicate_attendances)
def get_duplicate_attendances(db: Session) -> int: def get_duplicate_attendances(db: Session) -> int:
@@ -37,7 +35,7 @@ def get_duplicate_attendances(db: Session) -> int:
select(func.count(Attendance.id)).where( select(func.count(Attendance.id)).where(
~Attendance.id.in_(sub_query), Attendance.is_valid == True # noqa: E712 ~Attendance.id.in_(sub_query), Attendance.is_valid == True # noqa: E712
) )
).scalar() ).scalar_one()
return query return query
+14 -14
View File
@@ -111,7 +111,7 @@ def show_blank(
@router.get("/list", response_model=List[schemas.Employee]) @router.get("/list", response_model=List[schemas.Employee])
async def show_list(user: UserToken = Depends(get_user)): async def show_list(user: UserToken = Depends(get_user)) -> List[schemas.Employee]:
with SessionFuture() as db: with SessionFuture() as db:
return [ return [
employee_info(item) employee_info(item)
@@ -127,25 +127,25 @@ async def show_list(user: UserToken = Depends(get_user)):
] ]
@router.get("/query") @router.get("/query", response_model=List[schemas.EmployeeLink])
async def show_term( async def show_term(
q: str, q: str,
c: int = None, c: int = None,
current_user: UserToken = Depends(get_user), current_user: UserToken = Depends(get_user),
): ) -> List[schemas.EmployeeLink]:
list_ = [] list_: List[schemas.EmployeeLink] = []
with SessionFuture() as db: with SessionFuture() as db:
for index, item in enumerate(Employee.query(q=q, type_=10, reconcilable=None, active=None, db=db)): for index, item in enumerate(Employee.query(q=q, type_=10, reconcilable=None, active=None, db=db)):
list_.append( list_.append(
{ schemas.EmployeeLink(
"id": item.id, id=item.id,
"name": item.name, name=item.name,
"designation": item.designation, designation=item.designation,
"costCentre": { costCentre=schemas.CostCentreLink(
"id": item.cost_centre.id, id=item.cost_centre.id,
"name": item.cost_centre.name, name=item.cost_centre.name,
}, ),
} )
) )
if c is not None and index == c - 1: if c is not None and index == c - 1:
break break
@@ -196,7 +196,7 @@ def employee_blank() -> schemas.EmployeeBlank:
) )
def delete_with_data(employee: Employee, db: Session): def delete_with_data(employee: Employee, db: Session) -> None:
suspense_account = db.execute(select(Account).where(Account.id == Account.suspense())).scalar_one() suspense_account = db.execute(select(Account).where(Account.id == Account.suspense())).scalar_one()
query = ( query = (
db.execute( db.execute(
@@ -49,7 +49,7 @@ def employee_attendance_report(
finish_date = datetime.strptime(f or get_finish_date(request.session), "%d-%b-%Y").date() finish_date = datetime.strptime(f or get_finish_date(request.session), "%d-%b-%Y").date()
start_date = employee.joining_date if employee.joining_date > start_date else start_date start_date = employee.joining_date if employee.joining_date > start_date else start_date
finish_date = ( finish_date = (
employee.leaving_date if not employee.is_active and employee.leaving_date < finish_date else finish_date employee.leaving_date if not employee.is_active and employee.leaving_date < finish_date else finish_date # type: ignore[assignment]
) )
info = schemas.EmployeeAttendance( info = schemas.EmployeeAttendance(
startDate=start_date, startDate=start_date,
+10 -10
View File
@@ -2,7 +2,7 @@ import uuid
from datetime import date, datetime from datetime import date, datetime
from math import ceil from math import ceil
from typing import List from typing import List, Tuple
import brewman.schemas.input as schema_in import brewman.schemas.input as schema_in
import brewman.schemas.voucher as output import brewman.schemas.voucher as output
@@ -93,7 +93,7 @@ def save_employee_benefits(
employee_benefits: List[EmployeeBenefitSchema], employee_benefits: List[EmployeeBenefitSchema],
days_in_month: int, days_in_month: int,
db: Session, db: Session,
): ) -> Tuple[int, int]:
total_exp, total_total = 0, 0 total_exp, total_total = 0, 0
for item in employee_benefits: for item in employee_benefits:
account = db.execute(select(Employee).where(Employee.id == item.employee.id_)).scalar_one() account = db.execute(select(Employee).where(Employee.id == item.employee.id_)).scalar_one()
@@ -125,7 +125,7 @@ def save_employee_benefits(
return total_exp, total_total return total_exp, total_total
def save_journals(voucher: Voucher, exp: int, total: int, db: Session): def save_journals(voucher: Voucher, exp: int, total: int, db: Session) -> None:
account = db.execute(select(AccountBase).where(AccountBase.id == AccountBase.esi_pf_expense())).scalar_one() account = db.execute(select(AccountBase).where(AccountBase.id == AccountBase.esi_pf_expense())).scalar_one()
journal = Journal( journal = Journal(
amount=exp, amount=exp,
@@ -154,7 +154,7 @@ def update_route(
i: List[bytes] = File(None), i: List[bytes] = File(None),
t: List[bytes] = File(None), t: List[bytes] = File(None),
user: UserToken = Security(get_user, scopes=["employee-benefit"]), user: UserToken = Security(get_user, scopes=["employee-benefit"]),
): ) -> output.Voucher:
try: try:
dt = get_last_day(data.date_) dt = get_last_day(data.date_)
days_in_month = dt.day days_in_month = dt.day
@@ -212,7 +212,7 @@ def update_employee_benefits(
employee_benefits: List[EmployeeBenefitSchema], employee_benefits: List[EmployeeBenefitSchema],
days_in_month: int, days_in_month: int,
db: Session, db: Session,
): ) -> Tuple[int, int]:
exp, total = 0, 0 exp, total = 0, 0
for i in range(len(voucher.employee_benefits), 0, -1): for i in range(len(voucher.employee_benefits), 0, -1):
item = voucher.employee_benefits[i - 1] item = voucher.employee_benefits[i - 1]
@@ -228,7 +228,7 @@ def update_employee_benefits(
return exp + new_exp, total + new_total return exp + new_exp, total + new_total
def update_journals(voucher: Voucher, exp: int, total: int): def update_journals(voucher: Voucher, exp: int, total: int) -> None:
journal = next(i for i in voucher.journals if i.account_id == AccountBase.esi_pf_expense()) journal = next(i for i in voucher.journals if i.account_id == AccountBase.esi_pf_expense())
journal.amount = exp journal.amount = exp
journal = next(i for i in voucher.journals if i.account_id == AccountBase.esi_pf_payable()) journal = next(i for i in voucher.journals if i.account_id == AccountBase.esi_pf_payable())
@@ -239,7 +239,7 @@ def update_journals(voucher: Voucher, exp: int, total: int):
def get_id( def get_id(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["employee-benefit"]), user: UserToken = Security(get_user, scopes=["employee-benefit"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one()
@@ -255,13 +255,13 @@ def get_id(
def show_blank( def show_blank(
request: Request, request: Request,
user: UserToken = Security(get_user, scopes=["employee-benefit"]), user: UserToken = Security(get_user, scopes=["employee-benefit"]),
): ) -> output.Voucher:
additional_info = BlankVoucherInfo(date=get_date(request.session), type=VoucherType.EMPLOYEE_BENEFIT) additional_info = BlankVoucherInfo(date=get_date(request.session), type=VoucherType.EMPLOYEE_BENEFIT)
with SessionFuture() as db: with SessionFuture() as db:
return blank_voucher(additional_info, db) return blank_voucher(additional_info, db)
def esi_contribution(gross_salary, days_worked, days_in_month): def esi_contribution(gross_salary: int, days_worked: int, days_in_month: int) -> Tuple[int, int, int]:
limit = 21000 limit = 21000
employee_rate = 0.0175 employee_rate = 0.0175
employer_rate = 0.0475 employer_rate = 0.0475
@@ -270,7 +270,7 @@ def esi_contribution(gross_salary, days_worked, days_in_month):
return employee, employer, employee + employer return employee, employer, employee + employer
def pf_contribution(gross_salary, days_worked, days_in_month): def pf_contribution(gross_salary: int, days_worked: int, days_in_month: int) -> Tuple[int, int, int]:
limit = 15000 limit = 15000
employee_rate = 0.12 employee_rate = 0.12
employer_rate = 0.12 + 0.011 + 0.005 + 0.0001 employer_rate = 0.12 + 0.011 + 0.005 + 0.0001
+22 -19
View File
@@ -1,8 +1,12 @@
import csv import csv
import io
import uuid import uuid
from datetime import date, datetime, time, timedelta from datetime import date, datetime, time, timedelta
from io import StringIO from io import StringIO
from typing import Dict, List, Tuple
import brewman.schemas.fingerprint as schemas
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
from sqlalchemy import bindparam, select from sqlalchemy import bindparam, select
@@ -20,20 +24,20 @@ from ..schemas.user import UserToken
router = APIRouter() router = APIRouter()
@router.post("") @router.post("", response_model=None)
def upload_prints( def upload_prints(
fingerprints: UploadFile = File(None), fingerprints: UploadFile = File(None),
user: UserToken = Depends(get_user), user: UserToken = Depends(get_user),
): ) -> None:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
start = date.today() - timedelta(days=90) start = date.today() - timedelta(days=90)
finish = date.today() + timedelta(days=7) finish = date.today() + timedelta(days=7)
employees = {} employees: Dict[int, uuid.UUID] = {}
for id_, code in db.execute(select(Employee.id, Employee.code)).all(): for id_, code in db.execute(select(Employee.id, Employee.code)).all():
employees[code] = id_ employees[code] = id_
file_data = read_file(fingerprints) file_data = read_file(fingerprints)
prints = [d for d in fp(file_data, employees) if start <= d["date"].date() <= finish] prints = [d for d in fp(file_data, employees) if start <= d.date <= finish]
paged_data = [prints[i : i + 100] for i in range(0, len(prints), 100)] paged_data = [prints[i : i + 100] for i in range(0, len(prints), 100)]
for i, page in enumerate(paged_data): for i, page in enumerate(paged_data):
print(f"Processing page {i} of {len(paged_data)}") print(f"Processing page {i} of {len(paged_data)}")
@@ -47,10 +51,9 @@ def upload_prints(
} }
) )
.on_conflict_do_nothing(), .on_conflict_do_nothing(),
page, [p.dict() for p in page],
) )
db.commit() db.commit()
return {}
except SQLAlchemyError as e: except SQLAlchemyError as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -58,7 +61,7 @@ def upload_prints(
) )
def read_file(input_file: UploadFile): def read_file(input_file: UploadFile) -> io.StringIO:
input_file.file.seek(0) input_file.file.seek(0)
output = bytearray() output = bytearray()
while 1: while 1:
@@ -77,24 +80,24 @@ def read_file(input_file: UploadFile):
return StringIO(output.decode(encoding)) return StringIO(output.decode(encoding))
def fp(file_data, employees): def fp(file_data: StringIO, employees: Dict[int, uuid.UUID]) -> List[schemas.Fingerprint]:
fingerprints = [] fingerprints: List[schemas.Fingerprint] = []
reader = csv.reader(file_data, delimiter="\t") reader = csv.reader(file_data, delimiter="\t")
header = next(reader, None) header = next(reader)
employee_column = 2 employee_column = 2
date_column = len(header) - 1 date_column = len(header) - 1
date_format = "%Y/%m/%d %H:%M:%S" if date_column == 6 else "%Y-%m-%d %H:%M:%S" date_format = "%Y/%m/%d %H:%M:%S" if date_column == 6 else "%Y-%m-%d %H:%M:%S"
for row in reader: for row in reader:
try: try:
employee_code = int(row[employee_column]) # EnNo employee_code = int(row[employee_column]) # EnNo
date_ = datetime.strptime(row[date_column], date_format) date_ = datetime.strptime(row[date_column], date_format).date()
if employee_code in employees.keys(): if employee_code in employees.keys():
fingerprints.append( fingerprints.append(
{ schemas.Fingerprint(
"id": uuid.uuid4(), id=uuid.uuid4(),
"employee_id": employees[employee_code], employee_id=employees[employee_code],
"date": date_, date=date_,
} )
) )
except ValueError: except ValueError:
continue continue
@@ -112,7 +115,7 @@ def fp(file_data, employees):
# return Fingerprint.__table__.insert().from_select([Fingerprint.id, Fingerprint.employee_id, Fingerprint.date], sel) # return Fingerprint.__table__.insert().from_select([Fingerprint.id, Fingerprint.employee_id, Fingerprint.date], sel)
def get_prints(employee_id: uuid.UUID, date_: date, db: Session): def get_prints(employee_id: uuid.UUID, date_: date, db: Session) -> Tuple[str, str, bool]:
prints = ( prints = (
db.execute( db.execute(
select(Fingerprint) select(Fingerprint)
@@ -136,7 +139,7 @@ def get_prints(employee_id: uuid.UUID, date_: date, db: Session):
last = item last = item
if len(prints) == 0: if len(prints) == 0:
hours_worked, full_day = "", None hours_worked, full_day = "", False
elif len(prints) == 2: elif len(prints) == 2:
time_worked = prints[1].date - prints[0].date time_worked = prints[1].date - prints[0].date
hours_worked, full_day = working_hours(time_worked) hours_worked, full_day = working_hours(time_worked)
@@ -152,7 +155,7 @@ def get_prints(employee_id: uuid.UUID, date_: date, db: Session):
) )
def working_hours(delta: timedelta): def working_hours(delta: timedelta) -> Tuple[str, bool]:
minutes = (delta.seconds // 60) % 60 minutes = (delta.seconds // 60) % 60
minutes = int(5 * round(float(minutes) / 5)) minutes = int(5 * round(float(minutes) / 5))
hours = delta.seconds // 3600 hours = delta.seconds // 3600
+10 -10
View File
@@ -40,7 +40,7 @@ def save_route(
request: Request, request: Request,
data: schema_in.IncentiveIn = Depends(schema_in.IncentiveIn.load_form), data: schema_in.IncentiveIn = Depends(schema_in.IncentiveIn.load_form),
user: UserToken = Security(get_user, scopes=["incentive"]), user: UserToken = Security(get_user, scopes=["incentive"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = save(data, user, db) item: Voucher = save(data, user, db)
@@ -91,7 +91,7 @@ def save_incentives(
employees: List[schema_in.IncentiveEmployee], employees: List[schema_in.IncentiveEmployee],
point_value: Decimal, point_value: Decimal,
db: Session, db: Session,
): ) -> None:
total_amount = 0 total_amount = 0
for item in employees: for item in employees:
item_amount = round(item.points * item.days_worked * point_value) item_amount = round(item.points * item.days_worked * point_value)
@@ -114,13 +114,13 @@ def save_incentives(
db.add(journal) db.add(journal)
@router.put("/{id_}") @router.put("/{id_}", response_model=output.Voucher)
def update_route( def update_route(
id_: uuid.UUID, id_: uuid.UUID,
request: Request, request: Request,
data: schema_in.IncentiveIn = Depends(schema_in.IncentiveIn.load_form), data: schema_in.IncentiveIn = Depends(schema_in.IncentiveIn.load_form),
user: UserToken = Security(get_user, scopes=["incentive"]), user: UserToken = Security(get_user, scopes=["incentive"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = update_voucher(id_, data, user, db) item: Voucher = update_voucher(id_, data, user, db)
@@ -173,7 +173,7 @@ def update_incentives(
employees: List[schema_in.IncentiveEmployee], employees: List[schema_in.IncentiveEmployee],
point_value: Decimal, point_value: Decimal,
db: Session, db: Session,
): ) -> None:
total_amount = 0 total_amount = 0
for item in voucher.incentives: for item in voucher.incentives:
employee = next(e for e in employees if e.employee_id == item.journal.account_id) employee = next(e for e in employees if e.employee_id == item.journal.account_id)
@@ -191,7 +191,7 @@ def update_incentives(
def get_id( def get_id(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["incentive"]), user: UserToken = Security(get_user, scopes=["incentive"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one()
@@ -208,7 +208,7 @@ def show_blank(
request: Request, request: Request,
d: str = None, d: str = None,
user: UserToken = Security(get_user, scopes=["incentive"]), user: UserToken = Security(get_user, scopes=["incentive"]),
): ) -> output.Voucher:
additional_info = BlankVoucherInfo(date=d or get_date(request.session), type=VoucherType.INCENTIVE) additional_info = BlankVoucherInfo(date=d or get_date(request.session), type=VoucherType.INCENTIVE)
with SessionFuture() as db: with SessionFuture() as db:
return blank_voucher(additional_info, db) return blank_voucher(additional_info, db)
@@ -260,7 +260,7 @@ def get_employees(
return details return details
def balance(date_: date, voucher_id: Optional[uuid.UUID], db: Session): def balance(date_: date, voucher_id: Optional[uuid.UUID], db: Session) -> Decimal:
amount = ( amount = (
select(func.sum(Journal.amount * Journal.debit)) select(func.sum(Journal.amount * Journal.debit))
.join(Journal.voucher) .join(Journal.voucher)
@@ -279,14 +279,14 @@ def balance(date_: date, voucher_id: Optional[uuid.UUID], db: Session):
if voucher_id is not None: if voucher_id is not None:
amount = amount.where(Voucher.id != voucher_id) amount = amount.where(Voucher.id != voucher_id)
result: Optional[Decimal] = db.execute(amount).scalar_one_or_none() result: Optional[Decimal] = db.execute(amount).scalar_one_or_none()
return 0 if result is None else result * -1 return Decimal(0) if result is None else result * -1
def check_if_employees_changed( def check_if_employees_changed(
json: List[IncentiveSchema], json: List[IncentiveSchema],
db: List[Employee], db: List[Employee],
voucher: Optional[List[Journal]], voucher: Optional[List[Journal]],
): ) -> None:
json_ids = set(x.employee_id for x in json) json_ids = set(x.employee_id for x in json)
db_ids = set(x.id for x in db) db_ids = set(x.id for x in db)
voucher_ids = ( voucher_ids = (
+6 -6
View File
@@ -49,7 +49,7 @@ def save_route(
i: List[bytes] = File(None), i: List[bytes] = File(None),
t: List[bytes] = File(None), t: List[bytes] = File(None),
user: UserToken = Security(get_user, scopes=["issue"]), user: UserToken = Security(get_user, scopes=["issue"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item, batch_consumed = save(data, user, db) item, batch_consumed = save(data, user, db)
@@ -155,7 +155,7 @@ def save_journals(
destination: schema_in.CostCentreLink, destination: schema_in.CostCentreLink,
amount: Decimal, amount: Decimal,
db: Session, db: Session,
): ) -> None:
s = Journal( s = Journal(
debit=-1, debit=-1,
account_id=AccountBase.all_purchases(), account_id=AccountBase.all_purchases(),
@@ -182,7 +182,7 @@ def update_route(
i: List[bytes] = File(None), i: List[bytes] = File(None),
t: List[bytes] = File(None), t: List[bytes] = File(None),
user: UserToken = Security(get_user, scopes=["issue"]), user: UserToken = Security(get_user, scopes=["issue"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item, batch_consumed = update_voucher(id_, data, user, db) item, batch_consumed = update_voucher(id_, data, user, db)
@@ -272,7 +272,7 @@ def update_inventories(
inventories: List[InventorySchema], inventories: List[InventorySchema],
batch_consumed: Optional[bool], batch_consumed: Optional[bool],
db: Session, db: Session,
): ) -> Decimal:
amount: Decimal = Decimal(0) amount: Decimal = Decimal(0)
for it in range(len(voucher.inventories), 0, -1): for it in range(len(voucher.inventories), 0, -1):
item = voucher.inventories[it - 1] item = voucher.inventories[it - 1]
@@ -331,7 +331,7 @@ def update_journals(
source: schema_in.CostCentreLink, source: schema_in.CostCentreLink,
destination: schema_in.CostCentreLink, destination: schema_in.CostCentreLink,
amount: Decimal, amount: Decimal,
): ) -> None:
for i in range(len(voucher.journals), 0, -1): for i in range(len(voucher.journals), 0, -1):
item = voucher.journals[i - 1] item = voucher.journals[i - 1]
if item.debit == -1: if item.debit == -1:
@@ -366,7 +366,7 @@ def refresh_voucher(id_: uuid.UUID, batch_id: uuid.UUID, db: Session) -> None:
def get_id( def get_id(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["issue"]), user: UserToken = Security(get_user, scopes=["issue"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one()
+3 -3
View File
@@ -37,7 +37,7 @@ def save_route(
i: List[bytes] = File(None), i: List[bytes] = File(None),
t: List[bytes] = File(None), t: List[bytes] = File(None),
user: UserToken = Security(get_user, scopes=["journal"]), user: UserToken = Security(get_user, scopes=["journal"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = save(data, user, db) item: Voucher = save(data, user, db)
@@ -98,7 +98,7 @@ def update_route(
i: List[bytes] = File(None), i: List[bytes] = File(None),
t: List[bytes] = File(None), t: List[bytes] = File(None),
user: UserToken = Security(get_user, scopes=["journal"]), user: UserToken = Security(get_user, scopes=["journal"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = update_voucher(id_, data, user, db) item: Voucher = update_voucher(id_, data, user, db)
@@ -175,7 +175,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.JournalIn, user: UserToken, d
def get_id( def get_id(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["journal"]), user: UserToken = Security(get_user, scopes=["journal"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one()
+2 -2
View File
@@ -53,7 +53,7 @@ def post(
def delete_route( def delete_route(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["lock-date"]), user: UserToken = Security(get_user, scopes=["lock-date"]),
): ) -> List[LockInformation]:
with SessionFuture() as db: with SessionFuture() as db:
db.execute(delete(DbSetting).where(DbSetting.id == id_)) db.execute(delete(DbSetting).where(DbSetting.id == id_))
db.commit() db.commit()
@@ -93,5 +93,5 @@ def get_info(db: Session) -> List[LockInformation]:
finish=LockDate(days=item["finish"]["days"], date=item["finish"]["date_"]), finish=LockDate(days=item["finish"]["days"], date=item["finish"]["date_"]),
index=item["index"], index=item["index"],
) )
for item in sorted(data, key=lambda d: d["index"], reverse=True) for item in sorted(data, key=lambda d: d["index"], reverse=True) # type: ignore[no-any-return]
] ]
+5 -4
View File
@@ -1,4 +1,5 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Union
from fastapi import ( from fastapi import (
APIRouter, APIRouter,
@@ -38,7 +39,7 @@ async def login_for_access_token(
form_data: OAuth2PasswordRequestForm = Depends(), form_data: OAuth2PasswordRequestForm = Depends(),
client_id: int = Cookie(None), client_id: int = Cookie(None),
otp: int = Form(None), otp: int = Form(None),
): ) -> Union[Token, JSONResponse]:
with SessionFuture() as db: with SessionFuture() as db:
user = authenticate_user(form_data.username, form_data.password, db) user = authenticate_user(form_data.username, form_data.password, db)
if not user: if not user:
@@ -99,11 +100,11 @@ async def login_for_access_token(
}, },
expires_delta=access_token_expires, expires_delta=access_token_expires,
) )
return {"access_token": access_token, "token_type": "bearer"} return Token(access_token=access_token, token_type="bearer")
@router.post("/refresh", response_model=Token) @router.post("/refresh", response_model=Token)
async def refresh_token(user: UserToken = Security(get_current_active_user)): async def refresh_token(user: UserToken = Security(get_current_active_user)) -> Token:
access_token_expires = timedelta(minutes=settings.JWT_TOKEN_EXPIRE_MINUTES) access_token_expires = timedelta(minutes=settings.JWT_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token( access_token = create_access_token(
data={ data={
@@ -115,4 +116,4 @@ async def refresh_token(user: UserToken = Security(get_current_active_user)):
}, },
expires_delta=access_token_expires, expires_delta=access_token_expires,
) )
return {"access_token": access_token, "token_type": "bearer"} return Token(access_token=access_token, token_type="bearer")
+8 -6
View File
@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import APIRouter, Security from fastapi import APIRouter, Security
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -16,7 +18,7 @@ router = APIRouter()
@router.get("", response_model=Maintenance) @router.get("", response_model=Maintenance)
def get_maintenance( def get_maintenance(
user: UserToken = Security(get_user), user: UserToken = Security(get_user),
): ) -> Maintenance:
with SessionFuture() as db: with SessionFuture() as db:
data = db.execute(select(DbSetting).where(DbSetting.name == "Maintenance")).scalars().one_or_none() data = db.execute(select(DbSetting).where(DbSetting.name == "Maintenance")).scalars().one_or_none()
return info(data, db) return info(data, db)
@@ -26,9 +28,9 @@ def get_maintenance(
def set_maintenance( def set_maintenance(
data: Maintenance, data: Maintenance,
user: UserToken = Security(get_user, scopes=["maintenance"]), user: UserToken = Security(get_user, scopes=["maintenance"]),
): ) -> Maintenance:
with SessionFuture() as db: with SessionFuture() as db:
maintenance = db.execute(select(DbSetting).where(DbSetting.name == "Maintenance")).scalars().one_or_none() maintenance: Optional[DbSetting] = db.execute(select(DbSetting).where(DbSetting.name == "Maintenance")).scalar_one_or_none()
if data.enabled is False and maintenance is not None: if data.enabled is False and maintenance is not None:
db.delete(maintenance) db.delete(maintenance)
maintenance = None maintenance = None
@@ -41,8 +43,8 @@ def set_maintenance(
return info(maintenance, db) return info(maintenance, db)
def info(data, db: Session): def info(data: Optional[DbSetting], db: Session) -> Maintenance:
if data is None: if data is None:
return {"enabled": False, "user": ""} return Maintenance(enabled=False, user="")
user = db.execute(select(User).where(User.id == data.data)).scalar_one() user = db.execute(select(User).where(User.id == data.data)).scalar_one()
return {"enabled": True, "user": user.name} return Maintenance(enabled=True, user=user.name)
+7 -7
View File
@@ -50,7 +50,7 @@ def save_route(
i: List[bytes] = File(None), i: List[bytes] = File(None),
t: List[bytes] = File(None), t: List[bytes] = File(None),
user: UserToken = Security(get_user, scopes=["purchase"]), user: UserToken = Security(get_user, scopes=["purchase"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = save(data, user, db) item: Voucher = save(data, user, db)
@@ -105,7 +105,7 @@ def save(data: schema_in.PurchaseIn, user: UserToken, db: Session) -> Voucher:
return voucher return voucher
def save_inventories(voucher: Voucher, vendor_id: uuid.UUID, inventories: List[InventorySchema], db: Session): def save_inventories(voucher: Voucher, vendor_id: uuid.UUID, inventories: List[InventorySchema], db: Session) -> None:
for item in inventories: for item in inventories:
sku: StockKeepingUnit = db.execute( sku: StockKeepingUnit = db.execute(
select(StockKeepingUnit).where(StockKeepingUnit.id == item.batch.sku.id_) select(StockKeepingUnit).where(StockKeepingUnit.id == item.batch.sku.id_)
@@ -141,7 +141,7 @@ def save_inventories(voucher: Voucher, vendor_id: uuid.UUID, inventories: List[I
db.add(inventory) db.add(inventory)
def save_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session): def save_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session) -> None:
vendor = db.execute(select(AccountBase).where(AccountBase.id == ven.id_)).scalar_one() vendor = db.execute(select(AccountBase).where(AccountBase.id == ven.id_)).scalar_one()
journals: Dict[uuid.UUID, Journal] = {} journals: Dict[uuid.UUID, Journal] = {}
amount = 0 amount = 0
@@ -181,7 +181,7 @@ def update_route(
i: List[bytes] = File(None), i: List[bytes] = File(None),
t: List[bytes] = File(None), t: List[bytes] = File(None),
user: UserToken = Security(get_user, scopes=["purchase"]), user: UserToken = Security(get_user, scopes=["purchase"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = update_voucher(id_, data, user, db) item: Voucher = update_voucher(id_, data, user, db)
@@ -236,7 +236,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.PurchaseIn, user: UserToken,
return voucher return voucher
def update_inventory(voucher: Voucher, vendor_id: uuid.UUID, inventories: List[InventorySchema], db: Session): def update_inventory(voucher: Voucher, vendor_id: uuid.UUID, inventories: List[InventorySchema], db: Session) -> None:
for it in range(len(voucher.inventories), 0, -1): for it in range(len(voucher.inventories), 0, -1):
item = voucher.inventories[it - 1] item = voucher.inventories[it - 1]
quantity_consumed = -1 * get_batch_quantity(item.batch_id, voucher.id, db) quantity_consumed = -1 * get_batch_quantity(item.batch_id, voucher.id, db)
@@ -296,7 +296,7 @@ def update_inventory(voucher: Voucher, vendor_id: uuid.UUID, inventories: List[I
save_inventories(voucher, vendor_id, inventories, db) save_inventories(voucher, vendor_id, inventories, db)
def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session): def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session) -> None:
vendor = db.execute(select(AccountBase).where(AccountBase.id == ven.id_)).scalar_one() vendor = db.execute(select(AccountBase).where(AccountBase.id == ven.id_)).scalar_one()
journals: Dict[uuid.UUID, Journal] = {} journals: Dict[uuid.UUID, Journal] = {}
amount = Decimal(0) amount = Decimal(0)
@@ -343,7 +343,7 @@ def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session):
def get_id( def get_id(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["purchase"]), user: UserToken = Security(get_user, scopes=["purchase"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one()
+7 -7
View File
@@ -46,7 +46,7 @@ def save_route(
i: List[bytes] = File(None), i: List[bytes] = File(None),
t: List[bytes] = File(None), t: List[bytes] = File(None),
user: UserToken = Security(get_user, scopes=["purchase-return"]), user: UserToken = Security(get_user, scopes=["purchase-return"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = save(data, user, db) item: Voucher = save(data, user, db)
@@ -101,7 +101,7 @@ def save(data: schema_in.PurchaseIn, user: UserToken, db: Session) -> Voucher:
return voucher return voucher
def save_inventories(voucher: Voucher, inventories: List[InventorySchema], db: Session): def save_inventories(voucher: Voucher, inventories: List[InventorySchema], db: Session) -> None:
for d_item in inventories: for d_item in inventories:
batch = db.execute(select(Batch).where(Batch.id == d_item.batch.id_)).scalar_one() batch = db.execute(select(Batch).where(Batch.id == d_item.batch.id_)).scalar_one()
@@ -130,7 +130,7 @@ def save_inventories(voucher: Voucher, inventories: List[InventorySchema], db: S
db.add(item) db.add(item)
def save_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session): def save_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session) -> None:
vendor = db.execute(select(AccountBase).where(AccountBase.id == ven.id_)).scalar_one() vendor = db.execute(select(AccountBase).where(AccountBase.id == ven.id_)).scalar_one()
journals: Dict[uuid.UUID, Journal] = {} journals: Dict[uuid.UUID, Journal] = {}
amount = 0 amount = 0
@@ -170,7 +170,7 @@ def update_route(
i: List[bytes] = File(None), i: List[bytes] = File(None),
t: List[bytes] = File(None), t: List[bytes] = File(None),
user: UserToken = Security(get_user, scopes=["purchase-return"]), user: UserToken = Security(get_user, scopes=["purchase-return"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = update_voucher(id_, data, user, db) item: Voucher = update_voucher(id_, data, user, db)
@@ -228,7 +228,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.PurchaseIn, user: UserToken,
return voucher return voucher
def update_inventory(voucher: Voucher, new_inventories: List[InventorySchema], db: Session): def update_inventory(voucher: Voucher, new_inventories: List[InventorySchema], db: Session) -> None:
for it in range(len(voucher.inventories), 0, -1): for it in range(len(voucher.inventories), 0, -1):
item = voucher.inventories[it - 1] item = voucher.inventories[it - 1]
batch = db.execute(select(Batch).where(Batch.id == item.batch_id)).scalar_one() batch = db.execute(select(Batch).where(Batch.id == item.batch_id)).scalar_one()
@@ -261,7 +261,7 @@ def update_inventory(voucher: Voucher, new_inventories: List[InventorySchema], d
save_inventories(voucher, new_inventories, db) save_inventories(voucher, new_inventories, db)
def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db): def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session) -> None:
vendor = db.execute(select(AccountBase).where(AccountBase.id == ven.id_)).scalar_one() vendor = db.execute(select(AccountBase).where(AccountBase.id == ven.id_)).scalar_one()
journals: Dict[uuid.UUID, Journal] = {} journals: Dict[uuid.UUID, Journal] = {}
amount = 0 amount = 0
@@ -308,7 +308,7 @@ def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db):
def get_id( def get_id(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["purchase-return"]), user: UserToken = Security(get_user, scopes=["purchase-return"]),
): ) -> output.Voucher:
try: try:
with SessionFuture() as db: with SessionFuture() as db:
item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() item: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one()
+1 -1
View File
@@ -94,7 +94,7 @@ async def update_route(
) )
def update_items(rate_contract: RateContract, items: List[RateContractItemSchema], db: Session): def update_items(rate_contract: RateContract, items: List[RateContractItemSchema], db: Session) -> None:
for it in range(len(rate_contract.items), 0, -1): for it in range(len(rate_contract.items), 0, -1):
item = rate_contract.items[it - 1] item = rate_contract.items[it - 1]
index = next((idx for (idx, d) in enumerate(items) if d.id_ == item.id), None) index = next((idx for (idx, d) in enumerate(items) if d.id_ == item.id), None)
+13 -14
View File
@@ -30,18 +30,18 @@ from ..schemas.user import UserToken
router = APIRouter() router = APIRouter()
@router.post("/{date_}") @router.post("/{date_}", response_model=None)
def rebase( def rebase(
date_: str, date_: str,
user: UserToken = Security(get_user, scopes=["rebase"]), user: UserToken = Security(get_user, scopes=["rebase"]),
): ) -> None:
with SessionFuture() as db: with SessionFuture() as db:
date_ = datetime.strptime(date_, "%d-%b-%Y") date_obj = datetime.strptime(date_, "%d-%b-%Y")
voucher_l = opening_accounts(date_, user.id_, db) voucher_l = opening_accounts(date_obj, user.id_, db)
voucher_b = opening_batches(date_, user.id_, db) voucher_b = opening_batches(date_obj, user.id_, db)
starred_vouchers = save_starred(date_, db) starred_vouchers = save_starred(date_obj, db)
db.flush() db.flush()
delete_data(date_, starred_vouchers, db) delete_data(date_obj, starred_vouchers, db)
db.add(voucher_l) db.add(voucher_l)
for j in voucher_l.journals: for j in voucher_l.journals:
db.add(j) db.add(j)
@@ -52,13 +52,12 @@ def rebase(
for i in voucher_b.inventories: for i in voucher_b.inventories:
db.add(i) db.add(i)
db.flush() db.flush()
cleanup_lint(date_, db) cleanup_lint(date_obj, db)
# request.dbsession.execute('RESET statement_timeout;') # request.dbsession.execute('RESET statement_timeout;')
db.commit() db.commit()
return {}
def save_starred(date_: date, db: Session): def save_starred(date_: date, db: Session) -> List[Voucher]:
accounts = [ accounts = [
i.id for i in db.execute(select(AccountBase.id).where(AccountBase.is_starred == True)).all() # noqa: E712 i.id for i in db.execute(select(AccountBase.id).where(AccountBase.is_starred == True)).all() # noqa: E712
] ]
@@ -105,7 +104,7 @@ def save_starred(date_: date, db: Session):
return vouchers return vouchers
def opening_accounts(date_: date, user_id: uuid.UUID, db: Session): def opening_accounts(date_: date, user_id: uuid.UUID, db: Session) -> Voucher:
running_total = 0 running_total = 0
sum_func = func.sum(Journal.signed_amount) sum_func = func.sum(Journal.signed_amount)
query = db.execute( query = db.execute(
@@ -152,7 +151,7 @@ def opening_accounts(date_: date, user_id: uuid.UUID, db: Session):
return voucher return voucher
def opening_batches(date_: date, user_id: uuid.UUID, db: Session): def opening_batches(date_: date, user_id: uuid.UUID, db: Session) -> Voucher:
total = 0 total = 0
sum_func = func.sum(Journal.debit * Inventory.quantity) sum_func = func.sum(Journal.debit * Inventory.quantity)
query = db.execute( query = db.execute(
@@ -205,7 +204,7 @@ def opening_batches(date_: date, user_id: uuid.UUID, db: Session):
return voucher return voucher
def delete_data(date_: date, vouchers: List[Voucher], db: Session): def delete_data(date_: date, vouchers: List[Voucher], db: Session) -> None:
sub_voucher = aliased(Voucher) sub_voucher = aliased(Voucher)
sub_query = select(sub_voucher.id).where(sub_voucher.date < date_).subquery() sub_query = select(sub_voucher.id).where(sub_voucher.date < date_).subquery()
@@ -225,7 +224,7 @@ def delete_data(date_: date, vouchers: List[Voucher], db: Session):
db.execute(delete(Voucher).where(Voucher.date < date_, ~Voucher.id.in_(vouchers))) db.execute(delete(Voucher).where(Voucher.date < date_, ~Voucher.id.in_(vouchers)))
def cleanup_lint(date_: date, db: Session): def cleanup_lint(date_: date, db: Session) -> None:
# Insert executes on the end so keep list of batches and journals # Insert executes on the end so keep list of batches and journals
db.execute(delete(Batch).where(~Batch.id.in_(select(distinct(Inventory.batch_id)).subquery()))) db.execute(delete(Batch).where(~Batch.id.in_(select(distinct(Inventory.batch_id)).subquery())))
db.execute(delete(Fingerprint).where(Fingerprint.date < date_)) db.execute(delete(Fingerprint).where(Fingerprint.date < date_))
+28 -29
View File
@@ -30,7 +30,6 @@ from .reports import report_finish_date, report_start_date
router = APIRouter() router = APIRouter()
# @router.post("/new") # "Recipes"
@router.post("", response_model=schemas.Recipe) @router.post("", response_model=schemas.Recipe)
def save( def save(
data: schemas.RecipeIn, data: schemas.RecipeIn,
@@ -90,15 +89,15 @@ def save(
recipe_cost += round(ingredient_cost * quantity, 2) recipe_cost += round(ingredient_cost * quantity, 2)
recipe.items.append(RecipeItem(None, product.id, quantity, ingredient_cost)) recipe.items.append(RecipeItem(None, product.id, quantity, ingredient_cost))
recipe.cost_price = round(recipe_cost, 2) recipe.cost_price = round(recipe_cost / recipe.recipe_yield, 2)
recipe_sku.cost_price = round(recipe.cost_price / recipe.recipe_yield, 2) recipe_sku.cost_price = round(recipe.cost_price / recipe.recipe_yield, 2)
if recipe_sku.product.is_sold: if recipe_sku.product.is_sold:
recipe_sku.sale_price = recipe.sale_price recipe_sku.sale_price = recipe.sale_price
db.add(recipe) db.add(recipe)
for item in recipe.items: for r_item in recipe.items:
item.recipe_id = recipe.id r_item.recipe_id = recipe.id
db.add(item) db.add(r_item)
seen_recipes: Set[uuid.UUID] = set() seen_recipes: Set[uuid.UUID] = set()
check_recursion(recipe, seen_recipes, db) check_recursion(recipe, seen_recipes, db)
@@ -177,9 +176,9 @@ async def update_route(
else: else:
recipe.items.remove(item) recipe.items.remove(item)
for item in data.items: for d_item in data.items:
product = db.execute(select(Product).where(Product.id == item.product.id_)).scalar_one() product = db.execute(select(Product).where(Product.id == d_item.product.id_)).scalar_one()
quantity = round(item.quantity, 2) quantity = round(d_item.quantity, 2)
if product.is_purchased: if product.is_purchased:
ingredient_cost = get_purchased_product_cost(product, data.valid_from, data.valid_till, db) ingredient_cost = get_purchased_product_cost(product, data.valid_from, data.valid_till, db)
else: else:
@@ -189,7 +188,7 @@ async def update_route(
recipe_cost += round(ingredient_cost * quantity, 2) recipe_cost += round(ingredient_cost * quantity, 2)
recipe.items.append(RecipeItem(None, product.id, quantity, ingredient_cost)) recipe.items.append(RecipeItem(None, product.id, quantity, ingredient_cost))
recipe.cost_price = recipe_cost recipe.cost_price = round(recipe_cost / recipe.recipe_yield, 2)
seen_recipes: Set[uuid.UUID] = set() seen_recipes: Set[uuid.UUID] = set()
check_recursion(recipe, seen_recipes, db) check_recursion(recipe, seen_recipes, db)
db.commit() db.commit()
@@ -249,11 +248,11 @@ def get_purchased_product_cost(product: Product, start_date: date, finish_date:
else: else:
for sku in skus: for sku in skus:
price.append(sku.cost_price / sku.fraction / sku.product_yield) price.append(sku.cost_price / sku.fraction / sku.product_yield)
return round(sum(price) / len(price), 5) return round(sum(price) / len(price), 5) # type: ignore[return-value]
def get_sub_product_cost(product: Product, start_date: date, finish_date: date, db: Session): def get_sub_product_cost(product: Product, start_date: date, finish_date: date, db: Session) -> Decimal:
recipe: Recipe = ( recipe: Optional[Recipe] = (
db.execute( db.execute(
select(Recipe) select(Recipe)
.join(Recipe.sku) .join(Recipe.sku)
@@ -273,57 +272,57 @@ def get_sub_product_cost(product: Product, start_date: date, finish_date: date,
detail=f"Ingredient {product.name} is not bought and also does not have a recipe for the period.", detail=f"Ingredient {product.name} is not bought and also does not have a recipe for the period.",
) )
return recipe.cost_price return round(recipe.cost_price / recipe.sku.fraction / recipe.sku.product_yield, 5)
def update_old_rows(product_id, valid_from: date, valid_till: date, db: Session): def update_old_rows(sku_id: uuid.UUID, valid_from: date, valid_till: date, db: Session) -> None:
old = ( old: List[Recipe] = (
db.execute( db.execute(
select(Recipe) select(Recipe)
.where( .where(
Recipe.product_id == product_id, Recipe.sku_id == sku_id,
Recipe.valid_from < valid_till, Recipe.valid_from < valid_till,
Recipe.valid_till > valid_from, Recipe.valid_till > valid_from,
) )
.order_by(Recipe.effective_from) .order_by(Recipe.valid_from)
) )
.scalars() .scalars()
.all() .all()
) )
new_recipes = [] new_recipes: List[Recipe] = []
for item in old: for item in old:
if item.valid_from < valid_from: if item.valid_from < valid_from:
recipe = Recipe( recipe = Recipe(
product_id=item.product_id, sku_id=item.sku_id,
quantity=item.quantity, recipe_yield=item.recipe_yield,
cost_price=item.cost_price, cost_price=item.cost_price,
sale_price=item.sale_price, sale_price=item.sale_price,
valid_from=item.valid_from, valid_from=item.valid_from,
valid_till=valid_from - timedelta(days=1), valid_till=valid_from - timedelta(days=1),
) )
for ri in item.recipe_items: for ri in item.items:
recipe.recipe_items.append(RecipeItem(None, ri.product_id, ri.quantity, ri.price)) recipe.items.append(RecipeItem(None, ri.product_id, ri.quantity, ri.price))
new_recipes.append(recipe) new_recipes.append(recipe)
if item.valid_till > valid_till: if item.valid_till > valid_till:
recipe = Recipe( recipe = Recipe(
product_id=item.product_id, sku_id=item.sku_id,
quantity=item.quantity, recipe_yield=item.recipe_yield,
cost_price=item.cost_price, cost_price=item.cost_price,
sale_price=item.sale_price, sale_price=item.sale_price,
valid_from=valid_till + timedelta(days=1), valid_from=valid_till + timedelta(days=1),
valid_till=item.valid_till, valid_till=item.valid_till,
) )
for ri in item.recipe_items: for ri in item.items:
recipe.recipe_items.append(RecipeItem(None, ri.product_id, ri.quantity, ri.price)) recipe.items.append(RecipeItem(None, ri.product_id, ri.quantity, ri.price))
new_recipes.append(recipe) new_recipes.append(recipe)
for recipe in new_recipes: for recipe in new_recipes:
db.add(recipe) db.add(recipe)
for item in recipe.recipe_items: for r_item in recipe.items:
item.recipe_id = recipe.id r_item.recipe_id = recipe.id
db.add(item) db.add(r_item)
@router.delete("/{id_}", response_model=schemas.RecipeBlank) @router.delete("/{id_}", response_model=schemas.RecipeBlank)
+52 -44
View File
@@ -1,5 +1,5 @@
from datetime import date, datetime from datetime import date, datetime
from typing import Dict, List from typing import List, Tuple
import brewman.schemas.cash_flow as schemas import brewman.schemas.cash_flow as schemas
@@ -31,52 +31,54 @@ def report_blank(
startDate=get_start_date(request.session), startDate=get_start_date(request.session),
finishDate=get_finish_date(request.session), finishDate=get_finish_date(request.session),
body=schemas.CashFlowBody(operating=[], investing=[], financing=[], details=[]), body=schemas.CashFlowBody(operating=[], investing=[], financing=[], details=[]),
footer=None, footer=[],
) )
@router.get("/data") @router.get("/data", response_model=schemas.CashFlow)
def report_data( def report_data(
request: Request, request: Request,
s: str, s: str,
f: str, f: str,
user: UserToken = Security(get_user, scopes=["cash-flow"]), user: UserToken = Security(get_user, scopes=["cash-flow"]),
): ) -> schemas.CashFlow:
with SessionFuture() as db: with SessionFuture() as db:
start_date = datetime.strptime(s, "%d-%b-%Y") start_date = datetime.strptime(s, "%d-%b-%Y")
finish_date = datetime.strptime(f, "%d-%b-%Y") finish_date = datetime.strptime(f, "%d-%b-%Y")
body, footer = build_report(start_date, finish_date, db) body, footer = build_report(start_date, finish_date, db)
set_period(s, f, request.session) set_period(s, f, request.session)
return { return schemas.CashFlow(
"startDate": s, startDate=s,
"finishDate": f, finishDate=f,
"body": body, body=body,
"footer": footer, footer=footer,
} )
@router.get("/{id_}") @router.get("/{id_}", response_model=schemas.CashFlow)
def report_id( def report_id(
id_: int, id_: int,
request: Request, request: Request,
s: str, s: str,
f: str, f: str,
user: UserToken = Security(get_user, scopes=["cash-flow"]), user: UserToken = Security(get_user, scopes=["cash-flow"]),
): ) -> schemas.CashFlow:
with SessionFuture() as db: with SessionFuture() as db:
start_date = datetime.strptime(s, "%d-%b-%Y") start_date = datetime.strptime(s, "%d-%b-%Y")
finish_date = datetime.strptime(f, "%d-%b-%Y") finish_date = datetime.strptime(f, "%d-%b-%Y")
details, footer = build_report_id(id_, start_date, finish_date, db) body, footer = build_report_id(id_, start_date, finish_date, db)
set_period(s, f, request.session) set_period(s, f, request.session)
return { return schemas.CashFlow(
"startDate": s, startDate=s,
"finishDate": f, finishDate=f,
"body": {"details": details}, body=body,
"footer": footer, footer=footer,
} )
def build_report(start_date: date, finish_date: date, db: Session): def build_report(
start_date: date, finish_date: date, db: Session
) -> Tuple[schemas.CashFlowBody, List[schemas.CashFlowItem]]:
sub_query = ( sub_query = (
select(Voucher.id) select(Voucher.id)
.join(Voucher.journals) .join(Voucher.journals)
@@ -102,15 +104,16 @@ def build_report(start_date: date, finish_date: date, db: Session):
).all() ).all()
total_amount = 0 total_amount = 0
cf: Dict[str, List] = {"operating": [], "investing": [], "financing": []} cf: schemas.CashFlowBody = schemas.CashFlowBody(operating=[], investing=[], financing=[], details=[])
dict_ = {"operating": cf.operating, "investing": cf.investing, "financing": cf.investing, "details": cf.details}
for account_type, amount in query: for account_type, amount in query:
total_amount += amount * -1 total_amount += amount * -1
cf[account_type.cash_flow_classification.lower()].append( dict_[account_type.cash_flow_classification.lower()].append(
{ schemas.CashFlowItem(
"name": account_type.name, name=account_type.name,
"url": ["/", "cash-flow", str(account_type.id)], url=["/", "cash-flow", str(account_type.id)],
"amount": amount * -1, amount=amount * -1,
} )
) )
opening = db.execute( opening = db.execute(
@@ -138,21 +141,26 @@ def build_report(start_date: date, finish_date: date, db: Session):
return ( return (
cf, cf,
[ [
{ schemas.CashFlowItem(
"name": "Net increase in cash and cash equivalents", name="Net increase in cash and cash equivalents",
"amount": total_amount, url=[],
}, amount=total_amount,
{ ),
"name": "Cash and cash equivalents at beginning of period", schemas.CashFlowItem(
"amount": opening, name="Cash and cash equivalents at beginning of period",
}, url=[],
{"name": "Cash and cash equivalents at end of period", "amount": closing}, amount=opening,
),
schemas.CashFlowItem(name="Cash and cash equivalents at end of period", url=[], amount=closing),
], ],
) )
def build_report_id(account_type: int, start_date: date, finish_date: date, db: Session): def build_report_id(
details = [] account_type: int, start_date: date, finish_date: date, db: Session
) -> Tuple[schemas.CashFlowBody, List[schemas.CashFlowItem]]:
cf: schemas.CashFlowBody = schemas.CashFlowBody(operating=[], investing=[], financing=[], details=[])
details = cf.details
sub_query = ( sub_query = (
select(Voucher.id) select(Voucher.id)
.join(Voucher.journals) .join(Voucher.journals)
@@ -177,11 +185,11 @@ def build_report_id(account_type: int, start_date: date, finish_date: date, db:
for account, amount in query: for account, amount in query:
total_amount += amount * -1 total_amount += amount * -1
details.append( details.append(
{ schemas.CashFlowItem(
"name": account.name, name=account.name,
"url": ["/", "ledger", str(account.id)], url=["/", "ledger", str(account.id)],
"amount": amount * -1, amount=amount * -1,
} )
) )
return details, [{"name": "total", "amount": total_amount}] return cf, [schemas.CashFlowItem(name="total", url=[], amount=total_amount)]
@@ -63,7 +63,7 @@ def delete_voucher(
date_: str, date_: str,
d: Optional[uuid.UUID] = None, d: Optional[uuid.UUID] = None,
user: UserToken = Security(get_user, scopes=["closing-stock"]), user: UserToken = Security(get_user, scopes=["closing-stock"]),
): ) -> None:
try: try:
cost_centre_id = d or CostCentre.cost_centre_purchase() cost_centre_id = d or CostCentre.cost_centre_purchase()
with SessionFuture() as db: with SessionFuture() as db:
@@ -210,7 +210,7 @@ def get_opening_stock(date_: date, db: Session) -> Decimal:
return Decimal(0) if opening_stock is None else opening_stock return Decimal(0) if opening_stock is None else opening_stock
def get_closing_stock(date_, db: Session) -> Decimal: def get_closing_stock(date_: date, db: Session) -> Decimal:
closing_stock: Optional[Decimal] = db.execute( closing_stock: Optional[Decimal] = db.execute(
select(func.sum(Inventory.quantity * Inventory.rate * (1 + Inventory.tax) * Journal.debit)) select(func.sum(Inventory.quantity * Inventory.rate * (1 + Inventory.tax) * Journal.debit))
.join(Journal.voucher) .join(Journal.voucher)
@@ -226,7 +226,7 @@ def save_route(
request: Request, request: Request,
data: schemas.ClosingStock, data: schemas.ClosingStock,
user: UserToken = Security(get_user, scopes=["closing-stock"]), user: UserToken = Security(get_user, scopes=["closing-stock"]),
): ) -> schemas.ClosingStock:
try: try:
departments = set(i.cost_centre.id_ for i in data.items if i.cost_centre is not None) departments = set(i.cost_centre.id_ for i in data.items if i.cost_centre is not None)
if data.cost_centre.id_ in departments: if data.cost_centre.id_ in departments:
@@ -265,7 +265,7 @@ def save_route(
items = [d for d in data.items if d.cost_centre is not None and d.cost_centre.id_ == dep] items = [d for d in data.items if d.cost_centre is not None and d.cost_centre.id_ == dep]
item = save(data.date_, items, user, db) item = save(data.date_, items, user, db)
save_inventories(item, items, db) save_inventories(item, items, db)
amount: Decimal = sum(i.amount for i in item.inventories) amount: Decimal = sum(i.amount for i in item.inventories) # type: ignore[assignment]
save_journals(item, data.cost_centre.id_, dep, amount, db) save_journals(item, data.cost_centre.id_, dep, amount, db)
check_journals_are_valid(item) check_journals_are_valid(item)
db.commit() db.commit()
@@ -278,7 +278,7 @@ def save_route(
) )
def save_cs(data: schemas.ClosingStock, db: Session): def save_cs(data: schemas.ClosingStock, db: Session) -> None:
for item in data.items: for item in data.items:
cs = ClosingStock( cs = ClosingStock(
date_=data.date_, cost_centre_id=data.cost_centre.id_, sku_id=item.product.id_, quantity=item.physical date_=data.date_, cost_centre_id=data.cost_centre.id_, sku_id=item.product.id_, quantity=item.physical
@@ -344,7 +344,7 @@ def save_journals(
destination: uuid.UUID, destination: uuid.UUID,
amount: Decimal, amount: Decimal,
db: Session, db: Session,
): ) -> None:
s = Journal(debit=-1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=source) s = Journal(debit=-1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=source)
d = Journal(debit=1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=destination) d = Journal(debit=1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=destination)
voucher.journals.append(s) voucher.journals.append(s)
@@ -353,7 +353,7 @@ def save_journals(
db.add(d) db.add(d)
def update_cs(date_: date, cost_centre_id: uuid.UUID, items: List[schemas.ClosingStockItem], db: Session): def update_cs(date_: date, cost_centre_id: uuid.UUID, items: List[schemas.ClosingStockItem], db: Session) -> None:
old = ( old = (
db.execute( db.execute(
select(ClosingStock).where(ClosingStock.date == date_, ClosingStock.cost_centre_id == cost_centre_id) select(ClosingStock).where(ClosingStock.date == date_, ClosingStock.cost_centre_id == cost_centre_id)
@@ -380,7 +380,7 @@ def update_cs(date_: date, cost_centre_id: uuid.UUID, items: List[schemas.Closin
db.add(cs) db.add(cs)
def delete_old_vouchers(date_: date, cost_centre_id: uuid.UUID, db: Session): def delete_old_vouchers(date_: date, cost_centre_id: uuid.UUID, db: Session) -> None:
vouchers = ( vouchers = (
db.execute(select(Voucher.id).where(Voucher.date == date_, Voucher.voucher_type == VoucherType.CLOSING_STOCK)) db.execute(select(Voucher.id).where(Voucher.date == date_, Voucher.voucher_type == VoucherType.CLOSING_STOCK))
.scalars() .scalars()
@@ -162,8 +162,8 @@ def opening_balance(
.group_by(StockKeepingUnit.units) .group_by(StockKeepingUnit.units)
).all() ).all()
quantity: Decimal = sum(r.quantity for r in row) quantity: Decimal = sum(r.quantity for r in row) # type: ignore[assignment]
amount: Decimal = sum(r.amount for r in row) amount: Decimal = sum(r.amount for r in row) # type: ignore[assignment]
return ( return (
quantity, quantity,
+75 -74
View File
@@ -1,7 +1,11 @@
import datetime
import uuid import uuid
from fastapi import APIRouter, Depends, Request, Security from datetime import date, datetime
from typing import List
import brewman.schemas.reconcile as schemas
from fastapi import APIRouter, Request, Security
from sqlalchemy import not_ from sqlalchemy import not_
from sqlalchemy.orm import Session, joinedload from sqlalchemy.orm import Session, joinedload
from sqlalchemy.sql.expression import and_, func, or_, select from sqlalchemy.sql.expression import and_, func, or_, select
@@ -19,42 +23,44 @@ from ...schemas.user import UserToken
router = APIRouter() router = APIRouter()
@router.get("") @router.get("", response_model=schemas.Reconcile)
def show_blank( def show_blank(
request: Request, request: Request,
user: UserToken = Security(get_user, scopes=["reconcile"]), user: UserToken = Security(get_user, scopes=["reconcile"]),
): ) -> schemas.Reconcile:
return { return schemas.Reconcile(
"startDate": get_start_date(request.session), startDate=get_start_date(request.session),
"finishDate": get_finish_date(request.session), finishDate=get_finish_date(request.session),
"account": None, account=None,
"body": [], body=[],
} )
@router.get("/{id_}") @router.get("/{id_}", response_model=schemas.Reconcile)
def show_data( def show_data(
id_: uuid.UUID, id_: uuid.UUID,
request: Request, request: Request,
s: str = None, s: str = None,
f: str = None, f: str = None,
user: UserToken = Security(get_user, scopes=["reconcile"]), user: UserToken = Security(get_user, scopes=["reconcile"]),
): ) -> schemas.Reconcile:
with SessionFuture() as db: with SessionFuture() as db:
account = db.execute(select(AccountBase).where(AccountBase.id == id_)).scalar_one() account = db.execute(select(AccountBase).where(AccountBase.id == id_)).scalar_one()
start_date = s if s is not None else get_start_date(request.session) start_date = datetime.strptime(s or get_start_date(request.session), "%d-%b-%Y")
finish_date = f if f is not None else get_finish_date(request.session) finish_date = datetime.strptime(f or get_finish_date(request.session), "%d-%b-%Y")
body = build_report(account.id, start_date, finish_date, db) body = build_report(account.id, start_date, finish_date, db)
set_period(start_date, finish_date, request.session) set_period(start_date, finish_date, request.session)
return { return schemas.Reconcile(
"startDate": start_date, startDate=start_date,
"finishDate": finish_date, finishDate=finish_date,
"account": {"id": account.id, "name": account.name}, account=schemas.AccountLink(id=account.id, name=account.name),
"body": body, body=body,
} )
def build_report(account_id, start_date, finish_date, db): def build_report(
account_id: uuid.UUID, start_date: date, finish_date: date, db: Session
) -> List[schemas.ReconcileItem]:
opening = opening_balance(account_id, start_date, db) opening = opening_balance(account_id, start_date, db)
body = [opening] body = [opening]
@@ -66,8 +72,8 @@ def build_report(account_id, start_date, finish_date, db):
or_( or_(
Voucher.is_reconciled == False, # noqa: E712 Voucher.is_reconciled == False, # noqa: E712
and_( and_(
Voucher.reconcile_date >= datetime.datetime.strptime(start_date, "%d-%b-%Y"), Voucher.reconcile_date >= start_date,
Voucher.reconcile_date <= datetime.datetime.strptime(finish_date, "%d-%b-%Y"), Voucher.reconcile_date <= finish_date,
), ),
), ),
not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])),
@@ -94,27 +100,27 @@ def build_report(account_id, start_date, finish_date, db):
name += "{0} / ".format(journal.account.name) name += "{0} / ".format(journal.account.name)
name = name[:-3] name = name[:-3]
body.append( body.append(
{ schemas.ReconcileItem(
"id": voucher.id, id=voucher.id,
"date": voucher.date.strftime("%d-%b-%Y"), date=voucher.date,
"name": name, name=name,
"type": voucher.voucher_type.name.replace("_", " ").title(), type=voucher.voucher_type.name.replace("_", " ").title(),
"narration": voucher.narration, narration=voucher.narration,
"debit": debit, debit=debit,
"credit": credit, credit=credit,
"isReconciled": voucher.is_reconciled, isReconciled=voucher.is_reconciled,
"reconcileDate": voucher.reconcile_date.strftime("%d-%b-%Y"), reconcileDate=voucher.reconcile_date,
} )
) )
return body return body
def opening_balance(account_id: uuid.UUID, start_date, db: Session): def opening_balance(account_id: uuid.UUID, start_date: date, db: Session) -> schemas.ReconcileItem:
opening = db.execute( opening = db.execute(
select(func.sum(Journal.amount * Journal.debit)) select(func.sum(Journal.amount * Journal.debit))
.join(Journal.voucher) .join(Journal.voucher)
.where( .where(
Voucher.reconcile_date < datetime.datetime.strptime(start_date, "%d-%b-%Y"), Voucher.reconcile_date < start_date,
Voucher.is_reconciled == True, # noqa: E712 Voucher.is_reconciled == True, # noqa: E712
not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])),
Journal.account_id == account_id, Journal.account_id == account_id,
@@ -127,51 +133,46 @@ def opening_balance(account_id: uuid.UUID, start_date, db: Session):
else: else:
debit = opening debit = opening
credit = 0 credit = 0
return { return schemas.ReconcileItem(
"date": start_date, date=start_date,
"id": None, id=None,
"name": "Opening Balance", name="Opening Balance",
"type": "Opening Balance", type="Opening Balance",
"narration": "", narration="",
"debit": debit, debit=debit,
"credit": credit, credit=credit,
"running": opening, running=opening,
"isReconciled": True, isReconciled=True,
"reconcileDate": start_date, reconcileDate=start_date,
} )
@router.post("/{id_}") @router.post("/{id_}", response_model=schemas.Reconcile)
def save( def save(
id_: uuid.UUID, id_: uuid.UUID,
data: schemas.Reconcile,
request: Request, request: Request,
s: str = None, s: str = None,
f: str = None, f: str = None,
user: UserToken = Security(get_user, scopes=["reconcile"]), user: UserToken = Security(get_user, scopes=["reconcile"]),
): ) -> schemas.Reconcile:
with SessionFuture() as db: with SessionFuture() as db:
account = db.execute(select(AccountBase).where(AccountBase.id == id_)).scalar_one() account = db.execute(select(AccountBase).where(AccountBase.id == id_)).scalar_one()
start_date = s if s is not None else get_start_date(request.session) start_date = datetime.strptime(s or get_start_date(request.session), "%d-%b-%Y")
finish_date = f if f is not None else get_finish_date(request.session) finish_date = datetime.strptime(f or get_finish_date(request.session), "%d-%b-%Y")
raise Exception("not fixed") for item in data.body:
# for item in request.json_body["body"]: if item.id_ is None:
# if "id" not in item or item["id"] is None: continue
# continue
# voucher: Voucher = db.execute(select(Voucher).where(Voucher.id == item.id_)).scalar_one()
# voucher = ( voucher.is_reconciled = item.is_reconciled
# request.dbsession.query(Voucher) if item.reconcile_date is not None:
# .where(Voucher.id == uuid.UUID(item["id"])) voucher.reconcile_date = item.reconcile_date
# .first() db.commit()
# ) body = build_report(account.id, start_date, finish_date, db)
# is_reconciled = item["isReconciled"] return schemas.Reconcile(
# reconcile_date = datetime.datetime.strptime(item["reconcileDate"], "%d-%b-%Y") startDate=start_date,
# voucher.is_reconciled = is_reconciled finishDate=finish_date,
# voucher.reconcile_date = reconcile_date account=schemas.AccountLink(id=account.id, name=account.name),
# transaction.commit() body=body,
# body = build_report(account.id, start_date, finish_date, request) )
# return {
# "startDate": start_date,
# "finishDate": finish_date,
# "account": {"id": account.id, "name": account.name},
# "body": body
# }
+5 -5
View File
@@ -106,11 +106,11 @@ def add_roles(user: User, roles: List[schemas.RoleItem], db: Session) -> None:
user.roles.remove(ug) user.roles.remove(ug)
@router.delete("/{id_}") @router.delete("/{id_}", response_model=None)
def delete_route( def delete_route(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["users"]), user: UserToken = Security(get_user, scopes=["users"]),
): ) -> None:
if id_ == user.id_: if id_ == user.id_:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED, status_code=status.HTTP_501_NOT_IMPLEMENTED,
@@ -154,11 +154,11 @@ async def show_list(
] ]
@router.get("/active") @router.get("/active", response_model=List[schemas.UserBlank])
async def show_active(user: UserToken = Depends(get_user)): async def show_active(user: UserToken = Depends(get_user)) -> List[schemas.UserBlank]:
with SessionFuture() as db: with SessionFuture() as db:
return [ return [
{"name": name} schemas.UserBlank(name=name)
for name in db.execute(select(User.name).where(User.locked_out == False).order_by(User.name)) # noqa: E712 for name in db.execute(select(User.name).where(User.locked_out == False).order_by(User.name)) # noqa: E712
.scalars() .scalars()
.all() .all()
+1 -1
View File
@@ -92,7 +92,7 @@ def check_delete_permissions(voucher: Voucher, user: UserToken) -> None:
def delete_voucher( def delete_voucher(
id_: uuid.UUID, id_: uuid.UUID,
user: UserToken = Security(get_user), user: UserToken = Security(get_user),
): ) -> output.Voucher:
with SessionFuture() as db: with SessionFuture() as db:
voucher: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() voucher: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one()
images = db.execute(select(DbImage).where(DbImage.resource_id == voucher.id)).scalars().all() images = db.execute(select(DbImage).where(DbImage.resource_id == voucher.id)).scalars().all()
+8
View File
@@ -0,0 +1,8 @@
from decimal import Decimal
from pydantic import BaseModel
class AccountBalance(BaseModel):
date: Decimal
total: Decimal
@@ -21,7 +21,7 @@ class BlankVoucherInfo(BaseModel):
json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")}
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
+1 -1
View File
@@ -33,7 +33,7 @@ class CashFlow(BaseModel):
start_date: date start_date: date
finish_date: date finish_date: date
body: CashFlowBody body: CashFlowBody
footer: Optional[List[CashFlowItem]] footer: List[CashFlowItem]
class Config: class Config:
anystr_strip_whitespace = True anystr_strip_whitespace = True
+3 -3
View File
@@ -43,13 +43,13 @@ class ClosingStock(BaseModel):
json_encoders = {date: lambda v: v.strftime("%d-%b-%Y"), datetime: lambda v: v.strftime("%d-%b-%Y %H:%M")} json_encoders = {date: lambda v: v.strftime("%d-%b-%Y"), datetime: lambda v: v.strftime("%d-%b-%Y %H:%M")}
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
@validator("creation_date", pre=True) @validator("creation_date", pre=True)
def parse_creation_date(cls, value): def parse_creation_date(cls, value) -> Optional[datetime]:
if value is None: if value is None:
return None return None
if isinstance(value, datetime): if isinstance(value, datetime):
@@ -57,7 +57,7 @@ class ClosingStock(BaseModel):
return datetime.strptime(value, "%d-%b-%Y %H:%M") return datetime.strptime(value, "%d-%b-%Y %H:%M")
@validator("last_edit_date", pre=True) @validator("last_edit_date", pre=True)
def parse_last_edit_date(cls, value): def parse_last_edit_date(cls, value) -> Optional[datetime]:
if value is None: if value is None:
return None return None
if isinstance(value, datetime): if isinstance(value, datetime):
+11 -11
View File
@@ -30,13 +30,13 @@ class JournalIn(VoucherIn):
} }
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
@classmethod @classmethod
def load_form(cls, data: str = Form(...)): def load_form(cls, data: str = Form(...)) -> BaseModel:
json_data = json.loads(data) json_data = json.loads(data)
return cls.parse_obj(json_data) return cls.parse_obj(json_data)
@@ -54,13 +54,13 @@ class PurchaseIn(VoucherIn):
} }
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
@classmethod @classmethod
def load_form(cls, data: str = Form(...)): def load_form(cls, data: str = Form(...)) -> BaseModel:
json_data = json.loads(data) json_data = json.loads(data)
return cls.parse_obj(json_data) return cls.parse_obj(json_data)
@@ -79,19 +79,19 @@ class IssueIn(VoucherIn):
} }
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
@validator("destination") # For Purchase, Issue and Return Vouchers @validator("destination") # For Purchase, Issue and Return Vouchers
def source_destination_unique(cls, value: CostCentreLink, values): def source_destination_unique(cls, value: CostCentreLink, values) -> CostCentreLink:
if value.id_ == values["source"].id_: if value.id_ == values["source"].id_:
raise ValueError("Source and destination cannot be the same") raise ValueError("Source and destination cannot be the same")
return value return value
@classmethod @classmethod
def load_form(cls, data: str = Form(...)): def load_form(cls, data: str = Form(...)) -> BaseModel:
json_data = json.loads(data) json_data = json.loads(data)
return cls.parse_obj(json_data) return cls.parse_obj(json_data)
@@ -108,13 +108,13 @@ class EmployeeBenefitIn(VoucherIn):
} }
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
@classmethod @classmethod
def load_form(cls, data: str = Form(...)): def load_form(cls, data: str = Form(...)) -> BaseModel:
json_data = json.loads(data) json_data = json.loads(data)
return cls.parse_obj(json_data) return cls.parse_obj(json_data)
@@ -131,13 +131,13 @@ class IncentiveIn(VoucherIn):
} }
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
@classmethod @classmethod
def load_form(cls, data: str = Form(...)): def load_form(cls, data: str = Form(...)) -> BaseModel:
json_data = json.loads(data) json_data = json.loads(data)
return cls.parse_obj(json_data) return cls.parse_obj(json_data)
+5
View File
@@ -0,0 +1,5 @@
from pydantic.main import BaseModel
class Message(BaseModel):
message: str
+6 -36
View File
@@ -28,29 +28,17 @@ class RateContractIn(BaseModel):
} }
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
@validator("valid_from", pre=True)
def parse_creation_date(cls, value):
if isinstance(value, date):
return value
return datetime.strptime(value, "%d-%b-%Y")
@validator("valid_till", pre=True)
def parse_last_edit_date(cls, value):
if isinstance(value, date):
return value
return datetime.strptime(value, "%d-%b-%Y")
class RateContract(RateContractIn): class RateContract(RateContractIn):
id_: uuid.UUID id_: uuid.UUID
creation_date: Optional[datetime] creation_date: datetime
last_edit_date: Optional[datetime] last_edit_date: datetime
user: Optional[UserLink] user: UserLink
class Config: class Config:
anystr_strip_whitespace = True anystr_strip_whitespace = True
@@ -60,32 +48,14 @@ class RateContract(RateContractIn):
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I"), datetime: lambda v: v.strftime("%d-%b-%Y %H:%I"),
} }
# @validator("date_", pre=True)
# def parse_date(cls, value):
# if isinstance(value, date):
# return value
# return datetime.strptime(value, "%d-%b-%Y").date()
#
# @validator("valid_from", pre=True)
# def parse_creation_date(cls, value):
# if isinstance(value, datetime):
# return value
# return datetime.strptime(value, "%d-%b-%Y %H:%M")
#
# @validator("valid_till", pre=True)
# def parse_last_edit_date(cls, value):
# if isinstance(value, datetime):
# return value
# return datetime.strptime(value, "%d-%b-%Y %H:%M")
@validator("creation_date", pre=True) @validator("creation_date", pre=True)
def parse_creation_date(cls, value): def parse_creation_date(cls, value) -> datetime:
if isinstance(value, datetime): if isinstance(value, datetime):
return value return value
return datetime.strptime(value, "%d-%b-%Y %H:%M") return datetime.strptime(value, "%d-%b-%Y %H:%M")
@validator("last_edit_date", pre=True) @validator("last_edit_date", pre=True)
def parse_last_edit_date(cls, value): def parse_last_edit_date(cls, value) -> datetime:
if isinstance(value, datetime): if isinstance(value, datetime):
return value return value
return datetime.strptime(value, "%d-%b-%Y %H:%M") return datetime.strptime(value, "%d-%b-%Y %H:%M")
+2 -2
View File
@@ -30,13 +30,13 @@ class RecipeIn(BaseModel):
json_encoders = {date: lambda v: v.strftime("%d-%b-%Y") if v is not None else None} json_encoders = {date: lambda v: v.strftime("%d-%b-%Y") if v is not None else None}
@validator("valid_from", pre=True) @validator("valid_from", pre=True)
def parse_valid_from(cls, value): def parse_valid_from(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
@validator("valid_till", pre=True) @validator("valid_till", pre=True)
def parse_valid_till(cls, value): def parse_valid_till(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
+68
View File
@@ -0,0 +1,68 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from typing import List, Optional
from pydantic import validator
from pydantic.main import BaseModel
from . import to_camel
from .account import AccountLink
class ReconcileItem(BaseModel):
id_: Optional[uuid.UUID]
date_: date
name: str
url: List[str]
type_: str
narration: str
debit: Decimal
credit: Decimal
posted: bool
is_reconciled: bool
reconcile_date: Optional[date]
@validator("date_", pre=True)
def parse_date(cls, value):
if isinstance(value, date):
return value
return datetime.strptime(value, "%d-%b-%Y").date()
@validator("reconcile_date", pre=True)
def parse_reconcile_date(cls, value):
if value is None:
return None
if isinstance(value, date):
return value
return datetime.strptime(value, "%d-%b-%Y").date()
class Config:
anystr_strip_whitespace = True
alias_generator = to_camel
json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")}
class Reconcile(BaseModel):
start_date: date
finish_date: date
account: Optional[AccountLink]
body: List[ReconcileItem]
class Config:
anystr_strip_whitespace = True
alias_generator = to_camel
json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")}
@validator("start_date", pre=True)
def parse_start_date(cls, value):
if isinstance(value, date):
return value
return datetime.strptime(value, "%d-%b-%Y").date()
@validator("finish_date", pre=True)
def parse_finish_date(cls, value):
if isinstance(value, date):
return value
return datetime.strptime(value, "%d-%b-%Y").date()
+8 -1
View File
@@ -82,4 +82,11 @@ class LockInformation(BaseModel):
class Maintenance(BaseModel): class Maintenance(BaseModel):
enabled: bool enabled: bool
user: Optional[str] user: str
class AttendanceCount(BaseModel):
attendance_count: int
class Config:
alias_generator = to_camel
+5 -5
View File
@@ -30,7 +30,7 @@ class VoucherIn(BaseModel):
files: List[ImageUpload] files: List[ImageUpload]
@classmethod @classmethod
def load_form(cls, data: str = Form(...)): def load_form(cls, data: str = Form(...)) -> BaseModel:
json_data = json.loads(data) json_data = json.loads(data)
return cls.parse_obj(json_data) return cls.parse_obj(json_data)
@@ -63,13 +63,13 @@ class Voucher(VoucherIn):
} }
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value) -> date:
if isinstance(value, date): if isinstance(value, date):
return value return value
return datetime.strptime(value, "%d-%b-%Y").date() return datetime.strptime(value, "%d-%b-%Y").date()
@validator("creation_date", pre=True) @validator("creation_date", pre=True)
def parse_creation_date(cls, value): def parse_creation_date(cls, value) -> Optional[date]:
if value is None or value == "": if value is None or value == "":
return None return None
if isinstance(value, datetime): if isinstance(value, datetime):
@@ -77,7 +77,7 @@ class Voucher(VoucherIn):
return datetime.strptime(value, "%d-%b-%Y %H:%M") return datetime.strptime(value, "%d-%b-%Y %H:%M")
@validator("last_edit_date", pre=True) @validator("last_edit_date", pre=True)
def parse_last_edit_date(cls, value): def parse_last_edit_date(cls, value) -> Optional[date]:
if value is None or value == "": if value is None or value == "":
return None return None
if isinstance(value, datetime): if isinstance(value, datetime):
@@ -85,7 +85,7 @@ class Voucher(VoucherIn):
return datetime.strptime(value, "%d-%b-%Y %H:%M") return datetime.strptime(value, "%d-%b-%Y %H:%M")
@validator("reconcile_date", pre=True) @validator("reconcile_date", pre=True)
def parse_reconcile_date(cls, value): def parse_reconcile_date(cls, value) -> Optional[date]:
if value is None or value == "": if value is None or value == "":
return None return None
elif isinstance(value, date): elif isinstance(value, date):
+2 -1
View File
@@ -10,7 +10,7 @@ export class CashFlow {
details: CashFlowItem[]; details: CashFlowItem[];
}; };
footer?: CashFlowItem[]; footer: CashFlowItem[];
public constructor(init?: Partial<CashFlow>) { public constructor(init?: Partial<CashFlow>) {
this.startDate = ''; this.startDate = '';
@@ -21,6 +21,7 @@ export class CashFlow {
financing: [], financing: [],
details: [], details: [],
}; };
this.footer = [];
Object.assign(this, init); Object.assign(this, init);
} }