Blacked and isorted all files
This commit is contained in:
tanshu committed 2020-10-07 21:29:42 +05:30
1 parent 40f1f59f9d
commit cb5f52fcc7
71 files changed
+1395 -865

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
from brewman.main import init from brewman.main import init
init() init()
+2 -1
View File
@@ -1,7 +1,8 @@
from dotenv import load_dotenv
import secrets import secrets
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from dotenv import load_dotenv
from pydantic import BaseSettings, PostgresDsn, validator from pydantic import BaseSettings, PostgresDsn, validator
+20 -9
View File
@@ -1,23 +1,25 @@
import uuid import uuid
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Optional from typing import List, Optional
from jwt import PyJWTError
from fastapi import Depends, HTTPException, status, Security from fastapi import Depends, HTTPException, Security, status
from fastapi.security import OAuth2PasswordBearer, SecurityScopes from fastapi.security import OAuth2PasswordBearer, SecurityScopes
from pydantic import BaseModel, ValidationError
from sqlalchemy.orm import Session
from jose import jwt from jose import jwt
from jose.exceptions import ExpiredSignatureError from jose.exceptions import ExpiredSignatureError
from jwt import PyJWTError
from pydantic import BaseModel, ValidationError
from sqlalchemy.orm import Session
from brewman.core.config import settings from ..core.config import settings
from brewman.models.auth import User as UserModel, Client
from ..db.session import SessionLocal from ..db.session import SessionLocal
from ..models.auth import Client
from ..models.auth import User as UserModel
# to get a string like this run: # to get a string like this run:
from ..schemas.auth import UserToken from ..schemas.auth import UserToken
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token", scopes={}) oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token", scopes={})
@@ -58,7 +60,13 @@ def create_access_token(*, data: dict, expires_delta: timedelta = None):
def get_user(username: str, id_: str, locked_out: bool, scopes: List[str]) -> UserToken: def get_user(username: str, id_: str, locked_out: bool, scopes: List[str]) -> UserToken:
return UserToken(id_=uuid.UUID(id_), name=username, locked_out=locked_out, password="", permissions=scopes,) return UserToken(
id_=uuid.UUID(id_),
name=username,
locked_out=locked_out,
password="",
permissions=scopes,
)
def authenticate_user( def authenticate_user(
@@ -86,7 +94,10 @@ def client_allowed(user: UserModel, client_id: int, otp: Optional[int] = None, d
return False, client.code return False, client.code
async def get_current_user(security_scopes: SecurityScopes, token: str = Depends(oauth2_scheme),) -> UserToken: async def get_current_user(
security_scopes: SecurityScopes,
token: str = Depends(oauth2_scheme),
) -> UserToken:
if security_scopes.scopes: if security_scopes.scopes:
authenticate_value = f'Bearer scope="{security_scopes.scope_str}"' authenticate_value = f'Bearer scope="{security_scopes.scope_str}"'
else: else:
+16 -17
View File
@@ -1,31 +1,30 @@
# Import all the models, so that Base has them before being # Import all the models, so that Base has them before being
# imported by Alembic # imported by Alembic
from brewman.db.base_class import Base # noqa from brewman.db.base_class import Base # noqa
from brewman.models import Account # noqa
from brewman.models import ( from brewman.models import (
Client,
user_role,
role_permission,
User,
LoginHistory,
Role,
Permission,
Product,
AttendanceType,
CostCentre,
Employee,
Account,
AccountBase, AccountBase,
AccountType, AccountType,
ProductGroup,
Recipe,
RecipeItem,
Attendance, Attendance,
AttendanceType,
Batch, Batch,
Client,
CostCentre,
Employee,
EmployeeBenefit,
Fingerprint, Fingerprint,
Inventory, Inventory,
Journal, Journal,
LoginHistory,
Permission,
Product, Product,
EmployeeBenefit, ProductGroup,
Recipe,
RecipeItem,
Role,
User,
Voucher, Voucher,
VoucherType, VoucherType,
) # noqa role_permission,
user_role,
)
+1
View File
@@ -1,6 +1,7 @@
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import MetaData from sqlalchemy.schema import MetaData
# Recommended naming convention used by Alembic, as various different database # Recommended naming convention used by Alembic, as various different database
# providers will autogenerate vastly different names making migrations more # providers will autogenerate vastly different names making migrations more
# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html # difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html
+5 -3
View File
@@ -1,8 +1,8 @@
from sqlalchemy.orm import Session
from app import crud, schemas from app import crud, schemas
from brewman.core.config import settings from brewman.core.config import settings
from brewman.db import base # noqa: F401 from brewman.db import base # noqa: F401
from sqlalchemy.orm import Session
# make sure all SQL Alchemy models are imported (app.db.base) before initializing DB # make sure all SQL Alchemy models are imported (app.db.base) before initializing DB
# otherwise, SQL Alchemy might fail to initialize relationships properly # otherwise, SQL Alchemy might fail to initialize relationships properly
@@ -18,6 +18,8 @@ def init_db(db: Session) -> None:
user = crud.user.get_by_email(db, email=settings.FIRST_SUPERUSER) user = crud.user.get_by_email(db, email=settings.FIRST_SUPERUSER)
if not user: if not user:
user_in = schemas.UserCreate( user_in = schemas.UserCreate(
email=settings.FIRST_SUPERUSER, password=settings.FIRST_SUPERUSER_PASSWORD, is_superuser=True, email=settings.FIRST_SUPERUSER,
password=settings.FIRST_SUPERUSER_PASSWORD,
is_superuser=True,
) )
user = crud.user.create(db, obj_in=user_in) # noqa: F841 user = crud.user.create(db, obj_in=user_in) # noqa: F841
+3 -1
View File
@@ -1,8 +1,10 @@
import logging import logging
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from brewman.core.config import settings 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)
+14 -13
View File
@@ -1,13 +1,17 @@
import uvicorn import uvicorn
from fastapi import FastAPI from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware from starlette.middleware.sessions import SessionMiddleware
from .core.config import settings
from .db.base_class import Base
from .db.session import engine
from .routers import ( from .routers import (
account, account,
account_types, account_types,
attendance,
attendance_report, attendance_report,
attendance_types, attendance_types,
attendance,
batch, batch,
cost_centre, cost_centre,
credit_salary, credit_salary,
@@ -20,29 +24,29 @@ from .routers import (
incentive, incentive,
issue, issue,
issue_grid, issue_grid,
journal,
lock_information, lock_information,
login,
maintenance, maintenance,
product, product,
product_group, product_group,
rebase,
reset_stock,
recipe,
login,
journal,
purchase, purchase,
purchase_return, purchase_return,
rebase,
recipe,
reset_stock,
voucher, voucher,
) )
from .routers.auth import client, user, role from .routers.auth import client, role, user
from .routers.reports import ( from .routers.reports import (
ledger,
balance_sheet, balance_sheet,
profit_loss,
closing_stock,
cash_flow, cash_flow,
closing_stock,
daybook, daybook,
ledger,
net_transactions, net_transactions,
product_ledger, product_ledger,
profit_loss,
purchase_entries, purchase_entries,
purchases, purchases,
raw_material_cost, raw_material_cost,
@@ -52,9 +56,6 @@ from .routers.reports import (
unposted, unposted,
) )
from .db.base_class import Base
from .core.config import settings
from .db.session import engine
Base.metadata.create_all(bind=engine) Base.metadata.create_all(bind=engine)
+9 -9
View File
@@ -1,20 +1,20 @@
from .auth import ( from .auth import (
Client, Client,
user_role,
role_permission,
User,
LoginHistory, LoginHistory,
Role,
Permission, Permission,
Role,
User,
role_permission,
user_role,
) )
from .master import ( from .master import (
Product,
AttendanceType,
CostCentre,
Employee,
Account, Account,
AccountBase, AccountBase,
AccountType, AccountType,
AttendanceType,
CostCentre,
Employee,
Product,
ProductGroup, ProductGroup,
Recipe, Recipe,
RecipeItem, RecipeItem,
@@ -22,11 +22,11 @@ from .master import (
from .voucher import ( from .voucher import (
Attendance, Attendance,
Batch, Batch,
EmployeeBenefit,
Fingerprint, Fingerprint,
Inventory, Inventory,
Journal, Journal,
Product, Product,
EmployeeBenefit,
Voucher, Voucher,
VoucherType, VoucherType,
) )
+13 -6
View File
@@ -1,14 +1,15 @@
import random import random
import string import string
import uuid import uuid
from hashlib import md5
from datetime import datetime from datetime import datetime
from hashlib import md5
from sqlalchemy.schema import ForeignKey, Table from sqlalchemy import Boolean, Column, DateTime, Integer, Unicode, UniqueConstraint
from sqlalchemy import Column, Boolean, Unicode, Integer, DateTime, UniqueConstraint
from sqlalchemy.orm import synonym, relationship, Session
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Session, relationship, synonym
from sqlalchemy.schema import ForeignKey, Table
from .meta import Base from .meta import Base
@@ -29,7 +30,13 @@ class Client(Base):
login_history = relationship("LoginHistory", backref="client") login_history = relationship("LoginHistory", backref="client")
def __init__( def __init__(
self, code=None, name=None, enabled=False, otp=None, creation_date=None, id_=None, self,
code=None,
name=None,
enabled=False,
otp=None,
creation_date=None,
id_=None,
): ):
self.code = code self.code = code
self.name = name self.name = name
+25 -12
View File
@@ -1,21 +1,22 @@
import uuid import uuid
from datetime import date from datetime import date
from sqlalchemy import ( from sqlalchemy import (
UniqueConstraint,
Column,
Integer,
Unicode,
Numeric,
Boolean, Boolean,
ForeignKey, Column,
func,
PickleType,
Date, Date,
ForeignKey,
Integer,
Numeric,
PickleType,
Unicode,
UniqueConstraint,
func,
) )
from sqlalchemy.orm import relationship, Session
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Session, relationship
from .meta import Base from .meta import Base
@@ -30,7 +31,12 @@ class Product(Base):
fraction = Column("fraction", Numeric, nullable=False) fraction = Column("fraction", Numeric, nullable=False)
fraction_units = Column("fraction_units", Unicode(255), nullable=False) fraction_units = Column("fraction_units", Unicode(255), nullable=False)
product_yield = Column("product_yield", Numeric, nullable=False) product_yield = Column("product_yield", Numeric, nullable=False)
product_group_id = Column("product_group_id", UUID(as_uuid=True), ForeignKey("product_groups.id"), nullable=False,) product_group_id = Column(
"product_group_id",
UUID(as_uuid=True),
ForeignKey("product_groups.id"),
nullable=False,
)
account_id = Column("account_id", UUID(as_uuid=True), ForeignKey("accounts.id"), nullable=False) account_id = Column("account_id", UUID(as_uuid=True), ForeignKey("accounts.id"), nullable=False)
price = Column("cost_price", Numeric, nullable=False) price = Column("cost_price", Numeric, nullable=False)
sale_price = Column("sale_price", Numeric, nullable=False) sale_price = Column("sale_price", Numeric, nullable=False)
@@ -461,7 +467,14 @@ class AttendanceType:
class AccountType: class AccountType:
def __init__( def __init__(
self, id_, name, balance_sheet=None, debit=None, cash_flow_classification=None, order=None, show_in_list=None, self,
id_,
name,
balance_sheet=None,
debit=None,
cash_flow_classification=None,
order=None,
show_in_list=None,
): ):
self.id = id_ self.id = id_
self.name = name self.name = name
+1
View File
@@ -1,6 +1,7 @@
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import MetaData from sqlalchemy.schema import MetaData
# Recommended naming convention used by Alembic, as various different database # Recommended naming convention used by Alembic, as various different database
# providers will autogenerate vastly different names making migrations more # providers will autogenerate vastly different names making migrations more
# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html # difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html
+11 -5
View File
@@ -1,6 +1,5 @@
from fastapi import HTTPException, status
from brewman.models.master import CostCentre from brewman.models.master import CostCentre
from fastapi import HTTPException, status
def validate(voucher): def validate(voucher):
@@ -24,7 +23,8 @@ def validate(voucher):
def check_batch_insert(voucher): def check_batch_insert(voucher):
if voucher.type == 9: if voucher.type == 9:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_410_GONE, detail="Verification Vouchers have been disabled", status_code=status.HTTP_410_GONE,
detail="Verification Vouchers have been disabled",
) )
if voucher.type == 6: if voucher.type == 6:
# Purchase Return # Purchase Return
@@ -58,7 +58,10 @@ def check_batch_insert(voucher):
def issue_new(voucher): def issue_new(voucher):
consuming = filter(lambda x: x.cost_centre_id == CostCentre.cost_centre_purchase(), voucher.journals,) consuming = filter(
lambda x: x.cost_centre_id == CostCentre.cost_centre_purchase(),
voucher.journals,
)
if not len(consuming): if not len(consuming):
consuming = False consuming = False
elif consuming[0].debit == 1: elif consuming[0].debit == 1:
@@ -79,7 +82,10 @@ def issue_new(voucher):
def issue_update(voucher): def issue_update(voucher):
consuming = filter(lambda x: x.cost_centre_id == CostCentre.cost_centre_purchase(), voucher.journals,) consuming = filter(
lambda x: x.cost_centre_id == CostCentre.cost_centre_purchase(),
voucher.journals,
)
if not len(consuming): if not len(consuming):
consuming = False consuming = False
elif consuming[0].debit == 1: elif consuming[0].debit == 1:
+2 -1
View File
@@ -1,4 +1,5 @@
from datetime import timedelta, tzinfo, datetime from datetime import datetime, timedelta, tzinfo
ZERO = timedelta(0) ZERO = timedelta(0)
HOUR = timedelta(hours=1) HOUR = timedelta(hours=1)
+73 -26
View File
@@ -1,23 +1,23 @@
import uuid import uuid
from datetime import datetime from datetime import datetime
from sqlalchemy import (
Column,
Integer,
Boolean,
Unicode,
DateTime,
Numeric,
ForeignKey,
UniqueConstraint,
Date,
)
from sqlalchemy.dialects.postgresql import BYTEA
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship, synonym, backref, Session
from sqlalchemy.dialects.postgresql import UUID
from brewman.models.master import Product from brewman.models.master import Product
from sqlalchemy import (
Boolean,
Column,
Date,
DateTime,
ForeignKey,
Integer,
Numeric,
Unicode,
UniqueConstraint,
)
from sqlalchemy.dialects.postgresql import BYTEA, UUID
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import Session, backref, relationship, synonym
from .meta import Base from .meta import Base
@@ -80,16 +80,30 @@ class Voucher(Base):
poster = relationship("User", primaryjoin="User.id==Voucher.poster_id", cascade=None) poster = relationship("User", primaryjoin="User.id==Voucher.poster_id", cascade=None)
journals = relationship( journals = relationship(
"Journal", back_populates="voucher", cascade="delete, delete-orphan", cascade_backrefs=False, "Journal",
back_populates="voucher",
cascade="delete, delete-orphan",
cascade_backrefs=False,
) )
inventories = relationship( inventories = relationship(
"Inventory", back_populates="voucher", cascade="delete, delete-orphan", cascade_backrefs=False, "Inventory",
back_populates="voucher",
cascade="delete, delete-orphan",
cascade_backrefs=False,
) )
employee_benefits = relationship( employee_benefits = relationship(
"EmployeeBenefit", backref="voucher", cascade="delete, delete-orphan", cascade_backrefs=False, "EmployeeBenefit",
backref="voucher",
cascade="delete, delete-orphan",
cascade_backrefs=False,
)
incentives = relationship(
"Incentive",
backref="voucher",
cascade="delete, delete-orphan",
cascade_backrefs=False,
) )
incentives = relationship("Incentive", backref="voucher", cascade="delete, delete-orphan", cascade_backrefs=False,)
def _get_type(self): def _get_type(self):
return self._type return self._type
@@ -155,7 +169,13 @@ class Journal(Base):
return self.name return self.name
def __init__( def __init__(
self, id_=None, debit=None, amount=None, voucher_id=None, account_id=None, cost_centre_id=None, self,
id_=None,
debit=None,
amount=None,
voucher_id=None,
account_id=None,
cost_centre_id=None,
): ):
self.id = id_ self.id = id_
self.debit = debit self.debit = debit
@@ -178,7 +198,10 @@ class EmployeeBenefit(Base):
pf_er = Column("pf_employer", Integer) pf_er = Column("pf_employer", Integer)
journal = relationship( journal = relationship(
Journal, backref=backref("employee_benefit", uselist=False), cascade=None, cascade_backrefs=False, Journal,
backref=backref("employee_benefit", uselist=False),
cascade=None,
cascade_backrefs=False,
) )
def __init__( def __init__(
@@ -216,10 +239,21 @@ class Incentive(Base):
days_worked = Column("days_worked", Numeric(precision=5, scale=1), nullable=False) days_worked = Column("days_worked", Numeric(precision=5, scale=1), nullable=False)
points = Column("points", Numeric(precision=5, scale=2), nullable=False) points = Column("points", Numeric(precision=5, scale=2), nullable=False)
journal = relationship(Journal, backref=backref("incentive", uselist=False), cascade=None, cascade_backrefs=False,) journal = relationship(
Journal,
backref=backref("incentive", uselist=False),
cascade=None,
cascade_backrefs=False,
)
def __init__( def __init__(
self, id_=None, voucher_id=None, journal_id=None, journal=None, days_worked=None, points=None, self,
id_=None,
voucher_id=None,
journal_id=None,
journal=None,
days_worked=None,
points=None,
): ):
self.id = id_ self.id = id_
self.voucher_id = voucher_id self.voucher_id = voucher_id
@@ -292,7 +326,14 @@ class Batch(Base):
inventories = relationship("Inventory", backref="batch", cascade=None, cascade_backrefs=False) inventories = relationship("Inventory", backref="batch", cascade=None, cascade_backrefs=False)
def __init__( def __init__(
self, name=None, product_id=None, quantity_remaining=None, rate=None, tax=None, discount=None, product=None, self,
name=None,
product_id=None,
quantity_remaining=None,
rate=None,
tax=None,
discount=None,
product=None,
): ):
self.name = name self.name = name
self.product_id = product_id self.product_id = product_id
@@ -397,7 +438,13 @@ class DbImage(Base):
creation_date = Column("creation_date", DateTime(timezone=True), nullable=False) creation_date = Column("creation_date", DateTime(timezone=True), nullable=False)
def __init__( def __init__(
self, resource_id=None, resource_type=None, image=None, thumbnail=None, creation_date=None, id_=None, self,
resource_id=None,
resource_type=None,
image=None,
thumbnail=None,
creation_date=None,
id_=None,
): ):
self.resource_id = resource_id self.resource_id = resource_id
self.resource_type = resource_type self.resource_type = resource_type
+4 -3
View File
@@ -1,16 +1,17 @@
import re import re
import uuid import uuid
from datetime import date, timedelta from datetime import date, timedelta
from decimal import Decimal from decimal import Decimal
from io import BytesIO from io import BytesIO
from typing import Optional from typing import Optional
from fastapi import APIRouter
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from brewman.models.master import DbSetting from ..models.master import DbSetting
from brewman.models.voucher import DbImage from ..models.voucher import DbImage
from fastapi import APIRouter
router = APIRouter() router = APIRouter()
+42 -19
View File
@@ -1,18 +1,21 @@
import uuid import uuid
from typing import List, Optional
from datetime import datetime
from fastapi import APIRouter, HTTPException, status, Depends, Security from datetime import datetime
from typing import List, Optional
import brewman.schemas.master as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import func from sqlalchemy import func
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import joinedload_all, Session from sqlalchemy.orm import Session, joinedload_all
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from ..models.master import CostCentre, Account, AccountType, AccountBase from ..models.master import Account, AccountBase, AccountType, CostCentre
from ..models.voucher import Voucher, Journal, VoucherType from ..models.voucher import Journal, Voucher, VoucherType
import brewman.schemas.master as schemas from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -28,7 +31,9 @@ def get_db() -> Session:
@router.post("", response_model=schemas.Account) @router.post("", response_model=schemas.Account)
def save( def save(
data: schemas.AccountIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["accounts"]), data: schemas.AccountIn,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["accounts"]),
): ):
try: try:
item = Account( item = Account(
@@ -44,7 +49,8 @@ def save(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -62,7 +68,8 @@ def update(
item: Account = db.query(Account).filter(Account.id == id_).first() item: Account = db.query(Account).filter(Account.id == id_).first()
if item.is_fixture: if item.is_fixture:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_423_LOCKED, detail=f"{item.name} is a fixture and cannot be edited or deleted.", status_code=status.HTTP_423_LOCKED,
detail=f"{item.name} is a fixture and cannot be edited or deleted.",
) )
if not item.type == data.type: if not item.type == data.type:
item.code = Account.get_code(data.type, db) item.code = Account.get_code(data.type, db)
@@ -77,7 +84,8 @@ def update(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -86,7 +94,9 @@ def update(
@router.delete("/{id_}") @router.delete("/{id_}")
def delete( def delete(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["accounts"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["accounts"]),
): ):
account: Account = db.query(Account).filter(Account.id == id_).first() account: Account = db.query(Account).filter(Account.id == id_).first()
can_delete, reason = account.can_delete("advanced-delete" in user.permissions) can_delete, reason = account.can_delete("advanced-delete" in user.permissions)
@@ -97,13 +107,15 @@ def delete(
else: else:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Cannot delete account because {reason}", status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Cannot delete account because {reason}",
) )
@router.get("") @router.get("")
def show_blank( def show_blank(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["accounts"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["accounts"]),
): ):
return account_info(None) return account_info(None)
@@ -147,7 +159,10 @@ async def show_term(
@router.get("/{id_}/balance") @router.get("/{id_}/balance")
async def show_balance( async def show_balance(
id_: uuid.UUID, d: str = None, db: Session = Depends(get_db), user: UserToken = Depends(get_user), id_: uuid.UUID,
d: str = None,
db: Session = Depends(get_db),
user: UserToken = Depends(get_user),
): ):
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")
return {"date": balance(id_, date, db), "total": balance(id_, None, db)} return {"date": balance(id_, date, db), "total": balance(id_, None, db)}
@@ -155,7 +170,9 @@ async def show_balance(
@router.get("/{id_}") @router.get("/{id_}")
def show_id( def show_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["accounts"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["accounts"]),
): ):
item: Account = db.query(Account).filter(Account.id == id_).first() item: Account = db.query(Account).filter(Account.id == id_).first()
return account_info(item) return account_info(item)
@@ -194,7 +211,10 @@ def account_info(item: Optional[Account]):
"isReconcilable": item.is_reconcilable, "isReconcilable": item.is_reconcilable,
"isStarred": item.is_starred, "isStarred": item.is_starred,
"isFixture": item.is_fixture, "isFixture": item.is_fixture,
"costCentre": {"id": item.cost_centre_id, "name": item.cost_centre.name,}, "costCentre": {
"id": item.cost_centre_id,
"name": item.cost_centre.name,
},
} }
@@ -231,6 +251,9 @@ def delete_with_data(account: Account, db: Session):
sus_jnl.amount = abs(amount) sus_jnl.amount = abs(amount)
sus_jnl.debit = -1 if amount < 0 else 1 sus_jnl.debit = -1 if amount < 0 else 1
voucher.narration += f"\nDeleted \u20B9{acc_jnl.amount * acc_jnl.debit:,.2f} of {account.name}" voucher.narration += f"\nDeleted \u20B9{acc_jnl.amount * acc_jnl.debit:,.2f} of {account.name}"
if voucher.type in (VoucherType.by_name("Payment").id, VoucherType.by_name("Receipt").id,): if voucher.type in (
VoucherType.by_name("Payment").id,
VoucherType.by_name("Receipt").id,
):
voucher.type = VoucherType.by_name("Journal") voucher.type = VoucherType.by_name("Journal")
db.delete(account) db.delete(account)
+6 -3
View File
@@ -1,10 +1,13 @@
from typing import List from typing import List
import brewman.schemas.master as schemas
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user from ..core.security import get_current_active_user as get_user
import brewman.schemas.master as schemas from ..models.master import AccountType
from brewman.models.master import AccountType from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
+20 -8
View File
@@ -1,17 +1,20 @@
from datetime import datetime, date, timedelta from datetime import date, datetime, timedelta
from fastapi import APIRouter, HTTPException, status, Depends, Security, Request import brewman.schemas.voucher as schemas
from fastapi import APIRouter, Depends, HTTPException, Request, Security, status
from sqlalchemy import or_ from sqlalchemy import or_
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user from ..core.security import get_current_active_user as get_user
from ..core.session import get_date, set_date
from ..db.session import SessionLocal from ..db.session import SessionLocal
from ..models.master import Employee from ..models.master import Employee
from ..models.voucher import Attendance from ..models.voucher import Attendance
from ..routers.fingerprint import get_prints from ..routers.fingerprint import get_prints
from ..core.session import get_date, set_date from ..schemas.auth import UserToken
import brewman.schemas.voucher as schemas
router = APIRouter() router = APIRouter()
@@ -49,7 +52,12 @@ def attendance_date_report(date_: date, db: Session):
employees = ( employees = (
db.query(Employee) db.query(Employee)
.filter(Employee.joining_date <= date_) .filter(Employee.joining_date <= date_)
.filter(or_(Employee.is_active, Employee.leaving_date >= date_,)) .filter(
or_(
Employee.is_active,
Employee.leaving_date >= date_,
)
)
.order_by(Employee.cost_centre_id) .order_by(Employee.cost_centre_id)
.order_by(Employee.designation) .order_by(Employee.designation)
.order_by(Employee.name) .order_by(Employee.name)
@@ -94,7 +102,10 @@ def save(
for item in data.body: for item in data.body:
if item.attendance_type.id_ != 0: if item.attendance_type.id_ != 0:
attendance = Attendance( attendance = Attendance(
employee_id=item.id_, date=att_date, attendance_type=item.attendance_type.id_, user_id=user.id_, employee_id=item.id_,
date=att_date,
attendance_type=item.attendance_type.id_,
user_id=user.id_,
) )
attendance.create(db) attendance.create(db)
db.commit() db.commit()
@@ -102,7 +113,8 @@ def save(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
+9 -3
View File
@@ -1,15 +1,18 @@
import csv import csv
from datetime import datetime, date
import io import io
from datetime import date, datetime
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from sqlalchemy import or_ from sqlalchemy import or_
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..db.session import SessionLocal
from ..models.master import AttendanceType, Employee from ..models.master import AttendanceType, Employee
from ..models.voucher import Attendance from ..models.voucher import Attendance
from .attendance import date_range from .attendance import date_range
from ..db.session import SessionLocal
router = APIRouter() router = APIRouter()
@@ -33,7 +36,10 @@ def get_report(
try: try:
output = io.StringIO() output = io.StringIO()
attendance_record( attendance_record(
datetime.strptime(s, "%d-%b-%Y"), datetime.strptime(f, "%d-%b-%Y"), output, db, datetime.strptime(s, "%d-%b-%Y"),
datetime.strptime(f, "%d-%b-%Y"),
output,
db,
) )
headers = {"Content-Disposition": "attachment; filename = 'attendance-record.csv'"} headers = {"Content-Disposition": "attachment; filename = 'attendance-record.csv'"}
output.seek(0) output.seek(0)
+4 -2
View File
@@ -1,7 +1,9 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user from ..core.security import get_current_active_user as get_user
from brewman.models.master import AttendanceType from ..models.master import AttendanceType
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
+17 -8
View File
@@ -1,15 +1,17 @@
import uuid import uuid
from fastapi import APIRouter, HTTPException, status, Depends, Security import brewman.schemas.auth as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import desc from sqlalchemy import desc
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ...schemas.auth import UserToken
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 SessionLocal from ...db.session import SessionLocal
from ...models.auth import Client, LoginHistory from ...models.auth import Client, LoginHistory
import brewman.schemas.auth as schemas from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -41,7 +43,8 @@ def update(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -50,7 +53,9 @@ def update(
@router.delete("/{id_}") @router.delete("/{id_}")
def delete( def delete(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["clients"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["clients"]),
): ):
try: try:
item: Client = db.query(Client).filter(Client.id == id_).first() item: Client = db.query(Client).filter(Client.id == id_).first()
@@ -61,7 +66,8 @@ def delete(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -70,7 +76,8 @@ def delete(
@router.get("/list") @router.get("/list")
async def show_list( async def show_list(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["clients"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["clients"]),
): ):
list_ = db.query(Client).order_by(Client.name).all() list_ = db.query(Client).order_by(Client.name).all()
clients = [] clients = []
@@ -95,7 +102,9 @@ async def show_list(
@router.get("/{id_}") @router.get("/{id_}")
def show_id( def show_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["clients"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["clients"]),
): ):
item: Client = db.query(Client).filter(Client.id == id_).first() item: Client = db.query(Client).filter(Client.id == id_).first()
return { return {
+33 -14
View File
@@ -1,15 +1,18 @@
import uuid import uuid
from typing import List, Optional from typing import List, Optional
from fastapi import APIRouter, HTTPException, status, Depends, Security import brewman.schemas.auth as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ...schemas.auth import UserToken
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 SessionLocal from ...db.session import SessionLocal
from ...models.auth import Role, Permission from ...models.auth import Permission, Role
import brewman.schemas.auth as schemas from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -25,7 +28,9 @@ def get_db():
@router.post("", response_model=schemas.Role) @router.post("", response_model=schemas.Role)
def save( def save(
data: schemas.RoleIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), data: schemas.RoleIn,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
try: try:
item = Role(data.name) item = Role(data.name)
@@ -36,7 +41,8 @@ def save(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -59,7 +65,8 @@ def update(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -78,17 +85,21 @@ def add_permissions(role: Role, permissions: List[schemas.PermissionItem], db):
@router.delete("/{id_}") @router.delete("/{id_}")
def delete( def delete(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
try: try:
item: Role = db.query(Role).filter(Role.id == id_).first() item: Role = db.query(Role).filter(Role.id == id_).first()
if item is None: if item is None:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Role not found", status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Role not found",
) )
else: else:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED, detail="Role deletion not implemented", status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail="Role deletion not implemented",
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -97,14 +108,16 @@ def delete(
@router.get("") @router.get("")
def show_blank( def show_blank(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
return role_info(None, db) return role_info(None, db)
@router.get("/list", response_model=List[schemas.RoleList]) @router.get("/list", response_model=List[schemas.RoleList])
async def show_list( async def show_list(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
return [ return [
{ {
@@ -118,7 +131,9 @@ async def show_list(
@router.get("/{id_}", response_model=schemas.Role) @router.get("/{id_}", response_model=schemas.Role)
def show_id( def show_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
item: Role = db.query(Role).filter(Role.id == id_).first() item: Role = db.query(Role).filter(Role.id == id_).first()
return role_info(item, db) return role_info(item, db)
@@ -138,7 +153,11 @@ def role_info(item: Optional[Role], db):
"id": item.id, "id": item.id,
"name": item.name, "name": item.name,
"permissions": [ "permissions": [
{"id": p.id, "name": p.name, "enabled": True if p in item.permissions else False,} {
"id": p.id,
"name": p.name,
"enabled": True if p in item.permissions else False,
}
for p in db.query(Permission).order_by(Permission.name).all() for p in db.query(Permission).order_by(Permission.name).all()
], ],
} }
+40 -17
View File
@@ -1,15 +1,18 @@
import uuid import uuid
from typing import List, Optional from typing import List, Optional
from fastapi import APIRouter, HTTPException, status, Depends, Security import brewman.schemas.auth as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ...schemas.auth import UserToken
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 SessionLocal from ...db.session import SessionLocal
from brewman.models.auth import User, Role from ...models.auth import Role, User
import brewman.schemas.auth as schemas from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -25,7 +28,9 @@ def get_db():
@router.post("", response_model=schemas.User) @router.post("", response_model=schemas.User)
def save( def save(
data: schemas.UserIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), data: schemas.UserIn,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
try: try:
item = User(name=data.name, password=data.password, locked_out=data.locked_out) item = User(name=data.name, password=data.password, locked_out=data.locked_out)
@@ -36,7 +41,8 @@ def save(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -45,7 +51,8 @@ def save(
@router.get("/me", response_model=schemas.User) @router.get("/me", response_model=schemas.User)
def show_me( def show_me(
db: Session = Depends(get_db), user: UserToken = Depends(get_user), db: Session = Depends(get_db),
user: UserToken = Depends(get_user),
): ):
item = db.query(User).filter(User.id == user.id_).first() item = db.query(User).filter(User.id == user.id_).first()
return user_info(item, db, user) return user_info(item, db, user)
@@ -53,7 +60,9 @@ def show_me(
@router.put("/me", response_model=schemas.User) @router.put("/me", response_model=schemas.User)
def update_me( def update_me(
data: schemas.UserIn, db: Session = Depends(get_db), user: UserToken = Depends(get_user), data: schemas.UserIn,
db: Session = Depends(get_db),
user: UserToken = Depends(get_user),
): ):
try: try:
item: User = db.query(User).filter(User.id == user.id_).first() item: User = db.query(User).filter(User.id == user.id_).first()
@@ -68,7 +77,8 @@ def update_me(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -94,7 +104,8 @@ def update(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -113,17 +124,21 @@ def add_roles(user: User, roles: List[schemas.RoleItem], db: Session):
@router.delete("/{id_}") @router.delete("/{id_}")
def delete( def delete(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
try: try:
item: User = db.query(User).filter(User.id == id_).first() item: User = db.query(User).filter(User.id == id_).first()
if item is None: if item is None:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="User not found", status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="User not found",
) )
else: else:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED, detail="User deletion not implemented", status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail="User deletion not implemented",
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -132,14 +147,16 @@ def delete(
@router.get("") @router.get("")
def show_blank( def show_blank(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
return user_info(None, db, user) return user_info(None, db, user)
@router.get("/list", response_model=List[schemas.UserList]) @router.get("/list", response_model=List[schemas.UserList])
async def show_list( async def show_list(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
return [ return [
{ {
@@ -159,7 +176,9 @@ async def show_active(db: Session = Depends(get_db), user: UserToken = Depends(g
@router.get("/{id_}", response_model=schemas.User) @router.get("/{id_}", response_model=schemas.User)
def show_id( def show_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["users"]),
): ):
item = db.query(User).filter(User.id == id_).first() item = db.query(User).filter(User.id == id_).first()
return user_info(item, db, user) return user_info(item, db, user)
@@ -179,7 +198,11 @@ def user_info(item: Optional[User], db: Session, user: UserToken):
"password": "", "password": "",
"lockedOut": item.locked_out, "lockedOut": item.locked_out,
"roles": [ "roles": [
{"id": r.id, "name": r.name, "enabled": True if r in item.roles else False,} {
"id": r.id,
"name": r.name,
"enabled": True if r in item.roles else False,
}
for r in db.query(Role).order_by(Role.name).all() for r in db.query(Role).order_by(Role.name).all()
] ]
if "advanced-delete" in user.permissions if "advanced-delete" in user.permissions
+13 -4
View File
@@ -3,10 +3,11 @@ import datetime
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from brewman.models.voucher import Batch from ..models.voucher import Batch
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -22,7 +23,11 @@ def get_db() -> Session:
@router.get("") @router.get("")
def batch_term( def batch_term(
q: str, c: int = None, d: str = None, db: Session = Depends(get_db), current_user: UserToken = Depends(get_user), q: str,
c: int = None,
d: str = None,
db: Session = Depends(get_db),
current_user: UserToken = Depends(get_user),
): ):
filter_ = q if q is not None and q.strip() != "" else None filter_ = q if q is not None and q.strip() != "" else None
date = None if not d else datetime.datetime.strptime(d, "%d-%b-%Y") date = None if not d else datetime.datetime.strptime(d, "%d-%b-%Y")
@@ -37,7 +42,11 @@ def batch_term(
"rate": item.rate, "rate": item.rate,
"tax": item.tax, "tax": item.tax,
"discount": item.discount, "discount": item.discount,
"product": {"id": item.product.id, "name": item.product.name, "units": item.product.units,}, "product": {
"id": item.product.id,
"name": item.product.name,
"units": item.product.units,
},
} }
) )
if c is not None and index == c - 1: if c is not None and index == c - 1:
+26 -12
View File
@@ -1,15 +1,18 @@
import uuid import uuid
from typing import List, Optional from typing import List, Optional
from fastapi import APIRouter, HTTPException, status, Depends, Security import brewman.schemas.master as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..schemas.auth import UserToken
import brewman.schemas.master as schemas
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 SessionLocal from ..db.session import SessionLocal
from ..models.master import CostCentre from ..models.master import CostCentre
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -37,7 +40,8 @@ def save(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -55,7 +59,8 @@ def update(
item = db.query(CostCentre).filter(CostCentre.id == id_).first() item = db.query(CostCentre).filter(CostCentre.id == id_).first()
if item.is_fixture: if item.is_fixture:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_423_LOCKED, detail=f"{item.name} is a fixture and cannot be edited or deleted.", status_code=status.HTTP_423_LOCKED,
detail=f"{item.name} is a fixture and cannot be edited or deleted.",
) )
item.name = data.name item.name = data.name
db.commit() db.commit()
@@ -63,7 +68,8 @@ def update(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -72,22 +78,27 @@ def update(
@router.delete("/{id_}") @router.delete("/{id_}")
def delete( def delete(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["cost-centres"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["cost-centres"]),
): ):
try: try:
item: CostCentre = db.query(CostCentre).filter(CostCentre.id == id_).first() item: CostCentre = db.query(CostCentre).filter(CostCentre.id == id_).first()
if item is None: if item is None:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Cost Centre not found", status_code=status.HTTP_404_NOT_FOUND,
detail="Cost Centre not found",
) )
elif item.is_fixture: elif item.is_fixture:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_423_LOCKED, detail=f"{item.name} is a fixture and cannot be edited or deleted.", status_code=status.HTTP_423_LOCKED,
detail=f"{item.name} is a fixture and cannot be edited or deleted.",
) )
else: else:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED, detail="Cost Centre deletion not implemented", status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail="Cost Centre deletion not implemented",
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -96,7 +107,8 @@ def delete(
@router.get("") @router.get("")
def show_blank( def show_blank(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["cost-centres"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["cost-centres"]),
): ):
return cost_centre_info(None) return cost_centre_info(None)
@@ -111,7 +123,9 @@ async def show_list(db: Session = Depends(get_db), user: UserToken = Depends(get
@router.get("/{id_}", response_model=schemas.CostCentre) @router.get("/{id_}", response_model=schemas.CostCentre)
def show_id( def show_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["cost-centres"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["cost-centres"]),
): ):
item = db.query(CostCentre).filter(CostCentre.id == id_).first() item = db.query(CostCentre).filter(CostCentre.id == id_).first()
return cost_centre_info(item) return cost_centre_info(item)
+23 -9
View File
@@ -1,16 +1,17 @@
from calendar import monthrange from calendar import monthrange
from datetime import datetime, date from datetime import date, datetime
from fastapi import APIRouter, Depends, Security, Body, HTTPException, status from fastapi import APIRouter, Body, Depends, HTTPException, Security, status
from sqlalchemy import or_ from sqlalchemy import or_
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.session import get_first_day, get_last_day
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user from ..core.security import get_current_active_user as get_user
from ..core.session import get_first_day, get_last_day
from ..db.session import SessionLocal from ..db.session import SessionLocal
from ..models.master import Account, Employee, AttendanceType from ..models.master import Account, AttendanceType, Employee
from ..models.voucher import Voucher, Journal, VoucherType, Attendance from ..models.voucher import Attendance, Journal, Voucher, VoucherType
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -77,12 +78,25 @@ def salary_journals(start_date: date, finish_date: date, db: Session):
if att != 0: if att != 0:
amount += att amount += att
journals.append( journals.append(
Journal(amount=att, debit=-1, account_id=employee.id, cost_centre_id=employee.cost_centre_id,) Journal(
amount=att,
debit=-1,
account_id=employee.id,
cost_centre_id=employee.cost_centre_id,
)
) )
salary = db.query(Account).filter(Account.id == Account.salary_id()).first() salary = db.query(Account).filter(Account.id == Account.salary_id()).first()
if amount == 0: if amount == 0:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="No salaries to credit", status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="No salaries to credit",
)
journals.append(
Journal(
amount=amount,
debit=1,
account_id=salary.id,
cost_centre_id=salary.cost_centre_id,
)
) )
journals.append(Journal(amount=amount, debit=1, account_id=salary.id, cost_centre_id=salary.cost_centre_id,))
return journals return journals
+10 -3
View File
@@ -1,16 +1,19 @@
import uuid import uuid
from io import BytesIO from io import BytesIO
from typing import List from typing import List
import brewman.schemas.voucher as output
from fastapi import APIRouter, Depends, Security from fastapi import APIRouter, Depends, Security
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.security import get_user from ..core.security import get_user
from ..models.voucher import DbImage
from ..db.session import SessionLocal from ..db.session import SessionLocal
from ..models.voucher import DbImage
from ..schemas.auth import UserToken from ..schemas.auth import UserToken
import brewman.schemas.voucher as output
router = APIRouter() router = APIRouter()
@@ -42,7 +45,11 @@ def save_files(voucher_id: uuid.UUID, i: List[bytes], t: List[bytes], db: Sessio
def update_files( def update_files(
voucher_id: uuid.UUID, data: List[output.ImageUpload], i: List[bytes], t: List[bytes], db: Session, voucher_id: uuid.UUID,
data: List[output.ImageUpload],
i: List[bytes],
t: List[bytes],
db: Session,
): ):
i = i or [] i = i or []
t = t or [] t = t or []
+9 -9
View File
@@ -1,15 +1,12 @@
from fastapi import ( from fastapi import APIRouter, Depends, Security
APIRouter, from sqlalchemy import desc, distinct, func, over
Depends,
Security,
)
from sqlalchemy import distinct, func, over, desc
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..models import Attendance
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from ..models import Attendance
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -38,7 +35,10 @@ def post_check_db(db: Session = Depends(get_db), user: UserToken = Security(get_
def get_duplicate_attendances(db): def get_duplicate_attendances(db):
sub_query = ( sub_query = (
db.query( db.query(
over(distinct(func.first_value(Attendance.id)), partition_by=[Attendance.employee_id, Attendance.date],) over(
distinct(func.first_value(Attendance.id)),
partition_by=[Attendance.employee_id, Attendance.date],
)
) )
.filter(Attendance.is_valid == True) .filter(Attendance.is_valid == True)
.subquery() .subquery()
+46 -19
View File
@@ -1,16 +1,17 @@
import uuid import uuid
import brewman.schemas.master as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import desc from sqlalchemy import desc
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import joinedload_all, Session from sqlalchemy.orm import Session, joinedload_all
from fastapi import APIRouter, HTTPException, status, Depends, Security
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from brewman.models.master import CostCentre, Employee, AccountBase, Account from ..models.master import Account, AccountBase, CostCentre, Employee
from brewman.models.voucher import Voucher, Journal, VoucherType from ..models.voucher import Journal, Voucher, VoucherType
import brewman.schemas.master as schemas from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -27,7 +28,9 @@ def get_db():
@router.post("", response_model=schemas.Employee) @router.post("", response_model=schemas.Employee)
def save( def save(
data: schemas.EmployeeIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["employees"]), data: schemas.EmployeeIn,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["employees"]),
): ):
try: try:
item = Employee( item = Employee(
@@ -46,7 +49,8 @@ def save(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -64,7 +68,8 @@ def update(
item: Employee = db.query(Employee).filter(Employee.id == id_).first() item: Employee = db.query(Employee).filter(Employee.id == id_).first()
if item.is_fixture: if item.is_fixture:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_423_LOCKED, detail=f"{item.name} is a fixture and cannot be edited or deleted.", status_code=status.HTTP_423_LOCKED,
detail=f"{item.name} is a fixture and cannot be edited or deleted.",
) )
item.name = data.name item.name = data.name
item.cost_centre_id = data.cost_centre.id_ item.cost_centre_id = data.cost_centre.id_
@@ -80,7 +85,8 @@ def update(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -89,7 +95,9 @@ def update(
@router.delete("/{id_}") @router.delete("/{id_}")
def delete( def delete(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["employees"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["employees"]),
): ):
employee: Employee = db.query(Employee).filter(Employee.id == id_).first() employee: Employee = db.query(Employee).filter(Employee.id == id_).first()
can_delete, reason = employee.can_delete("advanced-delete" in user.permissions) can_delete, reason = employee.can_delete("advanced-delete" in user.permissions)
@@ -100,13 +108,15 @@ def delete(
else: else:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Cannot delete account because {reason}", status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Cannot delete account because {reason}",
) )
@router.get("") @router.get("")
def show_blank( def show_blank(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["employees"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["employees"]),
): ):
return employee_info(None, db) return employee_info(None, db)
@@ -138,7 +148,10 @@ async def show_list(db: Session = Depends(get_db), user: UserToken = Depends(get
@router.get("/query") @router.get("/query")
async def show_term( async def show_term(
q: str, c: int = None, db: Session = Depends(get_db), current_user: UserToken = Depends(get_user), q: str,
c: int = None,
db: Session = Depends(get_db),
current_user: UserToken = Depends(get_user),
): ):
list_ = [] list_ = []
for index, item in enumerate(AccountBase.query(q=q, type_=10, db=db)): for index, item in enumerate(AccountBase.query(q=q, type_=10, db=db)):
@@ -147,7 +160,10 @@ async def show_term(
"id": item.id, "id": item.id,
"name": item.name, "name": item.name,
"designation": item.designation, "designation": item.designation,
"costCentre": {"id": item.cost_centre.id, "name": item.cost_centre.name,}, "costCentre": {
"id": item.cost_centre.id,
"name": item.cost_centre.name,
},
} }
) )
if c is not None and index == c - 1: if c is not None and index == c - 1:
@@ -157,7 +173,9 @@ async def show_term(
@router.get("/{id_}") @router.get("/{id_}")
def show_id( def show_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["employees"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["employees"]),
): ):
return employee_info(id_, db) return employee_info(id_, db)
@@ -173,7 +191,10 @@ def employee_info(id_, db):
else: else:
employee = db.query(Employee).filter(Employee.id == id_).first() employee = db.query(Employee).filter(Employee.id == id_).first()
if employee is None: if employee is None:
raise ValidationError("Invalid Employee") raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Employee not found",
)
employee = { employee = {
"id": employee.id, "id": employee.id,
"code": employee.code, "code": employee.code,
@@ -185,7 +206,10 @@ def employee_info(id_, db):
"points": employee.points, "points": employee.points,
"joiningDate": employee.joining_date.strftime("%d-%b-%Y"), "joiningDate": employee.joining_date.strftime("%d-%b-%Y"),
"leavingDate": None if employee.is_active else employee.leaving_date.strftime("%d-%b-%Y"), "leavingDate": None if employee.is_active else employee.leaving_date.strftime("%d-%b-%Y"),
"costCentre": {"id": employee.cost_centre_id, "name": employee.cost_centre.name,}, "costCentre": {
"id": employee.cost_centre_id,
"name": employee.cost_centre.name,
},
"isFixture": employee.is_fixture, "isFixture": employee.is_fixture,
} }
return employee return employee
@@ -226,7 +250,10 @@ def delete_with_data(employee, db):
sus_jnl.amount = abs(amount) sus_jnl.amount = abs(amount)
sus_jnl.debit = -1 if amount < 0 else 1 sus_jnl.debit = -1 if amount < 0 else 1
voucher.narration += f"\nDeleted \u20B9 {acc_jnl.amount * acc_jnl.debit:,.2f} of {employee.name}" voucher.narration += f"\nDeleted \u20B9 {acc_jnl.amount * acc_jnl.debit:,.2f} of {employee.name}"
if voucher.type in (VoucherType.by_name("Payment").id, VoucherType.by_name("Receipt").id,): if voucher.type in (
VoucherType.by_name("Payment").id,
VoucherType.by_name("Receipt").id,
):
voucher.type = VoucherType.by_name("Journal") voucher.type = VoucherType.by_name("Journal")
for fingerprint in employee.fingerprints: for fingerprint in employee.fingerprints:
db.delete(fingerprint) db.delete(fingerprint)
+23 -17
View File
@@ -1,20 +1,21 @@
import uuid import uuid
from datetime import datetime, date
from fastapi import APIRouter, HTTPException, status, Depends, Security, Request from datetime import date, datetime
from sqlalchemy.orm import Session
from .attendance import date_range
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionLocal
from brewman.models.master import Employee
from brewman.models.voucher import Attendance
from brewman.routers.fingerprint import get_prints
import brewman.schemas.voucher as schemas import brewman.schemas.voucher as schemas
from ..core.session import (
get_start_date, from fastapi import APIRouter, Depends, HTTPException, Request, Security, status
get_finish_date, from sqlalchemy.orm import Session
)
from ..core.security import get_current_active_user as get_user
from ..core.session import get_finish_date, get_start_date
from ..db.session import SessionLocal
from ..models.master import Employee
from ..models.voucher import Attendance
from ..routers.fingerprint import get_prints
from ..schemas.auth import UserToken
from .attendance import date_range
router = APIRouter() router = APIRouter()
@@ -30,7 +31,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.EmployeeAttendance) @router.get("", response_model=schemas.EmployeeAttendance)
def show_blank( def show_blank(
request: Request, user: UserToken = Security(get_user, scopes=["attendance"]), request: Request,
user: UserToken = Security(get_user, scopes=["attendance"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
@@ -52,7 +54,8 @@ def employee_attendance_report(
employee: Employee = db.query(Employee).filter(Employee.id == id_).first() employee: Employee = db.query(Employee).filter(Employee.id == id_).first()
if employee is None: if employee is None:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Employee not found", status_code=status.HTTP_404_NOT_FOUND,
detail="Employee not found",
) )
start_date = s if s is not None else get_start_date(request.session) start_date = s if s is not None else get_start_date(request.session)
finish_date = f if f is not None else get_finish_date(request.session) finish_date = f if f is not None else get_finish_date(request.session)
@@ -113,7 +116,10 @@ def save_employee_attendance(
attendance_type = item.attendance_type.id_ attendance_type = item.attendance_type.id_
if attendance_type != 0: if attendance_type != 0:
attendance = Attendance( attendance = Attendance(
employee_id=employee.id, date=item.date_, attendance_type=attendance_type, user_id=user.id_, employee_id=employee.id,
date=item.date_,
attendance_type=attendance_type,
user_id=user.id_,
) )
attendance.create(db) attendance.create(db)
db.commit() db.commit()
+57 -37
View File
@@ -1,39 +1,30 @@
import uuid import uuid
from datetime import date, datetime
from math import ceil from math import ceil
from typing import List from typing import List
from datetime import datetime, date
from fastapi import ( import brewman.schemas.input as schema_in
APIRouter, import brewman.schemas.voucher as output
HTTPException,
status, from fastapi import APIRouter, Depends, File, HTTPException, Request, Security, status
Depends,
Security,
File,
Request,
)
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.security import get_current_active_user as get_user
from ..core.session import get_date, get_last_day, set_date
from ..db.session import SessionLocal
from ..models import AccountBase, Employee
from ..models.voucher import EmployeeBenefit, Journal, Voucher, VoucherType
from ..schemas.auth import UserToken
from .db_image import save_files, update_files from .db_image import save_files, update_files
from .voucher import ( from .voucher import (
voucher_info,
check_voucher_lock_info,
check_voucher_edit_allowed,
blank_voucher, blank_voucher,
check_voucher_edit_allowed,
check_voucher_lock_info,
voucher_info,
) )
from ..core.session import set_date, get_date, get_last_day
from ..models import AccountBase, Employee
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models.voucher import (
Voucher,
VoucherType,
Journal,
EmployeeBenefit,
)
import brewman.schemas.voucher as output
import brewman.schemas.input as schema_in
router = APIRouter() router = APIRouter()
@@ -70,7 +61,8 @@ def save_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -91,7 +83,10 @@ def save(data: schema_in.EmployeeBenefitIn, date_: date, user: UserToken, db: Se
def save_employee_benefits( def save_employee_benefits(
voucher: Voucher, employee_benefits: List[schema_in.EmployeeBenefit], days_in_month: int, db: Session, voucher: Voucher,
employee_benefits: List[schema_in.EmployeeBenefit],
days_in_month: int,
db: Session,
): ):
total_exp, total_total = 0, 0 total_exp, total_total = 0, 0
for item in employee_benefits: for item in employee_benefits:
@@ -100,7 +95,12 @@ def save_employee_benefits(
days_worked = item.days_worked days_worked = item.days_worked
esi_ee, esi_er, esi_both = esi_contribution(gross_salary, days_worked, days_in_month) esi_ee, esi_er, esi_both = esi_contribution(gross_salary, days_worked, days_in_month)
pf_ee, pf_er, pf_both = pf_contribution(gross_salary, days_worked, days_in_month) pf_ee, pf_er, pf_both = pf_contribution(gross_salary, days_worked, days_in_month)
journal = Journal(amount=esi_ee + pf_ee, debit=1, account_id=account.id, cost_centre_id=account.cost_centre_id,) journal = Journal(
amount=esi_ee + pf_ee,
debit=1,
account_id=account.id,
cost_centre_id=account.cost_centre_id,
)
sd = EmployeeBenefit( sd = EmployeeBenefit(
journal=journal, journal=journal,
gross_salary=gross_salary, gross_salary=gross_salary,
@@ -121,11 +121,21 @@ def save_employee_benefits(
def save_journals(voucher: Voucher, exp: int, total: int, db: Session): def save_journals(voucher: Voucher, exp: int, total: int, db: Session):
account = db.query(AccountBase).filter(AccountBase.id == AccountBase.esi_pf_expense()).first() account = db.query(AccountBase).filter(AccountBase.id == AccountBase.esi_pf_expense()).first()
journal = Journal(amount=exp, debit=1, account_id=account.id, cost_centre_id=account.cost_centre_id,) journal = Journal(
amount=exp,
debit=1,
account_id=account.id,
cost_centre_id=account.cost_centre_id,
)
db.add(journal) db.add(journal)
voucher.journals.append(journal) voucher.journals.append(journal)
account = db.query(AccountBase).filter(AccountBase.id == AccountBase.esi_pf_payable()).first() account = db.query(AccountBase).filter(AccountBase.id == AccountBase.esi_pf_payable()).first()
journal = Journal(amount=total, debit=-1, account_id=account.id, cost_centre_id=account.cost_centre_id,) journal = Journal(
amount=total,
debit=-1,
account_id=account.id,
cost_centre_id=account.cost_centre_id,
)
db.add(journal) db.add(journal)
voucher.journals.append(journal) voucher.journals.append(journal)
@@ -146,7 +156,8 @@ def update_route(
item: Voucher = update(id_, data, user, db) item: Voucher = update(id_, data, user, db)
if dt != item.date: if dt != item.date:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_423_LOCKED, detail="Date Cannot be changed for Employee Benefit voucher!", status_code=status.HTTP_423_LOCKED,
detail="Date Cannot be changed for Employee Benefit voucher!",
) )
exp, total = update_employee_benefits(item, data.employee_benefits, days_in_month, db) exp, total = update_employee_benefits(item, data.employee_benefits, days_in_month, db)
update_journals(item, exp, total) update_journals(item, exp, total)
@@ -158,7 +169,8 @@ def update_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -178,7 +190,10 @@ def update(id_: uuid.UUID, data: schema_in.EmployeeBenefitIn, user: UserToken, d
def update_employee_benefits( def update_employee_benefits(
voucher: Voucher, employee_benefits: List[schema_in.EmployeeBenefit], days_in_month: int, db: Session, voucher: Voucher,
employee_benefits: List[schema_in.EmployeeBenefit],
days_in_month: int,
db: Session,
): ):
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):
@@ -207,7 +222,9 @@ def update_journals(voucher: Voucher, exp: int, total: int):
@router.get("/{id_}", response_model=output.Voucher) @router.get("/{id_}", response_model=output.Voucher)
def get_id( def get_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["employee-benefit"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["employee-benefit"]),
): ):
try: try:
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first() item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
@@ -215,7 +232,8 @@ def get_id(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -224,7 +242,9 @@ def get_id(
@router.get("", response_model=output.Voucher) @router.get("", response_model=output.Voucher)
def show_blank( def show_blank(
request: Request, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["employee-benefit"]), request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["employee-benefit"]),
): ):
additional_info = {"date": get_date(request.session), "type": "Employee Benefit"} additional_info = {"date": get_date(request.session), "type": "Employee Benefit"}
return blank_voucher(additional_info, db) return blank_voucher(additional_info, db)
+25 -19
View File
@@ -1,26 +1,22 @@
import csv import csv
import uuid import uuid
from datetime import date, datetime, time, timedelta
from io import StringIO from io import StringIO
from datetime import datetime, date, time, timedelta
from fastapi import ( from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
APIRouter, from sqlalchemy import and_, bindparam, exists, select
HTTPException,
status,
Depends,
File,
UploadFile,
)
from sqlalchemy import bindparam, select, exists, and_
from sqlalchemy.dialects.postgresql import insert as pg_insert from sqlalchemy.dialects.postgresql import insert as pg_insert
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from ..models.master import Employee from ..models.master import Employee
from ..models.voucher import Fingerprint from ..models.voucher import Fingerprint
from ..routers import get_lock_info from ..routers import get_lock_info
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -36,9 +32,7 @@ def get_db() -> Session:
@router.post("") @router.post("")
def upload_prints( def upload_prints(
db: Session = Depends(get_db), db: Session = Depends(get_db), fingerprints: UploadFile = File(None), user: UserToken = Depends(get_user)
fingerprints: UploadFile = File(None),
user: UserToken = Depends(get_user)
): ):
try: try:
start, finish = get_lock_info(db) start, finish = get_lock_info(db)
@@ -47,7 +41,7 @@ def upload_prints(
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"] <= 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)}")
db.execute(get_query(9.4), page) db.execute(get_query(9.4), page)
@@ -56,7 +50,8 @@ def upload_prints(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -68,14 +63,21 @@ def get_query(version):
return ( return (
pg_insert(Fingerprint) pg_insert(Fingerprint)
.values( .values(
{"FingerprintID": bindparam("id"), "EmployeeID": bindparam("employee_id"), "Date": bindparam("date"),} {
"FingerprintID": bindparam("id"),
"EmployeeID": bindparam("employee_id"),
"Date": bindparam("date"),
}
) )
.on_conflict_do_nothing() .on_conflict_do_nothing()
) )
else: else:
sel = select([bindparam("id"), bindparam("employee_id"), bindparam("date")]).where( sel = select([bindparam("id"), bindparam("employee_id"), bindparam("date")]).where(
~exists([Fingerprint.id]).where( ~exists([Fingerprint.id]).where(
and_(Fingerprint.employee_id == bindparam("employee_id"), Fingerprint.date == bindparam("date"),) and_(
Fingerprint.employee_id == bindparam("employee_id"),
Fingerprint.date == bindparam("date"),
)
) )
) )
return Fingerprint.__table__.insert().from_select( return Fingerprint.__table__.insert().from_select(
@@ -114,7 +116,11 @@ def fp(file_data, employees):
date = datetime.datetime.strptime(row[date_column], date_format) date = datetime.datetime.strptime(row[date_column], date_format)
if employee_code in employees.keys(): if employee_code in employees.keys():
fingerprints.append( fingerprints.append(
{"id": uuid.uuid4(), "employee_id": employees[employee_code], "date": date,} {
"id": uuid.uuid4(),
"employee_id": employees[employee_code],
"date": date,
}
) )
except ValueError: except ValueError:
continue continue
+50 -38
View File
@@ -1,39 +1,30 @@
import uuid import uuid
from datetime import date, datetime
from decimal import Decimal from decimal import Decimal
from typing import List, Optional from typing import List, Optional
from datetime import date, datetime
from fastapi import ( import brewman.schemas.input as schema_in
APIRouter, import brewman.schemas.voucher as output
HTTPException,
status, from fastapi import APIRouter, Depends, HTTPException, Request, Security, status
Depends, from sqlalchemy import func, or_
Security,
Request,
)
from sqlalchemy import or_, func
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from .voucher import (
voucher_info,
check_voucher_lock_info,
check_voucher_edit_allowed,
blank_voucher,
)
from ..core.session import set_date, get_date, get_first_day
from ..models import Employee, AttendanceType, Account
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user from ..core.security import get_current_active_user as get_user
from ..core.session import get_date, get_first_day, set_date
from ..db.session import SessionLocal from ..db.session import SessionLocal
from ..models.voucher import ( from ..models import Account, AttendanceType, Employee
Voucher, from ..models.voucher import Attendance, Incentive, Journal, Voucher, VoucherType
VoucherType, from ..schemas.auth import UserToken
Journal, from .voucher import (
Incentive, blank_voucher,
Attendance, check_voucher_edit_allowed,
check_voucher_lock_info,
voucher_info,
) )
import brewman.schemas.voucher as output
import brewman.schemas.input as schema_in
router = APIRouter() router = APIRouter()
@@ -68,7 +59,8 @@ def save_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -89,13 +81,19 @@ def save(data: schema_in.IncentiveIn, user: UserToken, db: Session) -> Voucher:
def save_incentives( def save_incentives(
voucher: Voucher, employees: List[schema_in.IncentiveEmployee], point_value: Decimal, db: Session, voucher: Voucher,
employees: List[schema_in.IncentiveEmployee],
point_value: Decimal,
db: Session,
): ):
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)
journal = Journal( journal = Journal(
amount=item_amount, debit=-1, account_id=item.employee_id, cost_centre_id=item.cost_centre_id, amount=item_amount,
debit=-1,
account_id=item.employee_id,
cost_centre_id=item.cost_centre_id,
) )
inc = Incentive(journal=journal, days_worked=item.days_worked, points=item.points) inc = Incentive(journal=journal, days_worked=item.days_worked, points=item.points)
voucher.journals.append(journal) voucher.journals.append(journal)
@@ -131,7 +129,8 @@ def update_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -151,7 +150,10 @@ def update(id_: uuid.UUID, data: schema_in.IncentiveIn, user: UserToken, db: Ses
def update_incentives( def update_incentives(
voucher: Voucher, employees: List[schema_in.IncentiveEmployee], point_value: Decimal, db: Session, voucher: Voucher,
employees: List[schema_in.IncentiveEmployee],
point_value: Decimal,
db: Session,
): ):
total_amount = 0 total_amount = 0
for item in voucher.incentives: for item in voucher.incentives:
@@ -168,7 +170,9 @@ def update_incentives(
@router.get("/{id_}", response_model=output.Voucher) @router.get("/{id_}", response_model=output.Voucher)
def get_id( def get_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["incentive"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["incentive"]),
): ):
try: try:
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first() item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
@@ -176,7 +180,8 @@ def get_id(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -227,7 +232,10 @@ def get_employees(
points = next(x for x in incentives if x.employee_id == employee.id).points points = next(x for x in incentives if x.employee_id == employee.id).points
details.append( details.append(
schema_in.IncentiveEmployee( schema_in.IncentiveEmployee(
employee_id=employee.id, cost_centre_id=employee.cost_centre_id, days_worked=att, points=points, employee_id=employee.id,
cost_centre_id=employee.cost_centre_id,
days_worked=att,
points=points,
) )
) )
return details return details
@@ -248,7 +256,9 @@ def balance(date_: date, voucher_id: Optional[uuid.UUID], db: Session):
def check_if_employees_changed( def check_if_employees_changed(
json: List[schema_in.Incentive], db: List[Employee], voucher: Optional[List[Journal]], json: List[schema_in.Incentive],
db: List[Employee],
voucher: Optional[List[Journal]],
): ):
json = set(x.employee_id for x in json) json = set(x.employee_id for x in json)
db = set(x.id for x in db) db = set(x.id for x in db)
@@ -258,10 +268,12 @@ def check_if_employees_changed(
if voucher is None: if voucher is None:
if len(json ^ db) != 0: if len(json ^ db) != 0:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Employee missing in json data", status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Employee missing in json data",
) )
else: else:
if len(json ^ db) != 0 or len(db ^ voucher) != 0: if len(json ^ db) != 0 or len(db ^ voucher) != 0:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Employee missing in json data", status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Employee missing in json data",
) )
+54 -32
View File
@@ -1,35 +1,30 @@
import uuid import uuid
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
from typing import List, Optional from typing import List, Optional
from fastapi import ( import brewman.schemas.input as schema_in
APIRouter, import brewman.schemas.voucher as output
HTTPException,
status, from fastapi import APIRouter, Depends, File, HTTPException, Request, Security, status
Depends,
Security,
File,
Request,
)
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.security import get_current_active_user as get_user
from ..core.session import get_date, set_date
from ..db.session import SessionLocal
from ..models import AccountBase, CostCentre
from ..models.voucher import Batch, Inventory, Journal, Voucher, VoucherType
from ..schemas.auth import UserToken
from .db_image import save_files, update_files from .db_image import save_files, update_files
from .voucher import ( from .voucher import (
voucher_info,
check_voucher_lock_info,
check_voucher_edit_allowed,
blank_voucher, blank_voucher,
check_voucher_edit_allowed,
check_voucher_lock_info,
voucher_info,
) )
from ..core.session import set_date, get_date
from ..models import CostCentre, AccountBase
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models.voucher import Voucher, VoucherType, Batch, Inventory, Journal
import brewman.schemas.voucher as output
import brewman.schemas.input as schema_in
router = APIRouter() router = APIRouter()
@@ -64,7 +59,8 @@ def save_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -83,7 +79,8 @@ def save(data: schema_in.IssueIn, user: UserToken, db: Session) -> (Voucher, Opt
db.add(voucher) db.add(voucher)
if data.source.id_ == data.destination.id_: if data.source.id_ == data.destination.id_:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Source cannot be the same as destination", status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Source cannot be the same as destination",
) )
if data.source.id_ == CostCentre.cost_centre_purchase(): if data.source.id_ == CostCentre.cost_centre_purchase():
batch_consumed = True batch_consumed = True
@@ -95,7 +92,10 @@ def save(data: schema_in.IssueIn, user: UserToken, db: Session) -> (Voucher, Opt
def save_inventories( def save_inventories(
voucher: Voucher, inventories: List[schema_in.Inventory], batch_consumed: Optional[bool], db: Session, voucher: Voucher,
inventories: List[schema_in.Inventory],
batch_consumed: Optional[bool],
db: Session,
) -> Decimal: ) -> Decimal:
amount: Decimal = Decimal(0) amount: Decimal = Decimal(0)
for item in inventories: for item in inventories:
@@ -139,8 +139,18 @@ def save_journals(
amount: Decimal, amount: Decimal,
db: Session, db: Session,
): ):
s = Journal(debit=-1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=source.id_,) s = Journal(
d = Journal(debit=1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=destination.id_,) debit=-1,
account_id=AccountBase.all_purchases(),
amount=amount,
cost_centre_id=source.id_,
)
d = Journal(
debit=1,
account_id=AccountBase.all_purchases(),
amount=amount,
cost_centre_id=destination.id_,
)
voucher.journals.append(s) voucher.journals.append(s)
db.add(s) db.add(s)
voucher.journals.append(d) voucher.journals.append(d)
@@ -169,7 +179,8 @@ def update_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -209,13 +220,17 @@ def update(id_: uuid.UUID, data: schema_in.IssueIn, user: UserToken, db: Session
if new_batch_consumed != old_batch_consumed: if new_batch_consumed != old_batch_consumed:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Purchase cost centre cannot be changed", status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Purchase cost centre cannot be changed",
) )
return voucher, new_batch_consumed return voucher, new_batch_consumed
def update_inventories( def update_inventories(
voucher: Voucher, inventories: List[schema_in.Inventory], batch_consumed: Optional[bool], db: Session, voucher: Voucher,
inventories: List[schema_in.Inventory],
batch_consumed: Optional[bool],
db: Session,
): ):
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):
@@ -228,7 +243,8 @@ def update_inventories(
found = True found = True
if item.batch_id != batch.id: if item.batch_id != batch.id:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Product / Batch cannot be changed", status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Product / Batch cannot be changed",
) )
if batch_consumed and i.quantity - item.quantity > item.batch.quantity_remaining: if batch_consumed and i.quantity - item.quantity > item.batch.quantity_remaining:
raise HTTPException( raise HTTPException(
@@ -275,7 +291,10 @@ def update_inventories(
def update_journals( def update_journals(
voucher: Voucher, source: schema_in.CostCentreLink, destination: schema_in.CostCentreLink, amount: Decimal, voucher: Voucher,
source: schema_in.CostCentreLink,
destination: schema_in.CostCentreLink,
amount: Decimal,
): ):
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]
@@ -289,7 +308,9 @@ def update_journals(
@router.get("/{id_}", response_model=output.Voucher) @router.get("/{id_}", response_model=output.Voucher)
def get_id( def get_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["issue"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["issue"]),
): ):
try: try:
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first() item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
@@ -297,7 +318,8 @@ def get_id(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
+8 -5
View File
@@ -1,14 +1,14 @@
from datetime import datetime from datetime import datetime
from fastapi import APIRouter, Depends, Request, Security
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.orm.util import aliased from sqlalchemy.orm.util import aliased
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from brewman.models.voucher import Voucher, Journal, VoucherType from ..models.voucher import Journal, Voucher, VoucherType
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -24,7 +24,10 @@ def get_db() -> Session:
@router.get("/{date}") @router.get("/{date}")
def grid_date( def grid_date(
date: str, request: Request, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["issue"]), date: str,
request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["issue"]),
): ):
date = datetime.strptime(date, "%d-%b-%Y") date = datetime.strptime(date, "%d-%b-%Y")
return get_grid(date, db) return get_grid(date, db)
+36 -28
View File
@@ -1,33 +1,29 @@
import uuid import uuid
from typing import List
from datetime import datetime from datetime import datetime
from fastapi import ( from typing import List
APIRouter,
HTTPException, import brewman.schemas.input as schema_in
status, import brewman.schemas.voucher as output
Depends,
Security, from fastapi import APIRouter, Depends, File, HTTPException, Request, Security, status
File,
Request,
)
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.security import get_current_active_user as get_user
from ..core.session import get_date, set_date
from ..db.session import SessionLocal
from ..models import AccountBase
from ..models.voucher import Journal, Voucher, VoucherType
from ..schemas.auth import UserToken
from .db_image import save_files, update_files from .db_image import save_files, update_files
from .voucher import ( from .voucher import (
voucher_info,
check_voucher_lock_info,
check_voucher_edit_allowed,
blank_voucher, blank_voucher,
check_voucher_edit_allowed,
check_voucher_lock_info,
voucher_info,
) )
from ..core.session import set_date, get_date
from ..models import AccountBase
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models.voucher import Voucher, VoucherType, Journal
import brewman.schemas.voucher as output
import brewman.schemas.input as schema_in
router = APIRouter() router = APIRouter()
@@ -61,7 +57,8 @@ def save_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -81,7 +78,10 @@ def save(data: schema_in.JournalIn, user: UserToken, db: Session) -> Voucher:
for item in data.journals: for item in data.journals:
account: AccountBase = db.query(AccountBase).filter(AccountBase.id == item.account.id_).first() account: AccountBase = db.query(AccountBase).filter(AccountBase.id == item.account.id_).first()
journal = Journal( journal = Journal(
amount=item.amount, debit=item.debit, account_id=account.id, cost_centre_id=account.cost_centre_id, amount=item.amount,
debit=item.debit,
account_id=account.id,
cost_centre_id=account.cost_centre_id,
) )
voucher.journals.append(journal) voucher.journals.append(journal)
db.add(journal) db.add(journal)
@@ -107,7 +107,8 @@ def update_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -144,7 +145,10 @@ def update(id_: uuid.UUID, data: schema_in.JournalIn, user: UserToken, db: Sessi
for new_item in data.journals: for new_item in data.journals:
account = db.query(AccountBase).filter(AccountBase.id == new_item.account.id_).first() account = db.query(AccountBase).filter(AccountBase.id == new_item.account.id_).first()
journal = Journal( journal = Journal(
amount=new_item.amount, debit=new_item.debit, account_id=account.id, cost_centre_id=account.cost_centre_id, amount=new_item.amount,
debit=new_item.debit,
account_id=account.id,
cost_centre_id=account.cost_centre_id,
) )
db.add(journal) db.add(journal)
voucher.journals.append(journal) voucher.journals.append(journal)
@@ -153,19 +157,23 @@ def update(id_: uuid.UUID, data: schema_in.JournalIn, user: UserToken, db: Sessi
@router.get("/{id_}", response_model=output.Voucher) @router.get("/{id_}", response_model=output.Voucher)
def get_id( def get_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["journal"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["journal"]),
): ):
try: try:
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first() item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
if item is None: if item is None:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Voucher not found", status_code=status.HTTP_404_NOT_FOUND,
detail="Voucher not found",
) )
return voucher_info(item, db) return voucher_info(item, db)
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
+12 -11
View File
@@ -1,15 +1,12 @@
from fastapi import ( from fastapi import APIRouter, Depends, Security
APIRouter,
Depends,
Security,
)
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..models.master import DbSetting
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from brewman.schemas.settings import LockInformation from ..models.master import DbSetting
from ..schemas.auth import UserToken
from ..schemas.settings import LockInformation
router = APIRouter() router = APIRouter()
@@ -25,7 +22,9 @@ def get_db() -> Session:
@router.post("", response_model=LockInformation) @router.post("", response_model=LockInformation)
def post( def post(
data_in: LockInformation, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["lock-date"]), data_in: LockInformation,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["lock-date"]),
): ):
data = { data = {
"Start": {"Locked": data_in.lock_older}, "Start": {"Locked": data_in.lock_older},
@@ -57,7 +56,8 @@ def post(
@router.delete("") @router.delete("")
def delete( def delete(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["lock-date"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["lock-date"]),
): ):
lock_date = db.query(DbSetting).filter(DbSetting.name == "Lock Info").first() lock_date = db.query(DbSetting).filter(DbSetting.name == "Lock Info").first()
if lock_date is not None and lock_date.data is not None: if lock_date is not None and lock_date.data is not None:
@@ -68,7 +68,8 @@ def delete(
@router.get("") @router.get("")
def get( def get(
db: Session = Depends(get_db), user: UserToken = Security(get_user), db: Session = Depends(get_db),
user: UserToken = Security(get_user),
): ):
data = db.query(DbSetting).filter(DbSetting.name == "Lock Info").first() data = db.query(DbSetting).filter(DbSetting.name == "Lock Info").first()
if data is None: if data is None:
+15 -8
View File
@@ -2,28 +2,30 @@ from datetime import timedelta
from fastapi import ( from fastapi import (
APIRouter, APIRouter,
Depends,
HTTPException,
status,
Security,
Cookie, Cookie,
Depends,
Form, Form,
HTTPException,
Response, Response,
Security,
status,
) )
from fastapi.security import OAuth2PasswordRequestForm
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.config import settings
from ..core.security import ( from ..core.security import (
Token, Token,
authenticate_user, authenticate_user,
client_allowed,
create_access_token, create_access_token,
get_current_active_user, get_current_active_user,
client_allowed,
) )
from brewman.core.config import settings
from ..db.session import SessionLocal from ..db.session import SessionLocal
from ..schemas.auth import UserToken from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -81,7 +83,12 @@ async def login_for_access_token(
async def refresh_token(user: UserToken = Security(get_current_active_user)): async def refresh_token(user: UserToken = Security(get_current_active_user)):
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={"sub": user.name, "scopes": user.permissions, "userId": str(user.id_), "lockedOut": user.locked_out,}, data={
"sub": user.name,
"scopes": user.permissions,
"userId": str(user.id_),
"lockedOut": user.locked_out,
},
expires_delta=access_token_expires, expires_delta=access_token_expires,
) )
return {"access_token": access_token, "token_type": "bearer"} return {"access_token": access_token, "token_type": "bearer"}
+10 -10
View File
@@ -1,16 +1,13 @@
from fastapi import ( from fastapi import APIRouter, Depends, Security
APIRouter,
Depends,
Security,
)
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models import User from ..models import User
from ..models.master import DbSetting from ..models.master import DbSetting
from ..schemas.auth import UserToken from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user from ..schemas.settings import Maintenance
from ..db.session import SessionLocal
from brewman.schemas.settings import Maintenance
router = APIRouter() router = APIRouter()
@@ -26,7 +23,8 @@ def get_db() -> Session:
@router.get("", response_model=Maintenance) @router.get("", response_model=Maintenance)
def get_maintenance( def get_maintenance(
db: Session = Depends(get_db), user: UserToken = Security(get_user), db: Session = Depends(get_db),
user: UserToken = Security(get_user),
): ):
data = db.query(DbSetting).filter(DbSetting.name == "Maintenance").first() data = db.query(DbSetting).filter(DbSetting.name == "Maintenance").first()
return info(data, db) return info(data, db)
@@ -34,7 +32,9 @@ def get_maintenance(
@router.post("", response_model=Maintenance) @router.post("", response_model=Maintenance)
def set_maintenance( def set_maintenance(
data: Maintenance, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["maintenance"]), data: Maintenance,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["maintenance"]),
): ):
maintenance = db.query(DbSetting).filter(DbSetting.name == "Maintenance").first() maintenance = db.query(DbSetting).filter(DbSetting.name == "Maintenance").first()
if data.enabled is False and maintenance is not None: if data.enabled is False and maintenance is not None:
+28 -14
View File
@@ -1,17 +1,20 @@
import uuid import uuid
from typing import Optional from typing import Optional
from fastapi import APIRouter, HTTPException, status, Depends, Security import brewman.schemas.master as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import desc from sqlalchemy import desc
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import joinedload_all, Session from sqlalchemy.orm import Session, joinedload_all
from ..schemas.auth import UserToken
import brewman.schemas.master as schemas
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 SessionLocal from ..db.session import SessionLocal
from ..models.master import Product, Account from ..models.master import Account, Product
from ..models.voucher import Voucher, Batch, Inventory, VoucherType from ..models.voucher import Batch, Inventory, Voucher, VoucherType
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -27,7 +30,9 @@ def get_db():
@router.post("", response_model=schemas.Product) @router.post("", response_model=schemas.Product)
def save( def save(
data: schemas.ProductIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]), data: schemas.ProductIn,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["products"]),
): ):
try: try:
item = Product( item = Product(
@@ -49,7 +54,8 @@ def save(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -67,7 +73,8 @@ def update(
item: Product = db.query(Product).filter(Product.id == id_).first() item: Product = db.query(Product).filter(Product.id == id_).first()
if item.is_fixture: if item.is_fixture:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_423_LOCKED, detail=f"{item.name} is a fixture and cannot be edited or deleted.", status_code=status.HTTP_423_LOCKED,
detail=f"{item.name} is a fixture and cannot be edited or deleted.",
) )
item.name = data.name item.name = data.name
item.units = data.units item.units = data.units
@@ -86,7 +93,8 @@ def update(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -95,7 +103,9 @@ def update(
@router.delete("/{id_}") @router.delete("/{id_}")
def delete( def delete(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["products"]),
): ):
item: Product = db.query(Product).filter(Product.id == id_).first() item: Product = db.query(Product).filter(Product.id == id_).first()
can_delete, reason = item.can_delete("advanced-delete" in user.permissions) can_delete, reason = item.can_delete("advanced-delete" in user.permissions)
@@ -107,13 +117,15 @@ def delete(
else: else:
db.abort() db.abort()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Cannot delete account because {reason}", status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Cannot delete account because {reason}",
) )
@router.get("") @router.get("")
def show_blank( def show_blank(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["products"]),
): ):
return product_info(None, db) return product_info(None, db)
@@ -181,7 +193,9 @@ async def show_term(
@router.get("/{id_}") @router.get("/{id_}")
def show_id( def show_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["accounts"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["accounts"]),
): ):
return product_info(id_, db) return product_info(id_, db)
+27 -13
View File
@@ -1,15 +1,18 @@
import uuid import uuid
from typing import List, Optional from typing import List, Optional
from fastapi import APIRouter, HTTPException, status, Depends, Security import brewman.schemas.master as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
import brewman.schemas.master as schemas
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from brewman.models.master import ProductGroup from ..models.master import ProductGroup
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -37,7 +40,8 @@ def save(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -55,7 +59,8 @@ def update(
item = db.query(ProductGroup).filter(ProductGroup.id == id_).first() item = db.query(ProductGroup).filter(ProductGroup.id == id_).first()
if item.is_fixture: if item.is_fixture:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_423_LOCKED, detail=f"{item.name} is a fixture and cannot be edited or deleted.", status_code=status.HTTP_423_LOCKED,
detail=f"{item.name} is a fixture and cannot be edited or deleted.",
) )
item.name = data.name item.name = data.name
db.commit() db.commit()
@@ -63,7 +68,8 @@ def update(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -72,22 +78,27 @@ def update(
@router.delete("/{id_}") @router.delete("/{id_}")
def delete( def delete(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["product-groups"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["product-groups"]),
): ):
try: try:
item = db.query(ProductGroup).filter(ProductGroup.id == id_).first() item = db.query(ProductGroup).filter(ProductGroup.id == id_).first()
if item is None: if item is None:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Product Group not found", status_code=status.HTTP_404_NOT_FOUND,
detail="Product Group not found",
) )
elif item.is_fixture: elif item.is_fixture:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_423_LOCKED, detail=f"{item.name} is a fixture and cannot be edited or deleted.", status_code=status.HTTP_423_LOCKED,
detail=f"{item.name} is a fixture and cannot be edited or deleted.",
) )
else: else:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED, detail="Product Group deletion not implemented", status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail="Product Group deletion not implemented",
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -96,7 +107,8 @@ def delete(
@router.get("") @router.get("")
def show_blank( def show_blank(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["product-groups"]), db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["product-groups"]),
): ):
return product_group_info(None, db) return product_group_info(None, db)
@@ -111,7 +123,9 @@ async def show_list(db: Session = Depends(get_db), user: UserToken = Depends(get
@router.get("/{id_}", response_model=schemas.ProductGroup) @router.get("/{id_}", response_model=schemas.ProductGroup)
def show_id( def show_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["product-groups"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["product-groups"]),
): ):
item = db.query(ProductGroup).filter(ProductGroup.id == id_).first() item = db.query(ProductGroup).filter(ProductGroup.id == id_).first()
return product_group_info(item, db) return product_group_info(item, db)
+51 -31
View File
@@ -1,35 +1,31 @@
import uuid import uuid
from datetime import datetime
from decimal import Decimal from decimal import Decimal
from typing import List from typing import List
from datetime import datetime
from fastapi import ( import brewman.schemas.input as schema_in
APIRouter, import brewman.schemas.voucher as output
HTTPException,
status, from fastapi import APIRouter, Depends, File, HTTPException, Request, Security, status
Depends,
Security,
File,
Request,
)
from sqlalchemy import func from sqlalchemy import func
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.security import get_current_active_user as get_user
from ..core.session import get_date, set_date
from ..db.session import SessionLocal
from ..models import AccountBase, Product
from ..models.voucher import Batch, Inventory, Journal, Voucher, VoucherType
from ..schemas.auth import UserToken
from .db_image import save_files, update_files from .db_image import save_files, update_files
from .voucher import ( from .voucher import (
voucher_info,
check_voucher_lock_info,
check_voucher_edit_allowed,
blank_voucher, blank_voucher,
check_voucher_edit_allowed,
check_voucher_lock_info,
voucher_info,
) )
from ..core.session import set_date, get_date
from ..models import Product, AccountBase
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models.voucher import Voucher, VoucherType, Batch, Inventory, Journal
import brewman.schemas.voucher as output
import brewman.schemas.input as schema_in
router = APIRouter() router = APIRouter()
@@ -64,7 +60,8 @@ def save_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -121,9 +118,17 @@ def save_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session):
journals[account.id].amount += round(item.amount, 2) journals[account.id].amount += round(item.amount, 2)
else: else:
journals[account.id] = Journal( journals[account.id] = Journal(
debit=1, cost_centre_id=account.cost_centre_id, account_id=account.id, amount=round(item.amount, 2), debit=1,
cost_centre_id=account.cost_centre_id,
account_id=account.id,
amount=round(item.amount, 2),
)
journals[vendor.id] = Journal(
debit=-1,
cost_centre_id=vendor.cost_centre_id,
account_id=vendor.id,
amount=amount,
) )
journals[vendor.id] = Journal(debit=-1, cost_centre_id=vendor.cost_centre_id, account_id=vendor.id, amount=amount,)
for item in journals.values(): for item in journals.values():
voucher.journals.append(item) voucher.journals.append(item)
db.add(item) db.add(item)
@@ -151,7 +156,8 @@ def update_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -182,7 +188,8 @@ def update_inventory(voucher: Voucher, new_inventories: List[schema_in.Inventory
found = True found = True
if item.product_id != new_inventory.product.id_: if item.product_id != new_inventory.product.id_:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Product cannot be changed", status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Product cannot be changed",
) )
old_quantity = round(Decimal(item.quantity), 2) old_quantity = round(Decimal(item.quantity), 2)
quantity_remaining = round(Decimal(item.batch.quantity_remaining), 2) quantity_remaining = round(Decimal(item.batch.quantity_remaining), 2)
@@ -263,9 +270,17 @@ def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db):
journals[account.id].amount += item.amount journals[account.id].amount += item.amount
else: else:
journals[account.id] = Journal( journals[account.id] = Journal(
debit=1, cost_centre_id=account.cost_centre_id, account_id=account.id, amount=item.amount, debit=1,
cost_centre_id=account.cost_centre_id,
account_id=account.id,
amount=item.amount,
)
journals[vendor.id] = Journal(
debit=-1,
cost_centre_id=vendor.cost_centre_id,
account_id=vendor.id,
amount=amount,
) )
journals[vendor.id] = Journal(debit=-1, cost_centre_id=vendor.cost_centre_id, account_id=vendor.id, amount=amount,)
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.account_id in journals: if item.account_id in journals:
@@ -284,7 +299,9 @@ def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db):
@router.get("/{id_}", response_model=output.Voucher) @router.get("/{id_}", response_model=output.Voucher)
def get_id( def get_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["purchase"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["purchase"]),
): ):
try: try:
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first() item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
@@ -292,7 +309,8 @@ def get_id(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -301,7 +319,9 @@ def get_id(
@router.get("", response_model=output.Voucher) @router.get("", response_model=output.Voucher)
def show_blank( def show_blank(
request: Request, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["purchase"]), request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["purchase"]),
): ):
additional_info = {"date": get_date(request.session), "type": "Purchase"} additional_info = {"date": get_date(request.session), "type": "Purchase"}
return blank_voucher(additional_info, db) return blank_voucher(additional_info, db)
+51 -31
View File
@@ -1,34 +1,30 @@
import uuid import uuid
from datetime import datetime
from decimal import Decimal from decimal import Decimal
from typing import List from typing import List
from datetime import datetime
from fastapi import ( import brewman.schemas.input as schema_in
APIRouter, import brewman.schemas.voucher as output
HTTPException,
status, from fastapi import APIRouter, Depends, File, HTTPException, Request, Security, status
Depends,
Security,
File,
Request,
)
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.security import get_current_active_user as get_user
from ..core.session import get_date, set_date
from ..db.session import SessionLocal
from ..models import AccountBase
from ..models.voucher import Batch, Inventory, Journal, Voucher, VoucherType
from ..schemas.auth import UserToken
from .db_image import save_files, update_files from .db_image import save_files, update_files
from .voucher import ( from .voucher import (
voucher_info,
check_voucher_lock_info,
check_voucher_edit_allowed,
blank_voucher, blank_voucher,
check_voucher_edit_allowed,
check_voucher_lock_info,
voucher_info,
) )
from ..core.session import set_date, get_date
from ..models import AccountBase
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models.voucher import Voucher, VoucherType, Batch, Inventory, Journal
import brewman.schemas.voucher as output
import brewman.schemas.input as schema_in
router = APIRouter() router = APIRouter()
@@ -63,7 +59,8 @@ def save_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -123,9 +120,17 @@ def save_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session):
journals[account.id].amount += round(item.amount, 2) journals[account.id].amount += round(item.amount, 2)
else: else:
journals[account.id] = Journal( journals[account.id] = Journal(
debit=-1, cost_centre_id=account.cost_centre_id, account_id=account.id, amount=round(item.amount, 2), debit=-1,
cost_centre_id=account.cost_centre_id,
account_id=account.id,
amount=round(item.amount, 2),
)
journals[vendor.id] = Journal(
debit=1,
cost_centre_id=vendor.cost_centre_id,
account_id=vendor.id,
amount=amount,
) )
journals[vendor.id] = Journal(debit=1, cost_centre_id=vendor.cost_centre_id, account_id=vendor.id, amount=amount,)
for item in journals.values(): for item in journals.values():
voucher.journals.append(item) voucher.journals.append(item)
db.add(item) db.add(item)
@@ -153,7 +158,8 @@ def update_route(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -183,7 +189,8 @@ def update_inventory(voucher: Voucher, new_inventories: List[schema_in.Inventory
found = True found = True
if item.product_id != new_inventory.product.id_: if item.product_id != new_inventory.product.id_:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Product cannot be changed", status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Product cannot be changed",
) )
old_quantity = round(Decimal(item.quantity), 2) old_quantity = round(Decimal(item.quantity), 2)
quantity_remaining = round(Decimal(item.batch.quantity_remaining), 2) quantity_remaining = round(Decimal(item.batch.quantity_remaining), 2)
@@ -219,9 +226,17 @@ def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db):
journals[account.id].amount += item.amount journals[account.id].amount += item.amount
else: else:
journals[account.id] = Journal( journals[account.id] = Journal(
debit=-1, cost_centre_id=account.cost_centre_id, account_id=account.id, amount=item.amount, debit=-1,
cost_centre_id=account.cost_centre_id,
account_id=account.id,
amount=item.amount,
)
journals[vendor.id] = Journal(
debit=1,
cost_centre_id=vendor.cost_centre_id,
account_id=vendor.id,
amount=amount,
) )
journals[vendor.id] = Journal(debit=1, cost_centre_id=vendor.cost_centre_id, account_id=vendor.id, amount=amount,)
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.account_id in journals: if item.account_id in journals:
@@ -240,7 +255,9 @@ def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db):
@router.get("/{id_}", response_model=output.Voucher) @router.get("/{id_}", response_model=output.Voucher)
def get_id( def get_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["purchase-return"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["purchase-return"]),
): ):
try: try:
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first() item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
@@ -248,7 +265,8 @@ def get_id(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -257,7 +275,9 @@ def get_id(
@router.get("", response_model=output.Voucher) @router.get("", response_model=output.Voucher)
def show_blank( def show_blank(
request: Request, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["purchase-return"]), request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["purchase-return"]),
): ):
additional_info = {"date": get_date(request.session), "type": "Purchase Return"} additional_info = {"date": get_date(request.session), "type": "Purchase Return"}
return blank_voucher(additional_info, db) return blank_voucher(additional_info, db)
+13 -13
View File
@@ -1,22 +1,20 @@
import uuid import uuid
from datetime import datetime, timedelta, date
from datetime import date, datetime, timedelta
from decimal import Decimal from decimal import Decimal
from typing import List from typing import List
from fastapi import ( from fastapi import APIRouter, Depends, Security
APIRouter, from sqlalchemy import and_, distinct, func
Depends, from sqlalchemy.orm import Session, aliased, joinedload_all
Security,
)
from sqlalchemy import func, and_, distinct
from sqlalchemy.orm import Session, joinedload_all, aliased
from ..models import Voucher, Journal, VoucherType, Inventory, Batch, EmployeeBenefit
from ..models.master import AccountBase, CostCentre, Employee, Account
from ..models.voucher import Incentive, DbImage, Fingerprint, Attendance
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from ..models import Batch, EmployeeBenefit, Inventory, Journal, Voucher, VoucherType
from ..models.master import Account, AccountBase, CostCentre, Employee
from ..models.voucher import Attendance, DbImage, Fingerprint, Incentive
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -32,7 +30,9 @@ def get_db() -> Session:
@router.post("/{date_}") @router.post("/{date_}")
def rebase( def rebase(
date_: str, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["rebase"]), date_: str,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["rebase"]),
): ):
# request.dbsession.execute('SET statement_timeout TO 300000;') # 5 minutes # request.dbsession.execute('SET statement_timeout TO 300000;') # 5 minutes
date_ = datetime.strptime(date_, "%d-%b-%Y") date_ = datetime.strptime(date_, "%d-%b-%Y")
+13 -10
View File
@@ -1,17 +1,16 @@
import uuid
import datetime import datetime
import time import time
import uuid
from decimal import Decimal, InvalidOperation from decimal import Decimal, InvalidOperation
from sqlalchemy import desc, or_, func from brewman.models.master import CostCentre, Product, Recipe, RecipeItem
from brewman.models.master import Recipe, Product, RecipeItem, CostCentre from brewman.models.voucher import Inventory, Journal, Voucher, VoucherType
from brewman.models.voucher import Voucher, Inventory, VoucherType, Journal
from ..core.session import (
get_start_date,
get_finish_date,
set_period,
)
from fastapi import APIRouter from fastapi import APIRouter
from sqlalchemy import desc, func, or_
from ..core.session import get_finish_date, get_start_date, set_period
router = APIRouter() router = APIRouter()
@@ -86,7 +85,11 @@ def save_recipe(recipe, dbsession):
product = dbsession.query(Product).filter(Product.id == recipe.product_id).first() product = dbsession.query(Product).filter(Product.id == recipe.product_id).first()
product.price = recipe.cost_price product.price = recipe.cost_price
update_old_rows( update_old_rows(
recipe.product_id, recipe.valid_from, recipe.valid_to, recipe.effective_from, dbsession, recipe.product_id,
recipe.valid_from,
recipe.valid_to,
recipe.effective_from,
dbsession,
) )
dbsession.add(recipe) dbsession.add(recipe)
for item in recipe.recipe_items: for item in recipe.recipe_items:
+27 -20
View File
@@ -1,22 +1,20 @@
from datetime import datetime, date from datetime import date, datetime
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func, desc
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.master import AccountType, AccountBase
from brewman.models.voucher import Voucher, Journal, VoucherType
from brewman.routers.reports.closing_stock import get_closing_stock
from brewman.routers.reports.profit_loss import get_accumulated_profit
import brewman.schemas.reports as schemas import brewman.schemas.reports as schemas
from ...core.session import (
set_period, from fastapi import APIRouter, Depends, Request, Security
get_start_date, from sqlalchemy.orm import Session
get_finish_date, from sqlalchemy.sql.expression import desc, func
)
from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal
from ...models.master import AccountBase, AccountType
from ...models.voucher import Journal, Voucher, VoucherType
from ...routers.reports.closing_stock import get_closing_stock
from ...routers.reports.profit_loss import get_accumulated_profit
from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -32,7 +30,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.BalanceSheet) @router.get("", response_model=schemas.BalanceSheet)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["balance-sheet"]), request: Request,
user: UserToken = Security(get_user, scopes=["balance-sheet"]),
): ):
return {"date": get_finish_date(request.session), "body": [], "footer": None} return {"date": get_finish_date(request.session), "body": [], "footer": None}
@@ -58,7 +57,11 @@ def build_balance_sheet(date_: date, db: Session):
net_profit = round(get_accumulated_profit(date_, db), 2) - closing_stock net_profit = round(get_accumulated_profit(date_, db), 2) - closing_stock
total_amount = net_profit total_amount = net_profit
report.append( report.append(
{"name": "Net Loss" if net_profit >= 0 else "Net Profit", "subAmount": round(net_profit, 2), "order": 79000,} {
"name": "Net Loss" if net_profit >= 0 else "Net Profit",
"subAmount": round(net_profit, 2),
"order": 79000,
}
) )
capital_group = AccountType.by_id(5) capital_group = AccountType.by_id(5)
@@ -100,7 +103,11 @@ def build_balance_sheet(date_: date, db: Session):
if amount != 0: if amount != 0:
counter += 1 counter += 1
report.append( report.append(
{"name": account.name, "subAmount": round(amount, 2), "order": account_type.order + counter,} {
"name": account.name,
"subAmount": round(amount, 2),
"order": account_type.order + counter,
}
) )
if account_type.id in groups: if account_type.id in groups:
groups[account_type.id]["amount"] = round(groups[account_type.id]["amount"] + amount, 2) groups[account_type.id]["amount"] = round(groups[account_type.id]["amount"] + amount, 2)
+29 -16
View File
@@ -1,21 +1,19 @@
import datetime import datetime
from fastapi import APIRouter, Depends, Security, Request import brewman.schemas.reports as schemas
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.orm.util import aliased from sqlalchemy.orm.util import aliased
from sqlalchemy.sql.expression import func, desc from sqlalchemy.sql.expression import desc, func
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal from ...db.session import SessionLocal
from brewman.models.master import AccountBase, AccountType from ...models.master import AccountBase, AccountType
from brewman.models.voucher import Voucher, Journal, VoucherType from ...models.voucher import Journal, Voucher, VoucherType
import brewman.schemas.reports as schemas from ...schemas.auth import UserToken
from ...core.session import (
set_period,
get_start_date,
get_finish_date,
)
router = APIRouter() router = APIRouter()
@@ -31,7 +29,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.CashFlow) @router.get("", response_model=schemas.CashFlow)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["cash-flow"]), request: Request,
user: UserToken = Security(get_user, scopes=["cash-flow"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
@@ -110,7 +109,11 @@ def build_report(start_date, finish_date, db):
lt = AccountType.by_id(account_type) lt = AccountType.by_id(account_type)
total_amount += amount * -1 total_amount += amount * -1
cf[lt.cash_flow_classification.lower()].append( cf[lt.cash_flow_classification.lower()].append(
{"name": lt.name, "url": ["/", "cash-flow", str(lt.id)], "amount": amount * -1,} {
"name": lt.name,
"url": ["/", "cash-flow", str(lt.id)],
"amount": amount * -1,
}
) )
opening = ( opening = (
@@ -136,8 +139,14 @@ def build_report(start_date, finish_date, db):
return ( return (
cf, cf,
[ [
{"name": "Net increase in cash and cash equivalents", "amount": total_amount,}, {
{"name": "Cash and cash equivalents at beginning of period", "amount": opening,}, "name": "Net increase in cash and cash equivalents",
"amount": total_amount,
},
{
"name": "Cash and cash equivalents at beginning of period",
"amount": opening,
},
{"name": "Cash and cash equivalents at end of period", "amount": closing}, {"name": "Cash and cash equivalents at end of period", "amount": closing},
], ],
) )
@@ -174,7 +183,11 @@ def build_report_id(account_type, start_date, finish_date, db):
for account, amount in query: for account, amount in query:
total_amount += amount * -1 total_amount += amount * -1
details.append( details.append(
{"name": account.name, "url": ["/", "ledger", str(account.id)], "amount": amount * -1,} {
"name": account.name,
"url": ["/", "ledger", str(account.id)],
"amount": amount * -1,
}
) )
return details, [{"name": "total", "amount": total_amount}] return details, [{"name": "total", "amount": total_amount}]
+11 -12
View File
@@ -1,20 +1,18 @@
from datetime import datetime, date from datetime import date, datetime
from fastapi import APIRouter, Depends, Security, Request import brewman.schemas.reports as schemas
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func from sqlalchemy.sql.expression import func
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal from ...db.session import SessionLocal
from brewman.models.master import Product, CostCentre from ...models.master import CostCentre, Product
from brewman.models.voucher import Voucher, Journal, Inventory from ...models.voucher import Inventory, Journal, Voucher
import brewman.schemas.reports as schemas from ...schemas.auth import UserToken
from ...core.session import (
set_period,
get_start_date,
get_finish_date,
)
router = APIRouter() router = APIRouter()
@@ -30,7 +28,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.ClosingStock) @router.get("", response_model=schemas.ClosingStock)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["closing-stock"]), request: Request,
user: UserToken = Security(get_user, scopes=["closing-stock"]),
): ):
return {"date": get_finish_date(request.session), "body": []} return {"date": get_finish_date(request.session), "body": []}
+17 -14
View File
@@ -1,18 +1,16 @@
import datetime import datetime
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import joinedload_all, Session
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.voucher import Voucher, Journal, VoucherType
import brewman.schemas.reports as schemas import brewman.schemas.reports as schemas
from ...core.session import (
set_period, from fastapi import APIRouter, Depends, Request, Security
get_start_date, from sqlalchemy.orm import Session, joinedload_all
get_finish_date,
) from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal
from ...models.voucher import Journal, Voucher, VoucherType
from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -28,7 +26,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.Daybook) @router.get("", response_model=schemas.Daybook)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["daybook"]), request: Request,
user: UserToken = Security(get_user, scopes=["daybook"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
@@ -83,7 +82,11 @@ def build_report(start_date, finish_date, db):
{ {
"id": voucher.id, "id": voucher.id,
"date": voucher.date.strftime("%d-%b-%Y"), "date": voucher.date.strftime("%d-%b-%Y"),
"url": ["/", VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(), str(voucher.id),], "url": [
"/",
VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(),
str(voucher.id),
],
"type": VoucherType.by_id(voucher.type).name, "type": VoucherType.by_id(voucher.type).name,
"narration": voucher.narration, "narration": voucher.narration,
"posted": voucher.posted, "posted": voucher.posted,
+16 -13
View File
@@ -1,21 +1,19 @@
import datetime import datetime
import uuid import uuid
from fastapi import APIRouter, Depends, Security, Request import brewman.schemas.reports as schemas
from sqlalchemy.orm import joinedload_all, Session
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session, joinedload_all
from sqlalchemy.sql.expression import func from sqlalchemy.sql.expression import func
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal from ...db.session import SessionLocal
from brewman.models.master import AccountBase from ...models.master import AccountBase
from brewman.models.voucher import Voucher, Journal, VoucherType from ...models.voucher import Journal, Voucher, VoucherType
import brewman.schemas.reports as schemas from ...schemas.auth import UserToken
from ...core.session import (
set_period,
get_start_date,
get_finish_date,
)
router = APIRouter() router = APIRouter()
@@ -31,7 +29,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.Ledger) @router.get("", response_model=schemas.Ledger)
def show_blank( def show_blank(
request: Request, user: UserToken = Security(get_user, scopes=["ledger"]), request: Request,
user: UserToken = Security(get_user, scopes=["ledger"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
@@ -103,7 +102,11 @@ def build_report(account_id, start_date, finish_date, db):
"id": voucher.id, "id": voucher.id,
"date": voucher.date.strftime("%d-%b-%Y"), "date": voucher.date.strftime("%d-%b-%Y"),
"name": name, "name": name,
"url": ["/", VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(), str(voucher.id),], "url": [
"/",
VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(),
str(voucher.id),
],
"type": VoucherType.by_id(voucher.type).name, "type": VoucherType.by_id(voucher.type).name,
"narration": voucher.narration, "narration": voucher.narration,
"debit": debit, "debit": debit,
+20 -17
View File
@@ -1,20 +1,18 @@
from datetime import datetime, date from datetime import date, datetime
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func, desc
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.master import AccountBase
from brewman.models.voucher import Voucher, Journal, VoucherType
import brewman.schemas.reports as schemas import brewman.schemas.reports as schemas
from ...core.session import (
set_period, from fastapi import APIRouter, Depends, Request, Security
get_start_date, from sqlalchemy.orm import Session
get_finish_date, from sqlalchemy.sql.expression import desc, func
)
from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal
from ...models.master import AccountBase
from ...models.voucher import Journal, Voucher, VoucherType
from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -30,7 +28,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.NetTransactions) @router.get("", response_model=schemas.NetTransactions)
def show_blank( def show_blank(
request: Request, user: UserToken = Security(get_user, scopes=["net-transactions"]), request: Request,
user: UserToken = Security(get_user, scopes=["net-transactions"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
@@ -51,7 +50,11 @@ def show_data(
return { return {
"startDate": start, "startDate": start,
"finishDate": finish, "finishDate": finish,
"body": build_report(datetime.strptime(start, "%d-%b-%Y"), datetime.strptime(finish, "%d-%b-%Y"), db,), "body": build_report(
datetime.strptime(start, "%d-%b-%Y"),
datetime.strptime(finish, "%d-%b-%Y"),
db,
),
} }
+30 -17
View File
@@ -1,21 +1,20 @@
from datetime import datetime, date
import uuid import uuid
from fastapi import APIRouter, Depends, Security, Request from datetime import date, datetime
from sqlalchemy.orm import joinedload, Session
import brewman.schemas.reports as schemas
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session, joinedload
from sqlalchemy.sql.expression import func from sqlalchemy.sql.expression import func
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal from ...db.session import SessionLocal
from brewman.models.master import Product, CostCentre from ...models.master import CostCentre, Product
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory from ...models.voucher import Inventory, Journal, Voucher, VoucherType
import brewman.schemas.reports as schemas from ...schemas.auth import UserToken
from ...core.session import (
set_period,
get_start_date,
get_finish_date,
)
router = APIRouter() router = APIRouter()
@@ -31,7 +30,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.ProductLedger) @router.get("", response_model=schemas.ProductLedger)
def show_blank( def show_blank(
request: Request, user: UserToken = Security(get_user, scopes=["product-ledger"]), request: Request,
user: UserToken = Security(get_user, scopes=["product-ledger"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
@@ -54,7 +54,10 @@ def show_data(
start_date = s if s is not None else get_start_date(request.session) start_date = s if s is not None else get_start_date(request.session)
finish_date = f if f is not None else get_finish_date(request.session) finish_date = f if f is not None else get_finish_date(request.session)
body = build_report( body = build_report(
product.id, datetime.strptime(start_date, "%d-%b-%Y"), datetime.strptime(finish_date, "%d-%b-%Y"), db, product.id,
datetime.strptime(start_date, "%d-%b-%Y"),
datetime.strptime(finish_date, "%d-%b-%Y"),
db,
) )
set_period(start_date, finish_date, request.session) set_period(start_date, finish_date, request.session)
return { return {
@@ -72,7 +75,10 @@ def build_report(product_id: uuid.UUID, start_date: date, finish_date: date, db:
query = ( query = (
db.query(Voucher, Inventory, Journal) db.query(Voucher, Inventory, Journal)
.options(joinedload(Journal.account, innerjoin=True), joinedload(Journal.cost_centre, innerjoin=True),) .options(
joinedload(Journal.account, innerjoin=True),
joinedload(Journal.cost_centre, innerjoin=True),
)
.filter(Voucher.id == Inventory.voucher_id) .filter(Voucher.id == Inventory.voucher_id)
.filter(Voucher.id == Journal.voucher_id) .filter(Voucher.id == Journal.voucher_id)
.filter(Inventory.product_id == product_id) .filter(Inventory.product_id == product_id)
@@ -104,7 +110,11 @@ def build_report(product_id: uuid.UUID, start_date: date, finish_date: date, db:
"id": row.Voucher.id, "id": row.Voucher.id,
"date": row.Voucher.date.strftime("%d-%b-%Y"), "date": row.Voucher.date.strftime("%d-%b-%Y"),
"name": name, "name": name,
"url": ["/", VoucherType.by_id(row.Voucher.type).name.replace(" ", "-").lower(), str(row.Voucher.id),], "url": [
"/",
VoucherType.by_id(row.Voucher.type).name.replace(" ", "-").lower(),
str(row.Voucher.id),
],
"type": VoucherType.by_id(row.Voucher.type).name, "type": VoucherType.by_id(row.Voucher.type).name,
"narration": row.Voucher.narration, "narration": row.Voucher.narration,
"posted": row.Voucher.posted or VoucherType.by_id(row.Voucher.type).name == "Issue", "posted": row.Voucher.posted or VoucherType.by_id(row.Voucher.type).name == "Issue",
@@ -122,7 +132,10 @@ def build_report(product_id: uuid.UUID, start_date: date, finish_date: date, db:
def opening_balance(product_id: uuid.UUID, start_date: date, db: Session): def opening_balance(product_id: uuid.UUID, start_date: date, db: Session):
quantity, amount = ( quantity, amount = (
db.query(func.sum(Inventory.quantity * Journal.debit), func.sum(Inventory.amount * Journal.debit),) db.query(
func.sum(Inventory.quantity * Journal.debit),
func.sum(Inventory.amount * Journal.debit),
)
.join(Inventory.voucher) .join(Inventory.voucher)
.join(Voucher.journals) .join(Voucher.journals)
.filter(Voucher.id == Inventory.voucher_id) .filter(Voucher.id == Inventory.voucher_id)
+21 -18
View File
@@ -1,21 +1,19 @@
from datetime import datetime, date from datetime import date, datetime
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func, desc
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.master import AccountType, AccountBase
from brewman.models.voucher import Voucher, Journal, VoucherType
from brewman.routers.reports.closing_stock import get_opening_stock, get_closing_stock
import brewman.schemas.reports as schemas import brewman.schemas.reports as schemas
from ...core.session import (
set_period, from fastapi import APIRouter, Depends, Request, Security
get_start_date, from sqlalchemy.orm import Session
get_finish_date, from sqlalchemy.sql.expression import desc, func
)
from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal
from ...models.master import AccountBase, AccountType
from ...models.voucher import Journal, Voucher, VoucherType
from ...routers.reports.closing_stock import get_closing_stock, get_opening_stock
from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -31,7 +29,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.ProfitLoss) @router.get("", response_model=schemas.ProfitLoss)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["profit-&-loss"]), request: Request,
user: UserToken = Security(get_user, scopes=["profit-&-loss"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
@@ -103,7 +102,11 @@ def build_profit_loss(start_date: date, finish_date: date, db: Session):
if amount != 0: if amount != 0:
counter += 10 counter += 10
report.append( report.append(
{"name": account.name, "amount": amount, "order": account_type.order + counter,} {
"name": account.name,
"amount": amount,
"order": account_type.order + counter,
}
) )
if account_type.id in groups: if account_type.id in groups:
groups[account_type.id]["total"] += amount groups[account_type.id]["total"] += amount
+16 -12
View File
@@ -1,18 +1,17 @@
from datetime import datetime, date from datetime import date, datetime
from typing import List from typing import List
from fastapi import APIRouter, Depends, Security, Request
import brewman.schemas.reports as schemas
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal from ...db.session import SessionLocal
from brewman.models.voucher import Voucher, VoucherType from ...models.voucher import Voucher, VoucherType
import brewman.schemas.reports as schemas from ...schemas.auth import UserToken
from ...core.session import (
set_period,
get_start_date,
get_finish_date,
)
router = APIRouter() router = APIRouter()
@@ -28,7 +27,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.PurchaseEntries) @router.get("", response_model=schemas.PurchaseEntries)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["purchase-entries"]), request: Request,
user: UserToken = Security(get_user, scopes=["purchase-entries"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
@@ -70,7 +70,11 @@ def build_report(start_date: date, finish_date, db):
row = { row = {
"date": voucher.date.strftime("%d-%b-%Y"), "date": voucher.date.strftime("%d-%b-%Y"),
"supplier": journal.account.name, "supplier": journal.account.name,
"url": ["/", VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(), str(voucher.id),], "url": [
"/",
VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(),
str(voucher.id),
],
"product": item.product.full_name, "product": item.product.full_name,
"quantity": item.quantity, "quantity": item.quantity,
"rate": item.rate, "rate": item.rate,
+24 -18
View File
@@ -1,21 +1,18 @@
import datetime import datetime
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func, desc
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.master import CostCentre, Product
from brewman.models.voucher import Voucher, Journal, Inventory, VoucherType
import brewman.schemas.reports as schemas import brewman.schemas.reports as schemas
from ...core.session import (
set_period, from fastapi import APIRouter, Depends, Request, Security
get_start_date, from sqlalchemy.orm import Session
get_finish_date, from sqlalchemy.sql.expression import desc, func
)
from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal
from ...models.master import CostCentre, Product
from ...models.voucher import Inventory, Journal, Voucher, VoucherType
from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -31,10 +28,14 @@ def get_db() -> Session:
@router.get("", response_model=schemas.Purchases) @router.get("", response_model=schemas.Purchases)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["purchases"]), request: Request,
user: UserToken = Security(get_user, scopes=["purchases"]),
): ):
return schemas.Purchases( return schemas.Purchases(
startDate=get_start_date(request.session), finishDate=get_finish_date(request.session), body=[], footer=None, startDate=get_start_date(request.session),
finishDate=get_finish_date(request.session),
body=[],
footer=None,
) )
@@ -48,7 +49,12 @@ def report_data(
): ):
body, footer = build_report(start, finish, db) body, footer = build_report(start, finish, db)
set_period(start, finish, request.session) set_period(start, finish, request.session)
return schemas.Purchases(startDate=start, finishDate=finish, body=body, footer=footer,) return schemas.Purchases(
startDate=start,
finishDate=finish,
body=body,
footer=footer,
)
def build_report(start_date, finish_date, db): def build_report(start_date, finish_date, db):
+15 -15
View File
@@ -1,21 +1,20 @@
from datetime import datetime, date
import uuid import uuid
from fastapi import APIRouter, Depends, Security, Request from datetime import date, datetime
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func, case
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.master import AccountBase, CostCentre, Product, ProductGroup
from brewman.models.voucher import Voucher, Journal, Inventory
import brewman.schemas.reports as schemas import brewman.schemas.reports as schemas
from ...core.session import (
set_period, from fastapi import APIRouter, Depends, Request, Security
get_start_date, from sqlalchemy.orm import Session
get_finish_date, from sqlalchemy.sql.expression import case, func
)
from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal
from ...models.master import AccountBase, CostCentre, Product, ProductGroup
from ...models.voucher import Inventory, Journal, Voucher
from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -31,7 +30,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.RawMaterialCost) @router.get("", response_model=schemas.RawMaterialCost)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["raw-material-cost"]), request: Request,
user: UserToken = Security(get_user, scopes=["raw-material-cost"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
+10 -13
View File
@@ -1,21 +1,17 @@
import datetime import datetime
import uuid import uuid
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session, joinedload_all
from sqlalchemy.sql.expression import and_, func, or_
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import joinedload_all, Session
from sqlalchemy.sql.expression import func, or_, and_
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal from ...db.session import SessionLocal
from brewman.models.master import AccountBase from ...models.master import AccountBase
from brewman.models.voucher import Voucher, Journal, VoucherType from ...models.voucher import Journal, Voucher, VoucherType
from ...core.session import ( from ...schemas.auth import UserToken
set_period,
get_start_date,
get_finish_date,
)
router = APIRouter() router = APIRouter()
@@ -31,7 +27,8 @@ def get_db() -> Session:
@router.get("") @router.get("")
def show_blank( def show_blank(
request: Request, user: UserToken = Security(get_user, scopes=["reconcile"]), request: Request,
user: UserToken = Security(get_user, scopes=["reconcile"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
+11 -12
View File
@@ -1,21 +1,19 @@
from datetime import datetime, date from datetime import date, datetime
from decimal import Decimal from decimal import Decimal
from fastapi import APIRouter, Depends, Security, Request import brewman.schemas.reports as schemas
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func from sqlalchemy.sql.expression import func
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal from ...db.session import SessionLocal
from brewman.models.master import Product, CostCentre from ...models.master import CostCentre, Product
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory from ...models.voucher import Inventory, Journal, Voucher, VoucherType
import brewman.schemas.reports as schemas from ...schemas.auth import UserToken
from ...core.session import (
set_period,
get_start_date,
get_finish_date,
)
router = APIRouter() router = APIRouter()
@@ -31,7 +29,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.StockMovement) @router.get("", response_model=schemas.StockMovement)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["stock-movement"]), request: Request,
user: UserToken = Security(get_user, scopes=["stock-movement"]),
): ):
return { return {
"startDate": get_start_date(request.session), "startDate": get_start_date(request.session),
+11 -12
View File
@@ -1,20 +1,18 @@
from datetime import datetime, date from datetime import date, datetime
from fastapi import APIRouter, Depends, Security, Request import brewman.schemas.reports as schemas
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func from sqlalchemy.sql.expression import func
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user from ...core.security import get_current_active_user as get_user
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal from ...db.session import SessionLocal
from brewman.models.master import AccountBase from ...models.master import AccountBase
from brewman.models.voucher import Voucher, Journal, VoucherType from ...models.voucher import Journal, Voucher, VoucherType
import brewman.schemas.reports as schemas from ...schemas.auth import UserToken
from ...core.session import (
set_period,
get_start_date,
get_finish_date,
)
router = APIRouter() router = APIRouter()
@@ -30,7 +28,8 @@ def get_db() -> Session:
@router.get("", response_model=schemas.TrialBalance) @router.get("", response_model=schemas.TrialBalance)
def report_blank( def report_blank(
request: Request, user: UserToken = Security(get_user, scopes=["trial-balance"]), request: Request,
user: UserToken = Security(get_user, scopes=["trial-balance"]),
): ):
return {"date": get_finish_date(request.session), "body": []} return {"date": get_finish_date(request.session), "body": []}
+15 -7
View File
@@ -1,13 +1,15 @@
from typing import List from typing import List
from fastapi import APIRouter, Depends, Security, Request import brewman.schemas.reports as schemas
from sqlalchemy.orm import joinedload_all, Session
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session, joinedload_all
from ...schemas.auth import UserToken
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 SessionLocal from ...db.session import SessionLocal
from brewman.models.voucher import Voucher, Journal, VoucherType from ...models.voucher import Journal, Voucher, VoucherType
import brewman.schemas.reports as schemas from ...schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -23,7 +25,9 @@ def get_db() -> Session:
@router.get("", response_model=List[schemas.Unposted]) @router.get("", response_model=List[schemas.Unposted])
def report_data( def report_data(
request: Request, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["post-vouchers"]), request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["post-vouchers"]),
): ):
return build_report(db) return build_report(db)
@@ -60,7 +64,11 @@ def build_report(db: Session):
{ {
"id": voucher.id, "id": voucher.id,
"date": voucher.date.strftime("%d-%b-%Y"), "date": voucher.date.strftime("%d-%b-%Y"),
"url": ["/", VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(), str(voucher.id),], "url": [
"/",
VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(),
str(voucher.id),
],
"type": VoucherType.by_id(voucher.type).name, "type": VoucherType.by_id(voucher.type).name,
"narration": voucher.narration, "narration": voucher.narration,
"debitName": name_debit, "debitName": name_debit,
+25 -14
View File
@@ -1,22 +1,17 @@
import uuid import uuid
from fastapi import ( from fastapi import APIRouter, Depends, HTTPException, Security, status
APIRouter,
Depends,
status,
Security,
HTTPException,
)
from sqlalchemy import func from sqlalchemy import func
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..models import Inventory, Journal, Voucher, Batch, VoucherType
from ..models.master import Product, CostCentre, AccountBase
from ..schemas.auth import UserToken
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 SessionLocal from ..db.session import SessionLocal
from ..models import Batch, Inventory, Journal, Voucher, VoucherType
from ..models.master import AccountBase, CostCentre, Product
from ..schemas.auth import UserToken
from ..schemas.settings import ResetStock from ..schemas.settings import ResetStock
router = APIRouter() router = APIRouter()
@@ -40,7 +35,8 @@ def rebase(
if item.reset_date > item.stock_date: if item.reset_date > item.stock_date:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Reset cannot be after the stock date", status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Reset cannot be after the stock date",
) )
change = round(item.quantity, 2) - get_closing_stock(product, item.stock_date, db=db) change = round(item.quantity, 2) - get_closing_stock(product, item.stock_date, db=db)
@@ -95,7 +91,12 @@ def set_batches(batch, quantity, db):
def create_voucher(batch, quantity, date_, user_id, db): def create_voucher(batch, quantity, date_, user_id, db):
voucher = Voucher(date=date_, narration="Product Reset", user_id=user_id, type_=VoucherType.by_name("Issue"),) voucher = Voucher(
date=date_,
narration="Product Reset",
user_id=user_id,
type_=VoucherType.by_name("Issue"),
)
db.add(voucher) db.add(voucher)
if quantity > 0: if quantity > 0:
@@ -117,9 +118,19 @@ def create_voucher(batch, quantity, date_, user_id, db):
db.add(inventory) db.add(inventory)
amount = round(inventory.amount, 2) amount = round(inventory.amount, 2)
source = Journal(debit=-1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=source,) source = Journal(
debit=-1,
account_id=AccountBase.all_purchases(),
amount=amount,
cost_centre_id=source,
)
voucher.journals.append(source) voucher.journals.append(source)
db.add(source) db.add(source)
destination = Journal(debit=1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=destination,) destination = Journal(
debit=1,
account_id=AccountBase.all_purchases(),
amount=amount,
cost_centre_id=destination,
)
voucher.journals.append(destination) voucher.journals.append(destination)
db.add(destination) db.add(destination)
+46 -40
View File
@@ -1,40 +1,31 @@
import uuid import uuid
from typing import Optional
from datetime import datetime, date
from decimal import Decimal
from fastapi import ( from datetime import date, datetime
APIRouter, from decimal import Decimal
HTTPException, from typing import Optional
status,
Depends, import brewman.schemas.voucher as output
Security,
) from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import func, or_ from sqlalchemy import func, or_
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from brewman.models.master import (
AccountBase,
CostCentre,
Employee,
AttendanceType,
Account,
)
from brewman.models.voucher import (
VoucherType,
Inventory,
DbImage,
Attendance,
Journal,
)
from brewman.routers import get_lock_info
from brewman.core.session import get_first_day
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user from ..core.security import get_current_active_user as get_user
from ..core.session import get_first_day
from ..db.session import SessionLocal from ..db.session import SessionLocal
from ..models.voucher import Voucher from ..models.master import Account, AccountBase, AttendanceType, CostCentre, Employee
import brewman.schemas.voucher as output from ..models.voucher import (
Attendance,
DbImage,
Inventory,
Journal,
Voucher,
VoucherType,
)
from ..routers import get_lock_info
from ..schemas.auth import UserToken
router = APIRouter() router = APIRouter()
@@ -50,7 +41,9 @@ def get_db() -> Session:
@router.post("/post-voucher/{id_}", response_model=output.Voucher) @router.post("/post-voucher/{id_}", response_model=output.Voucher)
def post_voucher( def post_voucher(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["post-vouchers"]), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["post-vouchers"]),
): ):
try: try:
voucher: Voucher = db.query(Voucher).filter(Voucher.id == id_).first() voucher: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
@@ -62,7 +55,8 @@ def post_voucher(
except SQLAlchemyError as e: except SQLAlchemyError as e:
db.rollback() db.rollback()
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
) )
except Exception: except Exception:
db.rollback() db.rollback()
@@ -75,11 +69,13 @@ def check_delete_permissions(voucher: Voucher, user: UserToken):
voucher_type = "journal" voucher_type = "journal"
if voucher.posted and "edit-posted-vouchers" not in user.permissions: if voucher.posted and "edit-posted-vouchers" not in user.permissions:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit posted vouchers", status_code=status.HTTP_403_FORBIDDEN,
detail="You are not allowed to edit posted vouchers",
) )
elif voucher.user_id != user.id_ and "edit-other-user's-vouchers" not in user.permissions: elif voucher.user_id != user.id_ and "edit-other-user's-vouchers" not in user.permissions:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit other user's vouchers", status_code=status.HTTP_403_FORBIDDEN,
detail="You are not allowed to edit other user's vouchers",
) )
elif voucher_type not in user.permissions: elif voucher_type not in user.permissions:
raise HTTPException( raise HTTPException(
@@ -90,7 +86,9 @@ def check_delete_permissions(voucher: Voucher, user: UserToken):
@router.delete("/delete/{id_}") @router.delete("/delete/{id_}")
def delete_voucher( def delete_voucher(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user), id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user),
): ):
voucher: Voucher = db.query(Voucher).filter(Voucher.id == id_).first() voucher: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
images = db.query(DbImage).filter(DbImage.resource_id == voucher.id).all() images = db.query(DbImage).filter(DbImage.resource_id == voucher.id).all()
@@ -247,7 +245,10 @@ def voucher_info(voucher, db):
"tax": item.batch.tax, "tax": item.batch.tax,
"discount": item.batch.discount, "discount": item.batch.discount,
"rate": item.batch.rate, "rate": item.batch.rate,
"product": {"id": item.batch.product.id, "name": item.batch.product.full_name,}, "product": {
"id": item.batch.product.id,
"name": item.batch.product.full_name,
},
}, },
} }
) )
@@ -266,12 +267,14 @@ def voucher_info(voucher, db):
def blank_voucher(info, db): def blank_voucher(info, db):
if "type" not in info: if "type" not in info:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Voucher Type is null", status_code=status.HTTP_404_NOT_FOUND,
detail="Voucher Type is null",
) )
type_ = info["type"] type_ = info["type"]
if "date" not in info: if "date" not in info:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=f"Date cannot be null", status_code=status.HTTP_404_NOT_FOUND,
detail=f"Date cannot be null",
) )
json_voucher = { json_voucher = {
"type": type_, "type": type_,
@@ -323,7 +326,8 @@ def blank_voucher(info, db):
json_voucher["incentives"], json_voucher["incentive"] = incentive_employees(info["date"], db) json_voucher["incentives"], json_voucher["incentive"] = incentive_employees(info["date"], db)
else: else:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=f'Voucher of type "{type_}" does not exist.', status_code=status.HTTP_404_NOT_FOUND,
detail=f'Voucher of type "{type_}" does not exist.',
) )
json_voucher["files"] = [] json_voucher["files"] = []
return json_voucher return json_voucher
@@ -403,9 +407,11 @@ def check_voucher_lock_info(voucher_date: Optional[date], data_date: date, db: S
def check_voucher_edit_allowed(voucher: Voucher, user: UserToken): def check_voucher_edit_allowed(voucher: Voucher, user: UserToken):
if voucher.posted and "edit-posted-vouchers" not in user.permissions: if voucher.posted and "edit-posted-vouchers" not in user.permissions:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit posted vouchers", status_code=status.HTTP_403_FORBIDDEN,
detail="You are not allowed to edit posted vouchers",
) )
elif voucher.user_id != user.id_ and "edit-other-user's-vouchers" not in user.permissions: elif voucher.user_id != user.id_ and "edit-other-user's-vouchers" not in user.permissions:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit other user's vouchers", status_code=status.HTTP_403_FORBIDDEN,
detail="You are not allowed to edit other user's vouchers",
) )
+3 -2
View File
@@ -1,9 +1,10 @@
import uuid import uuid
from typing import List, Optional
from datetime import datetime from datetime import datetime
from pydantic import BaseModel from typing import List, Optional
from brewman.schemas import to_camel from brewman.schemas import to_camel
from pydantic import BaseModel
class ClientIn(BaseModel): class ClientIn(BaseModel):
+9 -9
View File
@@ -1,22 +1,22 @@
import uuid
import json import json
from datetime import datetime, date import uuid
from datetime import date, datetime
from decimal import Decimal from decimal import Decimal
from typing import List, Optional from typing import List, Optional
from fastapi import Form
from pydantic import validator, BaseModel, Field
from sqlalchemy.orm import Session
from brewman.schemas import to_camel from brewman.schemas import to_camel
from brewman.schemas.master import AccountLink, CostCentreLink from brewman.schemas.master import AccountLink, CostCentreLink
from brewman.schemas.voucher import ( from brewman.schemas.voucher import (
VoucherIn,
Journal,
Inventory,
EmployeeBenefit, EmployeeBenefit,
Incentive, Incentive,
Inventory,
Journal,
VoucherIn,
) )
from fastapi import Form
from pydantic import BaseModel, Field, validator
from sqlalchemy.orm import Session
class JournalIn(VoucherIn): class JournalIn(VoucherIn):
+3 -3
View File
@@ -1,11 +1,11 @@
import uuid import uuid
from typing import Optional
from datetime import date, datetime from datetime import date, datetime
from decimal import Decimal from decimal import Decimal
from typing import Optional
from pydantic import BaseModel, Field, validator
from brewman.schemas import to_camel from brewman.schemas import to_camel
from pydantic import BaseModel, Field, validator
class AccountLink(BaseModel): class AccountLink(BaseModel):
+3 -2
View File
@@ -1,11 +1,12 @@
import uuid import uuid
from datetime import date, datetime
from decimal import Decimal from decimal import Decimal
from typing import List, Optional from typing import List, Optional
from datetime import datetime, date
from pydantic import BaseModel, Field, validator
from brewman.schemas import to_camel from brewman.schemas import to_camel
from brewman.schemas.master import AccountLink, ProductLink from brewman.schemas.master import AccountLink, ProductLink
from pydantic import BaseModel, Field, validator
class LedgerItem(BaseModel): class LedgerItem(BaseModel):
+2 -2
View File
@@ -1,9 +1,9 @@
from datetime import date, datetime
from decimal import Decimal from decimal import Decimal
from typing import Optional from typing import Optional
from datetime import datetime, date
from pydantic import BaseModel, validator
from brewman.schemas import to_camel from brewman.schemas import to_camel
from pydantic import BaseModel, validator
class LockInformation(BaseModel): class LockInformation(BaseModel):
+7 -7
View File
@@ -1,19 +1,19 @@
import uuid
import json import json
from datetime import datetime, date import uuid
from decimal import Decimal
from typing import List, Optional, Any
from fastapi import Form from datetime import date, datetime
from pydantic import BaseModel, validator, Field from decimal import Decimal
from typing import Any, List, Optional
from brewman.schemas import to_camel from brewman.schemas import to_camel
from brewman.schemas.master import ( from brewman.schemas.master import (
AccountLink, AccountLink,
CostCentreLink, CostCentreLink,
ProductLink,
EmployeeLink, EmployeeLink,
ProductLink,
) )
from fastapi import Form
from pydantic import BaseModel, Field, validator
class ImageUpload(BaseModel): class ImageUpload(BaseModel):
+22 -16
View File
@@ -1,46 +1,46 @@
import os import os
import sys import sys
import transaction
import uuid import uuid
from pyramid.paster import get_appsettings, setup_logging import transaction
from pyramid.scripts.common import parse_vars
from ..models.meta import Base
from ..models import get_engine, get_session_factory, get_tm_session
from brewman.models.auth import ( from brewman.models.auth import (
Client, Client,
Group, Group,
LoginHistory,
Role, Role,
User, User,
role_group, role_group,
user_group, user_group,
LoginHistory,
) )
from brewman.models.master import ( from brewman.models.master import (
Product,
CostCentre,
Employee,
Account, Account,
AccountBase, AccountBase,
CostCentre,
DbSetting,
Employee,
Product,
ProductGroup, ProductGroup,
Recipe, Recipe,
RecipeItem, RecipeItem,
DbSetting,
) )
from brewman.models.voucher import ( from brewman.models.voucher import (
Attendance, Attendance,
Batch, Batch,
DbImage,
EmployeeBenefit,
Fingerprint, Fingerprint,
Incentive,
Inventory, Inventory,
Journal, Journal,
Product, Product,
EmployeeBenefit,
Voucher, Voucher,
Incentive,
DbImage,
) )
from pyramid.paster import get_appsettings, setup_logging
from pyramid.scripts.common import parse_vars
from ..models import get_engine, get_session_factory, get_tm_session
from ..models.meta import Base
def usage(argv): def usage(argv):
@@ -85,7 +85,10 @@ def main(argv=sys.argv):
Role("Cost Centres", uuid.UUID("6fcc1a20-6aec-e840-b334-1632b34aeab8")), Role("Cost Centres", uuid.UUID("6fcc1a20-6aec-e840-b334-1632b34aeab8")),
Role("Users", uuid.UUID("c5b7d9d7-f178-0e45-8ea4-bf4e08ec901b")), Role("Users", uuid.UUID("c5b7d9d7-f178-0e45-8ea4-bf4e08ec901b")),
Role("Daybook", uuid.UUID("c3edb554-a057-8942-8030-37b8e926d583")), Role("Daybook", uuid.UUID("c3edb554-a057-8942-8030-37b8e926d583")),
Role("Edit Posted Vouchers", uuid.UUID("d6675817-ddf5-bf40-9de6-fa223eb4aaa6"),), Role(
"Edit Posted Vouchers",
uuid.UUID("d6675817-ddf5-bf40-9de6-fa223eb4aaa6"),
),
Role("Employees", uuid.UUID("e4edd0ac-7f5d-e64d-8611-73fdc4cd8ba2")), Role("Employees", uuid.UUID("e4edd0ac-7f5d-e64d-8611-73fdc4cd8ba2")),
Role("Fingerprints", uuid.UUID("d9c45323-f997-ba46-9407-8a7145f0828b")), Role("Fingerprints", uuid.UUID("d9c45323-f997-ba46-9407-8a7145f0828b")),
Role("Issue", uuid.UUID("03b602eb-f58a-b94f-af58-8cb47d7849d0")), Role("Issue", uuid.UUID("03b602eb-f58a-b94f-af58-8cb47d7849d0")),
@@ -106,7 +109,10 @@ def main(argv=sys.argv):
Role("Closing Stock", uuid.UUID("97515732-24e4-c94d-9585-d4bd7f6c7891")), Role("Closing Stock", uuid.UUID("97515732-24e4-c94d-9585-d4bd7f6c7891")),
Role("Ledger", uuid.UUID("a2120944-243f-3f49-be57-0ad633ce4801")), Role("Ledger", uuid.UUID("a2120944-243f-3f49-be57-0ad633ce4801")),
Role("Raw Material Cost", uuid.UUID("d462842b-baf1-2343-95e5-ffdba9bbc163")), Role("Raw Material Cost", uuid.UUID("d462842b-baf1-2343-95e5-ffdba9bbc163")),
Role("Edit Other User's Vouchers", uuid.UUID("a8328891-7ce2-a943-8c29-2eabc1ffeea3"),), Role(
"Edit Other User's Vouchers",
uuid.UUID("a8328891-7ce2-a943-8c29-2eabc1ffeea3"),
),
Role("Clients", uuid.UUID("cfad44f0-f2a9-7045-89d7-9019cf0f371a")), Role("Clients", uuid.UUID("cfad44f0-f2a9-7045-89d7-9019cf0f371a")),
Role("Employee Benefit", uuid.UUID("92d70e80-1c32-384d-959e-abf84b804696")), Role("Employee Benefit", uuid.UUID("92d70e80-1c32-384d-959e-abf84b804696")),
Role("Messages", uuid.UUID("f586d128-b6d9-4090-a913-78fcbdb68e59")), Role("Messages", uuid.UUID("f586d128-b6d9-4090-a913-78fcbdb68e59")),
+31 -1
View File
@@ -23,10 +23,40 @@ starlette = "^0.13.6"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
flake8 = "^3.8.4" flake8 = "^3.8.4"
black = "^20.8b1" black = "^20.8b1"
isort = {extras = ["toml"], version = "^5.5.4"}
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
[tool.isort]
profile = "black"
atomic = true
include_trailing_comma = true
lines_after_imports = 2
lines_between_types = 1
use_parentheses = true
src_paths = ["poetry", "tests"]
skip_glob = ["*/setup.py"]
filter_files = true
known_first_party = "poetry"
[tool.black] [tool.black]
line-length = 120 line-length = 88
include = '\.pyi?$'
exclude = '''
/(
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
| tests/.*/setup.py
)/
'''