Chore:
Blacked and isorted all files
This commit is contained in:
1 parent
40f1f59f9d
commit
cb5f52fcc7
71 files changed
+1395
-865
No files matched your search
@@ -1,3 +1,4 @@
|
|||||||
from brewman.main import init
|
from brewman.main import init
|
||||||
|
|
||||||
|
|
||||||
init()
|
init()
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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,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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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,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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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)
|
||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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()
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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 []
|
||||||
|
|||||||
@@ -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
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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()
|
||||||
|
|||||||
@@ -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
@@ -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()
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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"}
|
||||||
@@ -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
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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)
|
||||||
@@ -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
@@ -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
@@ -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:
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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}]
|
||||||
@@ -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": []}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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": []}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
@@ -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",
|
||||||
)
|
)
|
||||||
@@ -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):
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
)/
|
||||||
|
'''
|
||||||
Reference in new issue
Block a user