Attendance Done!!
Changed the datatype of dates in attendance and employee to date from datetime this might bork things in other places
This commit is contained in:
parent
0a79b1acbb
commit
bd05e6bb17
alembic
brewman
core
models
routers
schemas
overlord/src/app
@ -50,6 +50,7 @@ def run_migrations_offline():
|
|||||||
target_metadata=target_metadata,
|
target_metadata=target_metadata,
|
||||||
literal_binds=True,
|
literal_binds=True,
|
||||||
dialect_opts={"paramstyle": "named"},
|
dialect_opts={"paramstyle": "named"},
|
||||||
|
compare_type=True
|
||||||
)
|
)
|
||||||
|
|
||||||
with context.begin_transaction():
|
with context.begin_transaction():
|
||||||
@ -73,7 +74,8 @@ def run_migrations_online():
|
|||||||
|
|
||||||
with connectable.connect() as connection:
|
with connectable.connect() as connection:
|
||||||
context.configure(
|
context.configure(
|
||||||
connection=connection, target_metadata=target_metadata
|
connection=connection, target_metadata=target_metadata,
|
||||||
|
compare_type=True
|
||||||
)
|
)
|
||||||
|
|
||||||
with context.begin_transaction():
|
with context.begin_transaction():
|
||||||
|
54
alembic/versions/03ea3e9cb1e5_rename_further.py
Normal file
54
alembic/versions/03ea3e9cb1e5_rename_further.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
"""test
|
||||||
|
|
||||||
|
Revision ID: 03ea3e9cb1e5
|
||||||
|
Revises: 5498fc4bf58d
|
||||||
|
Create Date: 2020-05-14 21:25:08.945280
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '03ea3e9cb1e5'
|
||||||
|
down_revision = '5498fc4bf58d'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table("attendances") as batch_op:
|
||||||
|
batch_op.alter_column('date', type_=sa.Date(), nullable=False)
|
||||||
|
with op.batch_alter_table("employees") as batch_op:
|
||||||
|
batch_op.alter_column('Designation', new_column_name='designation', nullable=False)
|
||||||
|
batch_op.alter_column('Salary', new_column_name='salary', nullable=False)
|
||||||
|
batch_op.alter_column('ServicePoints', new_column_name='points', nullable=False)
|
||||||
|
batch_op.alter_column('JoiningDate', new_column_name='joining_date', type_=sa.Date(), nullable=False)
|
||||||
|
batch_op.alter_column('LeavingDate', new_column_name='leaving_date', type_=sa.Date(), nullable=True)
|
||||||
|
with op.batch_alter_table("settings") as batch_op:
|
||||||
|
batch_op.alter_column('SettingID', new_column_name='id')
|
||||||
|
batch_op.alter_column('Name', new_column_name='name')
|
||||||
|
batch_op.alter_column('Data', new_column_name='data')
|
||||||
|
op.create_unique_constraint(op.f('uq_settings_name'), 'settings', ['name'])
|
||||||
|
op.drop_constraint('uq_settings_Name', 'settings', type_='unique')
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table("attendances") as batch_op:
|
||||||
|
batch_op.alter_column('date', type_=sa.DateTime())
|
||||||
|
with op.batch_alter_table("employees") as batch_op:
|
||||||
|
batch_op.alter_column('designation', new_column_name='Designation', nullable=True)
|
||||||
|
batch_op.alter_column('salary', new_column_name='Salary', nullable=True)
|
||||||
|
batch_op.alter_column('points', new_column_name='ServicePoints', nullable=True)
|
||||||
|
batch_op.alter_column('joining_date', new_column_name='JoiningDate', type_=sa.DateTime(), nullable=True)
|
||||||
|
batch_op.alter_column('leaving_date', new_column_name='LeavingDate', type_=sa.DateTime(), nullable=True)
|
||||||
|
with op.batch_alter_table("settings") as batch_op:
|
||||||
|
batch_op.alter_column('id', new_column_name='SettingID')
|
||||||
|
batch_op.alter_column('name', new_column_name='Name')
|
||||||
|
batch_op.alter_column('data', new_column_name='Data')
|
||||||
|
op.create_unique_constraint('uq_settings_Name', 'settings', ['name'])
|
||||||
|
op.drop_constraint(op.f('uq_settings_name'), 'settings', type_='unique')
|
||||||
|
# ### end Alembic commands ###
|
@ -7,7 +7,7 @@ def get_date(session) -> str:
|
|||||||
return session["date"]
|
return session["date"]
|
||||||
|
|
||||||
|
|
||||||
def set_date(session, date_):
|
def set_date(date_, session):
|
||||||
session["date"] = date_
|
session["date"] = date_
|
||||||
return session["date"]
|
return session["date"]
|
||||||
|
|
||||||
|
@ -392,11 +392,11 @@ class Employee(AccountBase):
|
|||||||
__mapper_args__ = {"polymorphic_identity": "employees"}
|
__mapper_args__ = {"polymorphic_identity": "employees"}
|
||||||
|
|
||||||
id = Column("id", GUID(), ForeignKey(AccountBase.id), primary_key=True)
|
id = Column("id", GUID(), ForeignKey(AccountBase.id), primary_key=True)
|
||||||
designation = Column("Designation", Unicode(255))
|
designation = Column("designation", Unicode(255), nullable=False)
|
||||||
salary = Column("Salary", Integer)
|
salary = Column("salary", Integer, nullable=False)
|
||||||
points = Column("ServicePoints", Numeric(precision=5, scale=2))
|
points = Column("points", Numeric(precision=5, scale=2), nullable=False)
|
||||||
joining_date = Column("JoiningDate", DateTime)
|
joining_date = Column("joining_date", Date, nullable=False)
|
||||||
leaving_date = Column("LeavingDate", DateTime)
|
leaving_date = Column("leaving_date", Date, nullable=True)
|
||||||
|
|
||||||
attendances = relationship(
|
attendances = relationship(
|
||||||
"Attendance", backref="employee", cascade=None, cascade_backrefs=False
|
"Attendance", backref="employee", cascade=None, cascade_backrefs=False
|
||||||
@ -562,9 +562,9 @@ class AccountType:
|
|||||||
class DbSetting(Base):
|
class DbSetting(Base):
|
||||||
__tablename__ = "settings"
|
__tablename__ = "settings"
|
||||||
|
|
||||||
id = Column("SettingID", GUID(), primary_key=True, default=uuid.uuid4)
|
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
|
||||||
name = Column("Name", Unicode(255), unique=True, nullable=False)
|
name = Column("name", Unicode(255), unique=True, nullable=False)
|
||||||
data = Column("Data", PickleType)
|
data = Column("data", PickleType)
|
||||||
|
|
||||||
def __init__(self, id=None, name=None, data=None):
|
def __init__(self, id=None, name=None, data=None):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
@ -9,7 +9,7 @@ from sqlalchemy import (
|
|||||||
DateTime,
|
DateTime,
|
||||||
Numeric,
|
Numeric,
|
||||||
ForeignKey,
|
ForeignKey,
|
||||||
UniqueConstraint,
|
UniqueConstraint, Date,
|
||||||
)
|
)
|
||||||
from sqlalchemy.dialects.postgresql import BYTEA
|
from sqlalchemy.dialects.postgresql import BYTEA
|
||||||
from sqlalchemy.ext.hybrid import hybrid_property
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
@ -378,7 +378,7 @@ class Attendance(Base):
|
|||||||
|
|
||||||
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
|
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
|
||||||
employee_id = Column("employee_id", GUID(), ForeignKey("employees.id"))
|
employee_id = Column("employee_id", GUID(), ForeignKey("employees.id"))
|
||||||
date = Column("date", DateTime)
|
date = Column("date", Date, nullable=False)
|
||||||
attendance_type = Column("attendance_type", Integer)
|
attendance_type = Column("attendance_type", Integer)
|
||||||
amount = Column("amount", Numeric)
|
amount = Column("amount", Numeric)
|
||||||
creation_date = Column("creation_date", DateTime(timezone=True))
|
creation_date = Column("creation_date", DateTime(timezone=True))
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
|
from typing import List
|
||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
|
|
||||||
from ..schemas.auth import UserToken
|
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 brewman.models.master import AccountType
|
from brewman.models.master import AccountType
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("")
|
@router.get("", response_model=List[schemas.AccountType])
|
||||||
def account_type_list(user: UserToken = Depends(get_user)):
|
def account_type_list(user: UserToken = Depends(get_user)):
|
||||||
return [
|
return [
|
||||||
{"id": item.id, "name": item.name}
|
schemas.AccountType(id=item.id, name=item.name)
|
||||||
for item in AccountType.list()
|
for item in AccountType.list()
|
||||||
]
|
]
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import uuid
|
import traceback
|
||||||
from datetime import datetime, date, timedelta
|
from datetime import datetime, date, timedelta, time
|
||||||
|
|
||||||
from fastapi import APIRouter, HTTPException, status, Depends, Security, Request
|
from fastapi import APIRouter, HTTPException, status, Depends, Security, Request
|
||||||
from sqlalchemy import or_
|
from sqlalchemy import or_
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from ..schemas.auth import UserToken
|
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
|
||||||
@ -10,7 +11,7 @@ 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
|
from ..core.session import get_date, set_date
|
||||||
import brewman.schemas.voucher as schemas
|
import brewman.schemas.voucher as schemas
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
@ -26,26 +27,37 @@ def get_db() -> Session:
|
|||||||
|
|
||||||
|
|
||||||
@router.get("")
|
@router.get("")
|
||||||
def attendance_blank(request: Request, user: UserToken = Security(get_user, scopes=["attendance"])):
|
def attendance_blank(
|
||||||
|
request: Request, user: UserToken = Security(get_user, scopes=["attendance"])
|
||||||
|
):
|
||||||
return {"date": get_date(request.session), "body": []}
|
return {"date": get_date(request.session), "body": []}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{date_}")
|
@router.get("/{date_}")
|
||||||
def attendance_date(
|
def attendance_date(
|
||||||
date_: str,
|
date_: str,
|
||||||
|
request: Request,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
user: UserToken = Security(get_user, scopes=["attendance"]),
|
user: UserToken = Security(get_user, scopes=["attendance"]),
|
||||||
):
|
):
|
||||||
return attendance_date_report(date_, db)
|
set_date(date_, request.session)
|
||||||
|
return {
|
||||||
|
"date": date_,
|
||||||
|
"body": attendance_date_report(datetime.strptime(date_, "%d-%b-%Y"), db),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def attendance_date_report(date_: str, db):
|
def attendance_date_report(date_: date, db: Session):
|
||||||
report = {"date": date_, "body": []}
|
body = []
|
||||||
date_ = datetime.strptime(date_, "%d-%b-%Y").date()
|
|
||||||
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)
|
||||||
@ -55,50 +67,60 @@ def attendance_date_report(date_: str, db):
|
|||||||
att = (
|
att = (
|
||||||
db.query(Attendance)
|
db.query(Attendance)
|
||||||
.filter(Attendance.employee_id == item.id)
|
.filter(Attendance.employee_id == item.id)
|
||||||
.filter(Attendance.date == date)
|
.filter(Attendance.date == date_)
|
||||||
.filter(Attendance.is_valid == True)
|
.filter(Attendance.is_valid == True)
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
att = 0 if att is None else att.attendance_type
|
att = 0 if att is None else att.attendance_type
|
||||||
|
|
||||||
prints, hours, worked = get_prints(item.id, date, db)
|
prints, hours_worked, full_day = get_prints(item.id, date_, db)
|
||||||
report["body"].append(
|
body.append(
|
||||||
{
|
schemas.AttendanceItem(
|
||||||
"id": item.id,
|
id=item.id,
|
||||||
"code": item.code,
|
code=item.code,
|
||||||
"name": item.name,
|
name=item.name,
|
||||||
"designation": item.designation,
|
designation=item.designation,
|
||||||
"department": item.cost_centre.name,
|
department=item.cost_centre.name,
|
||||||
"attendanceType": {"id": att},
|
attendanceType=schemas.AttendanceType(id=att),
|
||||||
"prints": prints,
|
prints=prints,
|
||||||
"hours": hours,
|
hoursWorked=hours_worked,
|
||||||
"worked": worked,
|
fullDay=full_day,
|
||||||
}
|
)
|
||||||
)
|
)
|
||||||
return report
|
return body
|
||||||
|
|
||||||
|
|
||||||
@router.post("/{date_}") # "Attendance"
|
@router.post("/{date_}")
|
||||||
def save(
|
def save(
|
||||||
date_: str,
|
date_: str,
|
||||||
data: schemas.AttendanceIn,
|
data: schemas.AttendanceIn,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
user: UserToken = Security(get_user, scopes=["attendance"]),
|
user: UserToken = Security(get_user, scopes=["attendance"]),
|
||||||
):
|
):
|
||||||
date_object = datetime.strptime(date_, "%d-%b-%Y").date()
|
try:
|
||||||
|
att_date = datetime.strptime(date_, "%d-%b-%Y").date()
|
||||||
for item in data.body:
|
for item in data.body:
|
||||||
attendance_type = item.attendance_type.id_
|
if item.attendance_type.id_ != 0:
|
||||||
if attendance_type != 0:
|
attendance = Attendance(
|
||||||
attendance = Attendance(
|
employee_id=item.id_,
|
||||||
employee_id=item.employee_id,
|
date=att_date,
|
||||||
date=date_object,
|
attendance_type=item.attendance_type.id_,
|
||||||
attendance_type=attendance_type,
|
user_id=user.id_,
|
||||||
user_id=user.id_,
|
)
|
||||||
)
|
attendance.create(db)
|
||||||
attendance.create(db)
|
db.commit()
|
||||||
db.commit()
|
return {"date": date_, "body": attendance_date_report(att_date, db)}
|
||||||
return attendance_date_report(date_, db)
|
except SQLAlchemyError as e:
|
||||||
|
db.rollback()
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e),
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
db.rollback()
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail=traceback.format_exc(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def date_range(start: date, stop: date, step=timedelta(days=1), inclusive=False):
|
def date_range(start: date, stop: date, step=timedelta(days=1), inclusive=False):
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
from brewman.models.master import AttendanceType, Employee
|
from fastapi import APIRouter, Depends
|
||||||
|
from ..schemas.auth import UserToken
|
||||||
from fastapi import APIRouter
|
from ..core.security import get_current_active_user as get_user
|
||||||
|
from brewman.models.master import AttendanceType
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/") # "Authenticated"
|
@router.get("")
|
||||||
def show_list(request):
|
async def show_list(user: UserToken = Depends(get_user)):
|
||||||
list_ = AttendanceType.list()
|
list_ = AttendanceType.list()
|
||||||
attendance_types = []
|
attendance_types = []
|
||||||
for item in list_:
|
for item in list_:
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import csv
|
import csv
|
||||||
import datetime
|
from datetime import datetime, date, timedelta, time
|
||||||
import uuid
|
import uuid
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
from sqlalchemy import bindparam, select, exists, and_
|
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 zope.sqlalchemy import mark_changed
|
# from zope.sqlalchemy import mark_changed
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from brewman.models.master import Employee
|
from brewman.models.master import Employee
|
||||||
from brewman.models.voucher import Fingerprint
|
from brewman.models.voucher import Fingerprint
|
||||||
@ -117,14 +118,12 @@ def fp(file_data, employees):
|
|||||||
# return Fingerprint.__table__.insert().from_select([Fingerprint.id, Fingerprint.employee_id, Fingerprint.date], sel)
|
# return Fingerprint.__table__.insert().from_select([Fingerprint.id, Fingerprint.employee_id, Fingerprint.date], sel)
|
||||||
|
|
||||||
|
|
||||||
def get_prints(employee_id, date, dbsession):
|
def get_prints(employee_id: uuid.UUID, date_: date, db: Session):
|
||||||
start_fp = date + datetime.timedelta(hours=7)
|
|
||||||
finish_fp = date + datetime.timedelta(hours=7, days=1)
|
|
||||||
prints = (
|
prints = (
|
||||||
dbsession.query(Fingerprint)
|
db.query(Fingerprint)
|
||||||
.filter(Fingerprint.employee_id == employee_id)
|
.filter(Fingerprint.employee_id == employee_id)
|
||||||
.filter(Fingerprint.date >= start_fp)
|
.filter(Fingerprint.date >= datetime.combine(date_, time(hour=7)))
|
||||||
.filter(Fingerprint.date < finish_fp)
|
.filter(Fingerprint.date < datetime.combine(date_ + timedelta(days=1), time(hour=7)))
|
||||||
.order_by(Fingerprint.date)
|
.order_by(Fingerprint.date)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
@ -132,31 +131,31 @@ def get_prints(employee_id, date, dbsession):
|
|||||||
last = None
|
last = None
|
||||||
for i in range(len(prints), 0, -1):
|
for i in range(len(prints), 0, -1):
|
||||||
item = prints[i - 1].date
|
item = prints[i - 1].date
|
||||||
if last is not None and last - item < datetime.timedelta(minutes=10):
|
if last is not None and last - item < timedelta(minutes=10):
|
||||||
prints.remove(prints[i - 1])
|
prints.remove(prints[i - 1])
|
||||||
else:
|
else:
|
||||||
last = item
|
last = item
|
||||||
|
|
||||||
if len(prints) == 0:
|
if len(prints) == 0:
|
||||||
hours = "", ""
|
hours_worked, full_day = "", None
|
||||||
elif len(prints) == 2:
|
elif len(prints) == 2:
|
||||||
hours = prints[1].date - prints[0].date
|
time_worked = prints[1].date - prints[0].date
|
||||||
hours = working_hours(hours)
|
hours_worked, full_day = working_hours(time_worked)
|
||||||
elif len(prints) == 4:
|
elif len(prints) == 4:
|
||||||
hours = (prints[1].date - prints[0].date) + (prints[3].date - prints[2].date)
|
time_worked = (prints[1].date - prints[0].date) + (prints[3].date - prints[2].date)
|
||||||
hours = working_hours(hours)
|
hours_worked, full_day = working_hours(time_worked)
|
||||||
else:
|
else:
|
||||||
hours = "Error", "Error"
|
hours_worked, full_day = "Error", False
|
||||||
return (
|
return (
|
||||||
", ".join([x.date.strftime("%H:%M") for x in prints]) + " ",
|
", ".join([x.date.strftime("%H:%M") for x in prints]) + " ",
|
||||||
hours[0],
|
hours_worked,
|
||||||
hours[1],
|
full_day,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def working_hours(delta):
|
def working_hours(delta: timedelta):
|
||||||
minutes = (delta.seconds // 60) % 60
|
minutes = (delta.seconds // 60) % 60
|
||||||
minutes = int(5 * round(float(minutes) / 5))
|
minutes = int(5 * round(float(minutes) / 5))
|
||||||
hours = delta.seconds // 3600
|
hours = delta.seconds // 3600
|
||||||
worked = str(hours).zfill(2) + ":" + str(minutes).zfill(2)
|
hours_worked = str(hours).zfill(2) + ":" + str(minutes).zfill(2)
|
||||||
return worked, delta.seconds >= 60 * 60 * 9 # 9hrs
|
return hours_worked, delta.seconds >= 60 * 60 * 9 # 9hrs
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
def to_camel(string: str) -> str:
|
||||||
|
first, *others = string.split("_")
|
||||||
|
return "".join([first] + [word.capitalize() for word in others])
|
||||||
|
|
||||||
|
|
@ -3,10 +3,7 @@ from typing import List, Optional
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from brewman.schemas import to_camel
|
||||||
def to_camel(string: str) -> str:
|
|
||||||
first, *others = string.split("_")
|
|
||||||
return "".join([first] + [word.capitalize() for word in others])
|
|
||||||
|
|
||||||
|
|
||||||
class ClientIn(BaseModel):
|
class ClientIn(BaseModel):
|
||||||
|
@ -5,10 +5,7 @@ from decimal import Decimal
|
|||||||
|
|
||||||
from pydantic import BaseModel, Field, validator
|
from pydantic import BaseModel, Field, validator
|
||||||
|
|
||||||
|
from brewman.schemas import to_camel
|
||||||
def to_camel(string: str) -> str:
|
|
||||||
first, *others = string.split('_')
|
|
||||||
return ''.join([first] + [word.capitalize() for word in others])
|
|
||||||
|
|
||||||
|
|
||||||
class AccountLink(BaseModel):
|
class AccountLink(BaseModel):
|
||||||
@ -55,7 +52,6 @@ class ProductIn(BaseModel):
|
|||||||
fraction_units: str
|
fraction_units: str
|
||||||
product_yield: Decimal = Field(ge=0, le=1, multiple_of=0.00001, default=1)
|
product_yield: Decimal = Field(ge=0, le=1, multiple_of=0.00001, default=1)
|
||||||
product_group: ProductGroupLink = Field(...)
|
product_group: ProductGroupLink = Field(...)
|
||||||
account_id: AccountLink = Field(...)
|
|
||||||
price: Decimal = Field(ge=0, multiple_of=0.01, default=0)
|
price: Decimal = Field(ge=0, multiple_of=0.01, default=0)
|
||||||
sale_price: Decimal = Field(ge=0, multiple_of=0.01, default=0)
|
sale_price: Decimal = Field(ge=0, multiple_of=0.01, default=0)
|
||||||
is_active: bool
|
is_active: bool
|
||||||
@ -71,6 +67,7 @@ class ProductIn(BaseModel):
|
|||||||
class Product(ProductIn):
|
class Product(ProductIn):
|
||||||
id_: uuid.UUID
|
id_: uuid.UUID
|
||||||
code: int
|
code: int
|
||||||
|
account: AccountLink = Field(...)
|
||||||
is_fixture: bool
|
is_fixture: bool
|
||||||
|
|
||||||
|
|
||||||
@ -185,3 +182,13 @@ class DbSetting(BaseModel):
|
|||||||
id_: uuid.UUID
|
id_: uuid.UUID
|
||||||
name: str
|
name: str
|
||||||
data: bytes
|
data: bytes
|
||||||
|
|
||||||
|
|
||||||
|
class AccountType(BaseModel):
|
||||||
|
id_: int
|
||||||
|
name: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
fields = {'id_': 'id'}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,14 +4,10 @@ from typing import List, Optional
|
|||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from pydantic import BaseModel, Field, validator
|
from pydantic import BaseModel, Field, validator
|
||||||
|
|
||||||
|
from brewman.schemas import to_camel
|
||||||
from brewman.schemas.master import AccountLink, ProductLink
|
from brewman.schemas.master import AccountLink, ProductLink
|
||||||
|
|
||||||
|
|
||||||
def to_camel(string: str) -> str:
|
|
||||||
first, *others = string.split("_")
|
|
||||||
return "".join([first] + [word.capitalize() for word in others])
|
|
||||||
|
|
||||||
|
|
||||||
class LedgerItem(BaseModel):
|
class LedgerItem(BaseModel):
|
||||||
id_: Optional[uuid.UUID]
|
id_: Optional[uuid.UUID]
|
||||||
date_: date
|
date_: date
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import List
|
from typing import List, Optional
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel, validator
|
||||||
|
|
||||||
|
from brewman.schemas import to_camel
|
||||||
|
|
||||||
|
|
||||||
class Voucher(BaseModel):
|
class Voucher(BaseModel):
|
||||||
@ -72,20 +74,26 @@ class Batch(BaseModel):
|
|||||||
|
|
||||||
class AttendanceType(BaseModel):
|
class AttendanceType(BaseModel):
|
||||||
id_: int
|
id_: int
|
||||||
name: str
|
name: Optional[str]
|
||||||
value: Decimal
|
value: Optional[Decimal]
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
alias_generator = to_camel
|
||||||
|
|
||||||
|
|
||||||
class AttendanceItem(BaseModel):
|
class AttendanceItem(BaseModel):
|
||||||
id: uuid.UUID
|
id_: uuid.UUID
|
||||||
employee_id: uuid.UUID
|
code: int
|
||||||
date: date
|
name: str
|
||||||
|
designation: str
|
||||||
|
department: str
|
||||||
attendance_type: AttendanceType
|
attendance_type: AttendanceType
|
||||||
amount: Decimal
|
prints: str
|
||||||
creation_date: datetime
|
hours_worked: str
|
||||||
user_id: uuid.UUID
|
full_day: Optional[bool]
|
||||||
is_valid: bool
|
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
alias_generator = to_camel
|
||||||
|
|
||||||
class AttendanceIn(BaseModel):
|
class AttendanceIn(BaseModel):
|
||||||
body: List[AttendanceItem]
|
body: List[AttendanceItem]
|
||||||
|
@ -58,9 +58,9 @@
|
|||||||
{{row.prints}}
|
{{row.prints}}
|
||||||
<mat-icon *ngIf="!form.controls.attendances.controls[i].pristine">new_releases</mat-icon>
|
<mat-icon *ngIf="!form.controls.attendances.controls[i].pristine">new_releases</mat-icon>
|
||||||
<mat-chip-list class="no-bg">
|
<mat-chip-list class="no-bg">
|
||||||
<mat-chip *ngIf="row.hours.length" class="no-bg" [selected]="row.worked !== 'Error'"
|
<mat-chip *ngIf="row.hoursWorked.length" class="no-bg" [selected]="true"
|
||||||
[color]="row.worked === true ? 'primary' : 'warn'">
|
[color]="row.fullDay === true ? 'primary' : 'warn'">
|
||||||
{{row.hours}}
|
{{row.hoursWorked}}
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
|
@ -17,8 +17,8 @@ export class AttendanceItem {
|
|||||||
department: string;
|
department: string;
|
||||||
attendanceType: AttendanceType;
|
attendanceType: AttendanceType;
|
||||||
prints: string;
|
prints: string;
|
||||||
hours: string;
|
hoursWorked: string;
|
||||||
worked: string;
|
fullDay?: boolean;
|
||||||
|
|
||||||
public constructor(init?: Partial<AttendanceItem>) {
|
public constructor(init?: Partial<AttendanceItem>) {
|
||||||
Object.assign(this, init);
|
Object.assign(this, init);
|
||||||
|
@ -46,7 +46,7 @@ export class UnpostedDataSource extends DataSource<Unposted> {
|
|||||||
case 'date':
|
case 'date':
|
||||||
return compare(a.date, b.date, isAsc);
|
return compare(a.date, b.date, isAsc);
|
||||||
case 'type':
|
case 'type':
|
||||||
return compare(a.voucherType, b.voucherType, isAsc);
|
return compare(a.type, b.type, isAsc);
|
||||||
case 'debitAmount':
|
case 'debitAmount':
|
||||||
return compare(+a.debitAmount, +b.debitAmount, isAsc);
|
return compare(+a.debitAmount, +b.debitAmount, isAsc);
|
||||||
case 'creditAmount':
|
case 'creditAmount':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user