Incentive Done!!

Employee Benefit Done!!
This commit is contained in:
tanshu 2020-05-23 09:45:02 +05:30
parent 814d289758
commit e3286c87ba
20 changed files with 515 additions and 415 deletions

@ -1,4 +1,4 @@
"""my test
"""lowercase and fastapi
Revision ID: eed0b382c287
Revises: 0bf3d70ee7de
@ -8,7 +8,6 @@ Create Date: 2020-05-10 19:52:58.163810
from alembic import op
import sqlalchemy as sa
from sqlalchemy import table, column
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = 'eed0b382c287'
@ -193,9 +192,9 @@ def upgrade():
op.drop_constraint('entities_salarydeductions_JournalID_fkey', 'employee_benefit', type_='foreignkey')
op.drop_constraint('salary_deductions_VoucherID_fkey', 'employee_benefit', type_='foreignkey')
role = table('auth_roles', column('name', sa.String))
op.execute(role.update().where(role.c.name == op.inline_literal('Service Charge')).values({'name': op.inline_literal('Incentive')}))
op.execute(role.update().where(role.c.name == op.inline_literal('Salary Deduction')).values({'name': op.inline_literal('Employee Benefit')}))
permission = table('auth_permissions', column('name', sa.String))
op.execute(permission.update().where(permission.c.name == op.inline_literal('Service Charge')).values({'name': op.inline_literal('Incentive')}))
op.execute(permission.update().where(permission.c.name == op.inline_literal('Salary Deduction')).values({'name': op.inline_literal('Employee Benefit')}))
account = table('accounts', column('name', sa.String))
op.execute(account.update().where(account.c.name == op.inline_literal('Service Charges')).values({'name': op.inline_literal('Incentives')}))
### end Alembic commands ###

@ -15,6 +15,7 @@ from .routers import (
employee_attendance,
employee_benefit,
fingerprint,
incentive,
issue,
issue_grid,
lock_information,
@ -29,7 +30,7 @@ from .routers import (
login,
journal,
purchase,
purchase_return
purchase_return,
)
from .routers.auth import client, user, role
from .routers.reports import (
@ -99,13 +100,23 @@ app.include_router(profit_loss.router, prefix="/api/profit-loss", tags=["reports
app.include_router(closing_stock.router, prefix="/api/closing-stock", tags=["reports"])
app.include_router(cash_flow.router, prefix="/api/cash-flow", tags=["reports"])
app.include_router(daybook.router, prefix="/api/daybook", tags=["reports"])
app.include_router(net_transactions.router, prefix="/api/net-transactions", tags=["reports"])
app.include_router(product_ledger.router, prefix="/api/product-ledger", tags=["reports"])
app.include_router(purchase_entries.router, prefix="/api/purchase-entries", tags=["reports"])
app.include_router(
net_transactions.router, prefix="/api/net-transactions", tags=["reports"]
)
app.include_router(
product_ledger.router, prefix="/api/product-ledger", tags=["reports"]
)
app.include_router(
purchase_entries.router, prefix="/api/purchase-entries", tags=["reports"]
)
app.include_router(purchases.router, prefix="/api/purchases", tags=["reports"])
app.include_router(raw_material_cost.router, prefix="/api/raw-material-cost", tags=["reports"])
app.include_router(
raw_material_cost.router, prefix="/api/raw-material-cost", tags=["reports"]
)
app.include_router(reconcile.router, prefix="/api/reconcile", tags=["reports"])
app.include_router(stock_movement.router, prefix="/api/stock-movement", tags=["reports"])
app.include_router(
stock_movement.router, prefix="/api/stock-movement", tags=["reports"]
)
app.include_router(trial_balance.router, prefix="/api/trial-balance", tags=["reports"])
app.include_router(unposted.router, prefix="/api/unposted", tags=["reports"])
@ -115,11 +126,18 @@ app.include_router(journal.router, prefix="/api/journal", tags=["vouchers"])
app.include_router(payment.router, prefix="/api/payment", tags=["vouchers"])
app.include_router(receipt.router, prefix="/api/receipt", tags=["vouchers"])
app.include_router(purchase.router, prefix="/api/purchase", tags=["vouchers"])
app.include_router(purchase_return.router, prefix="/api/purchase-return", tags=["vouchers"])
app.include_router(
purchase_return.router, prefix="/api/purchase-return", tags=["vouchers"]
)
app.include_router(issue.router, prefix="/api/issue", tags=["vouchers"])
app.include_router(employee_benefit.router, prefix="/api/employee-benefit", tags=["vouchers"])
app.include_router(
employee_benefit.router, prefix="/api/employee-benefit", tags=["vouchers"]
)
app.include_router(incentive.router, prefix="/api/incentive", tags=["vouchers"])
app.include_router(lock_information.router, prefix="/api/lock-information", tags=["settings"])
app.include_router(
lock_information.router, prefix="/api/lock-information", tags=["settings"]
)
app.include_router(maintenance.router, prefix="/api/maintenance", tags=["settings"])
app.include_router(db_integrity.router, prefix="/api/db-integrity", tags=["management"])

@ -241,7 +241,7 @@ class Incentive(Base):
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
voucher_id = Column("voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False)
journal_id = Column("journal_id", GUID(), ForeignKey("journals.id"), nullable=False)
days_worked = Column("days_worked", Integer, nullable=False)
days_worked = Column("days_worked", Numeric(precision=5, scale=1), nullable=False)
points = Column("points", Numeric(precision=5, scale=2), nullable=False)
journal = relationship(
@ -253,20 +253,20 @@ class Incentive(Base):
def __init__(
self,
id=None,
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.journal_id = journal_id
if journal is None:
self.journal_id = journal_id
self.days_worked = days_worked
self.points = points
if journal_id is None and journal is not None:
self.journal = journal
self.journal = journal
class Inventory(Base):
@ -296,7 +296,7 @@ class Inventory(Base):
tax=None,
discount=None,
batch=None,
product=None
product=None,
):
self.id = id_
self.voucher_id = voucher_id
@ -339,7 +339,7 @@ class Batch(Base):
rate=None,
tax=None,
discount=None,
product=None
product=None,
):
self.name = name
self.product_id = product_id

@ -1,6 +1,5 @@
import traceback
import uuid
from decimal import Decimal
from math import ceil
from typing import List
from datetime import datetime, date
@ -14,7 +13,6 @@ from fastapi import (
File,
Request,
)
from sqlalchemy import func
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
@ -25,15 +23,13 @@ from .voucher import (
blank_voucher,
)
from ..core.session import set_date, get_date, get_last_day
from ..models import Product, AccountBase, Employee
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,
Batch,
Inventory,
Journal,
EmployeeBenefit,
)
@ -112,7 +108,7 @@ def save_employee_benefits(
):
total_exp, total_total = 0, 0
for item in employee_benefits:
account = db.query(Employee).filter(Employee.id == item.employee_id).first()
account = db.query(Employee).filter(Employee.id == item.employee.id_).first()
gross_salary = item.gross_salary
days_worked = item.days_worked
esi_ee, esi_er, esi_both = esi_contribution(
@ -201,7 +197,7 @@ def update_route(
exp, total = update_employee_benefits(
item, data.employee_benefits, days_in_month, db
)
update_journals(item, exp, total, db)
update_journals(item, exp, total)
# journals_valid(voucher)
update_files(data, i + t, db)
db.commit()

@ -1,18 +1,40 @@
import traceback
import uuid
from typing import List
from fastapi import APIRouter, HTTPException, status, Depends, Security, UploadFile, File, Request
from decimal import Decimal
from typing import List, Optional
from datetime import date, datetime
from fastapi import (
APIRouter,
HTTPException,
status,
Depends,
Security,
Request,
)
from sqlalchemy import or_, func
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from .voucher import incentive_create_voucher, employee_benefit_create_voucher, voucher_info, check_voucher_lock_info, check_voucher_edit_allowed
from ..core.session import set_date
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 ..db.session import SessionLocal
from ..models.voucher import Voucher
import brewman.schemas.voucher as schemas
from ..models.voucher import (
Voucher,
VoucherType,
Journal,
Incentive,
Attendance,
)
import brewman.schemas.voucher as output
import brewman.schemas.input as schema_in
router = APIRouter()
@ -26,25 +48,30 @@ def get_db() -> Session:
db.close()
@router.post("", response_model=schemas.Voucher)
@router.post("", response_model=output.Voucher)
def save_route(
request: Request,
data: schemas.Voucher,
data: schema_in.IncentiveIn = Depends(schema_in.IncentiveIn.load_form),
db: Session = Depends(get_db),
files: List[UploadFile] = File(...),
user: UserToken = Security(get_user, scopes=["journal"]),
user: UserToken = Security(get_user, scopes=["incentive"]),
):
try:
item: Voucher = save(data, files, user, db)
item: Voucher = save(data, user, db)
employees = get_employees(
get_first_day(data.date_), data.date_, data.incentives, None, db
)
amount = balance(data.date_, None, db) * Decimal(0.9) # 10% for Deb Dip
total_points = sum(e.points * e.days_worked for e in employees)
point_value = round(amount / total_points, 2)
save_incentives(item, employees, point_value, db)
db.commit()
set_date(request.session, data.date_)
# item: Voucher = db.query(Voucher).filter(Voucher.id == item.id).first()
return voucher_info(item, db)
set_date(data.date_.strftime("%d-%b-%Y"), request.session)
info = voucher_info(item, db)
return info
except SQLAlchemyError as e:
db.rollback()
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:
db.rollback()
@ -54,33 +81,75 @@ def save_route(
)
def save(data: schemas.Voucher, files: List[UploadFile], user: UserToken, db: Session) -> Voucher:
def save(data: schema_in.IncentiveIn, user: UserToken, db: Session) -> Voucher:
check_voucher_lock_info(None, data.date_, db)
if data.type_ in ["Incentive"]:
voucher = incentive_create_voucher(data, files, user, db)
voucher = Voucher(
date=data.date_,
narration=data.narration,
is_starred=data.is_starred,
user_id=user.id_,
type_=VoucherType.by_name(data.type_),
)
db.add(voucher)
return voucher
@router.get("/{id_}")
def save_incentives(
voucher: Voucher,
employees: List[schema_in.IncentiveEmployee],
point_value: Decimal,
db: Session,
):
total_amount = 0
for item in employees:
item_amount = round(item.points * item.days_worked * point_value)
journal = Journal(
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
)
voucher.journals.append(journal)
voucher.incentives.append(inc)
db.add(journal)
db.add(inc)
total_amount += item_amount
sc = db.query(Account).filter(Account.id == Account.incentive_id()).first()
journal = Journal(
amount=total_amount, debit=1, account_id=sc.id, cost_centre_id=sc.cost_centre_id
)
voucher.journals.append(journal)
db.add(journal)
@router.put("/{id_}")
def update_route(
id_: uuid.UUID,
request: Request,
data: schemas.Voucher,
data: schema_in.IncentiveIn = Depends(schema_in.IncentiveIn.load_form),
db: Session = Depends(get_db),
files: List[UploadFile] = File(...),
user: UserToken = Security(get_user, scopes=["journal"]),
user: UserToken = Security(get_user, scopes=["incentive"]),
):
try:
item: Voucher = update(id_, data, files, user, db)
item: Voucher = update(id_, data, user, db)
employees = get_employees(
get_first_day(data.date_), data.date_, data.incentives, item.journals, db
)
amount = balance(data.date_, item.id, db) * Decimal(0.9) # 10% for Deb Dip
total_points = sum(e.points * e.days_worked for e in employees)
point_value = round(amount / total_points, 2)
update_incentives(item, employees, point_value, db)
db.commit()
set_date(request.session, data.date_)
# item: Voucher = db.query(Voucher).filter(Voucher.id == item.id).first()
return voucher_info(item, db)
except SQLAlchemyError as e:
db.rollback()
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:
db.rollback()
@ -90,10 +159,149 @@ def update_route(
)
def update(id_: uuid.UUID, data: schemas.Voucher, files: List[UploadFile], user: UserToken, db: Session) -> Voucher:
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
check_voucher_lock_info(item.date, data.date_, db)
check_voucher_edit_allowed(item, user)
if data.type_ in ["Incentive"]:
voucher = incentive_update_voucher(item, data, files, user, db)
def update(
id_: uuid.UUID, data: schema_in.IncentiveIn, user: UserToken, db: Session
) -> Voucher:
voucher: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
check_voucher_lock_info(voucher.date, data.date_, db)
check_voucher_edit_allowed(voucher, user)
voucher.is_starred = data.is_starred
voucher.narration = data.narration
voucher.user_id = user.id_
voucher.posted = False
voucher.last_edit_date = datetime.utcnow()
return voucher
def update_incentives(
voucher: Voucher,
employees: List[schema_in.IncentiveEmployee],
point_value: Decimal,
db: Session,
):
total_amount = 0
for item in voucher.incentives:
employee = next(
e for e in employees if e.employee_id == item.journal.account_id
)
item_amount = round(employee.points * employee.days_worked * point_value)
item.days_worked = employee.days_worked
item.points = employee.points
item.journal.amount = item_amount
total_amount += item_amount
journal = next(
j for j in voucher.journals if j.account_id == Account.incentive_id()
)
journal.amount = total_amount
@router.get("/{id_}", response_model=output.Voucher)
def get_id(
id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["incentive"]),
):
try:
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
return voucher_info(item, 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(),
)
@router.get("", response_model=output.Voucher)
def show_blank(
request: Request,
d: str = None,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["incentive"]),
):
additional_info = {"date": d or get_date(request.session), "type": "Incentive"}
return blank_voucher(additional_info, db)
def get_employees(
start_date: date,
finish_date: date,
incentives: List[schema_in.Incentive],
journals: Optional[List[Journal]],
db: Session,
) -> List[schema_in.IncentiveEmployee]:
details = []
employees = (
db.query(Employee)
.filter(Employee.joining_date <= finish_date)
.filter(or_(Employee.is_active, Employee.leaving_date >= start_date))
.order_by(Employee.cost_centre_id)
.order_by(Employee.designation)
.order_by(Employee.name)
.all()
)
check_if_employees_changed(incentives, employees, journals)
for employee in employees:
att = (
db.query(Attendance)
.filter(Attendance.employee_id == employee.id)
.filter(Attendance.date >= start_date)
.filter(Attendance.date <= finish_date)
.filter(Attendance.is_valid == True)
.all()
)
att = 0.5 * round(
sum(map(lambda x: AttendanceType.by_id(x.attendance_type).value, att)) / 0.5
)
points = next(x for x in incentives if x.employee_id == employee.id).points
details.append(
schema_in.IncentiveEmployee(
employee_id=employee.id,
cost_centre_id=employee.cost_centre_id,
days_worked=att,
points=points,
)
)
return details
def balance(date_: date, voucher_id: Optional[uuid.UUID], db: Session):
amount = (
db.query(func.sum(Journal.amount * Journal.debit))
.join(Journal.voucher)
.filter(Voucher.date <= date_)
.filter(Voucher.type != VoucherType.by_name("Issue").id)
.filter(Journal.account_id == Account.incentive_id())
)
if voucher_id is not None:
amount = amount.filter(Voucher.id != voucher_id)
amount = amount.scalar()
return 0 if amount is None else amount * -1
def check_if_employees_changed(
json: List[schema_in.Incentive],
db: List[Employee],
voucher: Optional[List[Journal]],
):
json = set(x.employee_id for x in json)
db = set(x.id for x in db)
voucher = (
set(x.account_id for x in voucher if x.account_id != Account.incentive_id())
if voucher is not None
else None
)
if voucher is None:
if len(json ^ db) != 0:
raise ValueError("Employee missing in json data")
else:
if len(json ^ db) != 0 or len(db ^ voucher) != 0:
raise ValueError("Employee missing in json data")

@ -22,8 +22,6 @@ from brewman.models.voucher import (
Journal,
)
from brewman.routers import get_lock_info
from .incentive import incentive_create_voucher, incentive_update_voucher
from .employee_benefit import employee_benefit_create_voucher, employee_benefit_update_voucher
from ...core.session import get_first_day
from fastapi import APIRouter, Depends, Security, Request, HTTPException, status
@ -37,19 +35,23 @@ router = APIRouter()
def voucher_post(request):
user = (
request.dbsession.query(User)
.filter(User.id == uuid.UUID(request.authenticated_userid))
.one()
.filter(User.id == uuid.UUID(request.authenticated_userid))
.one()
)
voucher = (
request.dbsession.query(Voucher)
.filter(Voucher.id == uuid.UUID(request.matchdict["id"]))
.first()
.filter(Voucher.id == uuid.UUID(request.matchdict["id"]))
.first()
)
start, finish = get_lock_info(request.dbsession)
if start is not None and start > voucher.date:
raise ValidationError(f"Vouchers before {start.strftime('%d-%b-%Y')} have been locked.")
raise ValidationError(
f"Vouchers before {start.strftime('%d-%b-%Y')} have been locked."
)
elif finish is not None and finish < voucher.date:
raise ValidationError(f"Vouchers after {finish.strftime('%d-%b-%Y')} have been locked.")
raise ValidationError(
f"Vouchers after {finish.strftime('%d-%b-%Y')} have been locked."
)
voucher.posted = True
voucher.poster_id = user.id
transaction.commit()
@ -62,8 +64,8 @@ def voucher_post(request):
def check_delete_permissions(request, voucher):
user = (
request.dbsession.query(User)
.filter(User.id == uuid.UUID(request.authenticated_userid))
.one()
.filter(User.id == uuid.UUID(request.authenticated_userid))
.one()
)
if voucher.posted and not request.has_permission("Edit Posted Vouchers"):
@ -71,22 +73,28 @@ def check_delete_permissions(request, voucher):
response.status_int = 403
return response
elif voucher.user_id != user.id and not request.has_permission(
"Edit Other User's Vouchers"
"Edit Other User's Vouchers"
):
response = Response("You are not allowed to edit other user's vouchers")
response.status_int = 403
return response
elif not request.has_permission(VoucherType.by_id(voucher.type).name):
response = Response(f"You are not allowed ({VoucherType.by_id(voucher.type).name}) vouchers")
response = Response(
f"You are not allowed ({VoucherType.by_id(voucher.type).name}) vouchers"
)
response.status_int = 403
return response
start, finish = get_lock_info(request.dbsession)
if start is not None and start > voucher.date:
response = Response(f"Vouchers before {start.strftime('%d-%b-%Y')} have been locked.")
response = Response(
f"Vouchers before {start.strftime('%d-%b-%Y')} have been locked."
)
response.status_int = 403
return response
elif finish is not None and finish < voucher.date:
response = Response(f"Vouchers after {finish.strftime('%d-%b-%Y')} have been locked.")
response = Response(
f"Vouchers after {finish.strftime('%d-%b-%Y')} have been locked."
)
response.status_int = 403
return response
@ -95,8 +103,8 @@ def check_delete_permissions(request, voucher):
def delete(request):
voucher = (
request.dbsession.query(Voucher)
.filter(Voucher.id == uuid.UUID(request.matchdict["id"]))
.first()
.filter(Voucher.id == uuid.UUID(request.matchdict["id"]))
.first()
)
images = (
request.dbsession.query(DbImage).filter(DbImage.resource_id == voucher.id).all()
@ -128,24 +136,20 @@ def delete(request):
for item in voucher.inventories:
if item.batch.quantity_remaining < item.batch.quantity_remaining:
raise ValueError(
"Quantity remaining for {0} is less than issued, hence cannot be deleted".format(
item.product.name
)
f"Quantity remaining for {item.product.name} is less than issued, hence cannot be deleted"
)
item.batch.quantity_remaining -= item.quantity
elif voucher.type == VoucherType.by_name("Purchase").id:
for item in voucher.inventories:
uses = (
request.dbsession.query(func.count(Inventory.id))
.filter(Inventory.batch_id == item.batch.id)
.filter(Inventory.id != item.id)
.scalar()
.filter(Inventory.batch_id == item.batch.id)
.filter(Inventory.id != item.id)
.scalar()
)
if uses > 0:
raise ValueError(
"{0} has been issued and cannot be deleted".format(
item.product.name
)
f"{item.product.name} has been issued and cannot be deleted"
)
batches_to_delete.append(item.batch)
elif voucher.type == VoucherType.by_name("Purchase Return").id:
@ -181,6 +185,7 @@ def voucher_info(voucher, db):
"inventories": [],
"employeeBenefits": [],
"incentives": [],
"incentive": 0,
"files": [],
"creationDate": voucher.creation_date.strftime("%d-%b-%Y %H:%M"),
"lastEditDate": voucher.last_edit_date.strftime("%d-%b-%Y %H:%M"),
@ -188,9 +193,7 @@ def voucher_info(voucher, db):
"poster": voucher.poster.name if voucher.posted else "",
}
if voucher.reconcile_date is not None:
json_voucher["reconcileDate"] = voucher.reconcile_date.strftime(
"%d-%b-%Y"
)
json_voucher["reconcileDate"] = voucher.reconcile_date.strftime("%d-%b-%Y")
if voucher.type == 2: # "Purchase"
item = [j for j in voucher.journals if j.debit == -1][0]
json_voucher["vendor"] = {"id": item.account.id, "name": item.account.name}
@ -219,29 +222,24 @@ def voucher_info(voucher, db):
"pfEmployee": item.pf_ee,
"esiEmployer": item.esi_er,
"pfEmployer": item.pf_er,
"journal": {
"id": item.journal.id,
"account": {
"id": item.journal.account.id,
"name": item.journal.account.name,
"designation": item.journal.account.designation,
"costCentre": {
"id": item.journal.account.cost_centre.id,
"name": item.journal.account.cost_centre.name,
},
"employee": {
"id": item.journal.account.id,
"name": item.journal.account.name,
"designation": item.journal.account.designation,
"costCentre": {
"id": item.journal.account.cost_centre.id,
"name": item.journal.account.cost_centre.name,
},
},
}
)
for item in voucher.incentives:
employee = (
db.query(Employee)
.filter(Employee.id == item.journal.account_id)
.first()
db.query(Employee).filter(Employee.id == item.journal.account_id).first()
)
json_voucher["incentives"].append(
{
"id": item.journal.account_id,
"employeeId": item.journal.account_id,
"name": item.journal.account.name,
"designation": employee.designation,
"department": item.journal.account.cost_centre.name,
@ -250,11 +248,9 @@ def voucher_info(voucher, db):
}
)
if len(json_voucher["incentives"]) > 0:
json_voucher["incentive"] = [
x.amount
for x in voucher.journals
if x.account_id == Account.incentive_id()
][0]
json_voucher["incentive"] = next(
x.amount for x in voucher.journals if x.account_id == Account.incentive_id()
)
for item in voucher.inventories:
text = f"{item.product.name} ({item.product.units}) {item.batch.quantity_remaining:.2f}@{item.batch.rate:.2f} from {item.batch.name.strftime('%d-%b-%Y')}"
json_voucher["inventories"].append(
@ -285,9 +281,7 @@ def voucher_info(voucher, db):
},
}
)
images = (
db.query(DbImage).filter(DbImage.resource_id == voucher.id).all()
)
images = db.query(DbImage).filter(DbImage.resource_id == voucher.id).all()
for image in images:
json_voucher["files"].append({"id": image.id, "resized": "", "thumbnail": ""})
return json_voucher
@ -315,8 +309,8 @@ def blank_voucher(info, db):
if info and "account" in info and info["account"]:
account = (
db.query(AccountBase)
.filter(AccountBase.id == uuid.UUID(info["account"]))
.first()
.filter(AccountBase.id == uuid.UUID(info["account"]))
.first()
)
if account is not None:
account = {"id": account.id, "name": account.name}
@ -328,8 +322,8 @@ def blank_voucher(info, db):
if info and "account" in info and info["account"]:
account = (
db.query(AccountBase)
.filter(AccountBase.id == uuid.UUID(info["account"]))
.first()
.filter(AccountBase.id == uuid.UUID(info["account"]))
.first()
)
if account is not None:
account = {"id": account.id, "name": account.name}
@ -355,42 +349,42 @@ def blank_voucher(info, db):
elif type_ == "Employee Benefit":
json_voucher["employeeBenefits"] = []
elif type_ == "Incentive":
json_voucher["incentives"], json_voucher[
"incentive"
] = incentive_employees(info["date"], dbsession)
json_voucher["incentives"], json_voucher["incentive"] = incentive_employees(
info["date"], db
)
else:
raise ValidationError(f'Voucher of type "{type_}" does not exist.')
raise ValueError(f'Voucher of type "{type_}" does not exist.')
json_voucher["files"] = []
return json_voucher
def incentive_employees(date, dbsession):
date = datetime.datetime.strptime(date, "%d-%b-%Y")
start_date = get_first_day(date)
finish_date = date + datetime.timedelta(1)
def incentive_employees(date_, db: Session):
date_ = datetime.strptime(date_, "%d-%b-%Y")
start_date = get_first_day(date_)
finish_date = date_
details = []
employees = (
dbsession.query(Employee)
.filter(Employee.joining_date <= finish_date)
.filter(or_(Employee.is_active, Employee.leaving_date >= start_date))
.order_by(Employee.cost_centre_id)
.order_by(Employee.designation)
.order_by(Employee.name)
.all()
db.query(Employee)
.filter(Employee.joining_date <= finish_date)
.filter(or_(Employee.is_active, Employee.leaving_date >= start_date))
.order_by(Employee.cost_centre_id)
.order_by(Employee.designation)
.order_by(Employee.name)
.all()
)
for employee in employees:
att = (
dbsession.query(Attendance)
.filter(Attendance.employee_id == employee.id)
.filter(Attendance.date >= start_date)
.filter(Attendance.date < finish_date)
.filter(Attendance.is_valid == True)
.all()
db.query(Attendance)
.filter(Attendance.employee_id == employee.id)
.filter(Attendance.date >= start_date)
.filter(Attendance.date <= finish_date)
.filter(Attendance.is_valid == True)
.all()
)
att = sum(map(lambda x: AttendanceType.by_id(x.attendance_type).value, att))
details.append(
{
"id": employee.id,
"employeeId": employee.id,
"name": employee.name,
"designation": employee.designation,
"department": employee.cost_centre.name,
@ -400,12 +394,12 @@ def incentive_employees(date, dbsession):
)
amount = (
dbsession.query(func.sum(Journal.amount * Journal.debit))
.join(Journal.voucher)
.filter(Voucher.date < finish_date)
.filter(Voucher.type != VoucherType.by_name("Issue").id)
.filter(Journal.account_id == Account.incentive_id())
.scalar()
db.query(func.sum(Journal.amount * Journal.debit))
.join(Journal.voucher)
.filter(Voucher.date < finish_date)
.filter(Voucher.type != VoucherType.by_name("Issue").id)
.filter(Journal.account_id == Account.incentive_id())
.scalar()
)
amount = 0 if amount is None else amount * Decimal(0.9) * -1
return details, amount
@ -413,12 +407,22 @@ def incentive_employees(date, dbsession):
def check_voucher_lock_info(voucher_date: Optional[date], data_date: date, db: Session):
start, finish = get_lock_info(db)
if start is not None and start > data_date or voucher_date is not None and start > voucher_date:
if (
start is not None
and start > data_date
or voucher_date is not None
and start > voucher_date
):
raise HTTPException(
status_code=status.HTTP_423_LOCKED,
detail=f"Vouchers before {start.strftime('%d-%b-%Y')} have been locked.",
)
elif finish is not None and finish < data_date or voucher_date is not None and finish < voucher_date:
elif (
finish is not None
and finish < data_date
or voucher_date is not None
and finish < voucher_date
):
raise HTTPException(
status_code=status.HTTP_423_LOCKED,
detail=f"Vouchers after {finish.strftime('%d-%b-%Y')} have been locked.",
@ -441,7 +445,10 @@ def check_voucher_edit_allowed(voucher: Voucher, user: UserToken):
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(
status_code=status.HTTP_403_FORBIDDEN,
detail="You are not allowed to edit other user's vouchers",

@ -1,178 +0,0 @@
import datetime
import uuid
from decimal import Decimal
from sqlalchemy import or_, func
from brewman.models.master import Employee, AttendanceType, Account
from brewman.models.voucher import (
Journal,
Voucher,
VoucherType,
Attendance,
Incentive,
)
from brewman.core.session import get_first_day
def incentive_create_voucher(json, user, dbsession):
date = datetime.datetime.strptime(json["date"], "%d-%b-%Y")
voucher = Voucher(date=date, user_id=user.id, type=VoucherType.by_id(13))
dbsession.add(voucher)
employees = get_employees(
get_first_day(date),
date + datetime.timedelta(1),
json["incentives"],
dbsession=dbsession,
)
amount = balance(date, dbsession=dbsession) * Decimal(0.9)
total_points = 0
for item in employees:
total_points += item["points"] * item["daysWorked"]
point_value = round(amount / total_points, 2)
total_amount = 0
for item in employees:
item_amount = round(item["points"] * item["daysWorked"] * point_value)
employee = item["employee"]
journal = Journal(
amount=item_amount,
debit=-1,
account_id=employee.id,
cost_centre_id=employee.cost_centre_id,
)
inc = Incentive(
journal=journal, days_worked=item["daysWorked"], points=item["points"]
)
voucher.journals.append(journal)
voucher.incentives.append(inc)
dbsession.add(journal)
dbsession.add(inc)
total_amount += item_amount
sc = (
dbsession.query(Account)
.filter(Account.id == Account.incentive_id())
.first()
)
journal = Journal(
amount=total_amount, debit=1, account_id=sc.id, cost_centre_id=sc.cost_centre_id
)
voucher.journals.append(journal)
dbsession.add(journal)
journals_valid(voucher)
return voucher
def incentive_update_voucher(voucher, json, user, dbsession):
date = datetime.datetime.strptime(json["date"], "%d-%b-%Y")
voucher.date = date
voucher.user_id = user.id
voucher.posted = False
voucher.last_edit_date = datetime.datetime.utcnow()
employees = get_employees(
get_first_day(date),
date + datetime.timedelta(1),
json["incentives"],
voucher.journals,
dbsession=dbsession,
)
amount = balance(date, voucher.id, dbsession) * Decimal(0.9)
total_points = 0
for item in employees:
total_points += item["points"] * item["daysWorked"]
point_value = round(amount / total_points, 2)
total_amount = 0
for item in voucher.incentives:
employee = [
e for e in employees if e["employee"].id == item.journal.account_id
][0]
item_amount = round(employee["points"] * employee["daysWorked"] * point_value)
item.days_worked = employee["daysWorked"]
item.points = employee["points"]
item.journal.amount = item_amount
total_amount += item_amount
journal = [
j for j in voucher.journals if j.account_id == Account.incentive_id()
][0]
journal.amount = total_amount
journals_valid(voucher)
return voucher
def get_employees(
start_date, finish_date, json, voucher_employees=None, dbsession=None
):
details = []
employees = (
dbsession.query(Employee)
.filter(Employee.joining_date <= finish_date)
.filter(or_(Employee.is_active, Employee.leaving_date >= start_date))
.order_by(Employee.cost_centre_id)
.order_by(Employee.designation)
.order_by(Employee.name)
.all()
)
check_if_employees_changed(json, employees, voucher_employees)
for employee in employees:
att = (
dbsession.query(Attendance)
.filter(Attendance.employee_id == employee.id)
.filter(Attendance.date >= start_date)
.filter(Attendance.date < finish_date)
.filter(Attendance.is_valid == True)
.all()
)
att = sum(map(lambda x: AttendanceType.by_id(x.attendance_type).value, att))
details.append({"employee": employee, "daysWorked": round(Decimal(att), 2)})
for item in details:
j = [x for x in json if uuid.UUID(x["id"]) == item["employee"].id][0]
item["points"] = round(Decimal(j["points"]), 2)
json.remove(j)
return details
def balance(date, voucher_id=None, dbsession=None):
amount = (
dbsession.query(func.sum(Journal.amount * Journal.debit))
.join(Journal.voucher)
.filter(Voucher.date < date + datetime.timedelta(1))
.filter(Voucher.type != VoucherType.by_name("Issue").id)
.filter(Journal.account_id == Account.incentive_id())
)
if voucher_id is not None:
amount = amount.filter(Voucher.id != voucher_id)
amount = amount.scalar()
return 0 if amount is None else amount * -1
def check_if_employees_changed(json, db, voucher):
json = set([uuid.UUID(x["id"]) for x in json])
db = set([x.id for x in db])
voucher = (
set(
[
x.account_id
for x in voucher
if x.account_id != Account.incentive_id()
]
)
if voucher is not None
else None
)
if voucher is None:
if len(json ^ db) != 0:
raise ValueError("Employee missing in json data")
else:
if len(json ^ db) != 0 or len(db ^ voucher) != 0:
raise ValueError("Employee missing in json data")

@ -5,12 +5,18 @@ from decimal import Decimal
from typing import List, Optional
from fastapi import Form
from pydantic import validator
from pydantic import validator, BaseModel, Field
from sqlalchemy.orm import Session
from brewman.schemas import to_camel
from brewman.schemas.master import AccountLink, CostCentreLink
from brewman.schemas.voucher import VoucherIn, Journal, Inventory, EmployeeBenefit
from brewman.schemas.voucher import (
VoucherIn,
Journal,
Inventory,
EmployeeBenefit,
Incentive,
)
class JournalIn(VoucherIn):
@ -21,7 +27,7 @@ class JournalIn(VoucherIn):
alias_generator = to_camel
json_encoders = {
date: lambda v: v.strftime("%d-%b-%Y"),
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I")
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I"),
}
@validator("date_", pre=True)
@ -38,7 +44,11 @@ class JournalIn(VoucherIn):
@validator("journals")
def is_distinct(cls, value: List[Journal]):
journal_set = set(hash(x.account.id_) ^ hash(None if x.cost_centre is None else x.cost_centre.id_) for x in value)
journal_set = set(
hash(x.account.id_)
^ hash(None if x.cost_centre is None else x.cost_centre.id_)
for x in value
)
if len(value) != len(journal_set):
raise ValueError("Duplicate journals")
return value
@ -58,7 +68,7 @@ class PurchaseIn(VoucherIn):
alias_generator = to_camel
json_encoders = {
date: lambda v: v.strftime("%d-%b-%Y"),
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I")
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I"),
}
@validator("date_", pre=True)
@ -67,13 +77,13 @@ class PurchaseIn(VoucherIn):
return value
return datetime.strptime(value, "%d-%b-%Y").date()
@validator("inventories") # For Purchase, Issue and Return Vouchers
@validator("inventories") # For Purchase, Issue and Return Vouchers
def validate_enough_inventories(cls, value: List[Inventory]):
if len(value) < 1:
raise ValueError("Not enough inventories")
return value
@validator("inventories") # For Purchase, Issue and Return Vouchers
@validator("inventories") # For Purchase, Issue and Return Vouchers
def validate_inventories_unique(cls, value: List[Inventory]):
if len(set(x.product.id_ for x in value)) != len(value):
raise ValueError("Duplicate products")
@ -95,7 +105,7 @@ class IssueIn(VoucherIn):
alias_generator = to_camel
json_encoders = {
date: lambda v: v.strftime("%d-%b-%Y"),
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I")
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I"),
}
@validator("date_", pre=True)
@ -104,21 +114,21 @@ class IssueIn(VoucherIn):
return value
return datetime.strptime(value, "%d-%b-%Y").date()
@validator("inventories") # For Purchase, Issue and Return Vouchers
@validator("inventories") # For Purchase, Issue and Return Vouchers
def validate_enough_inventories(cls, value: List[Inventory]):
if len(value) < 1:
raise ValueError("Not enough inventories")
return value
@validator("inventories") # For Purchase, Issue and Return Vouchers
@validator("inventories") # For Purchase, Issue and Return Vouchers
def validate_inventories_unique(cls, value: List[Inventory]):
if len(set(x.product.id_ for x in value)) != len(value):
raise ValueError("Duplicate products")
return value
@validator("destination") # For Purchase, Issue and Return Vouchers
@validator("destination") # For Purchase, Issue and Return Vouchers
def source_destination_unique(cls, value: CostCentreLink, values):
if value.id_ == values['source'].id_:
if value.id_ == values["source"].id_:
raise ValueError("Source and destination cannot be the same")
return value
@ -136,7 +146,7 @@ class EmployeeBenefitIn(VoucherIn):
alias_generator = to_camel
json_encoders = {
date: lambda v: v.strftime("%d-%b-%Y"),
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I")
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I"),
}
@validator("date_", pre=True)
@ -145,19 +155,39 @@ class EmployeeBenefitIn(VoucherIn):
return value
return datetime.strptime(value, "%d-%b-%Y").date()
@validator("inventories") # For Purchase, Issue and Return Vouchers
def validate_enough_inventories(cls, value: List[Inventory]):
if len(value) < 1:
raise ValueError("Not enough inventories")
return value
@classmethod
def load_form(cls, data: str = Form(...)):
json_data = json.loads(data)
return cls.parse_obj(json_data)
@validator("inventories") # For Purchase, Issue and Return Vouchers
def validate_inventories_unique(cls, value: List[Inventory]):
if len(set(x.product.id_ for x in value)) != len(value):
raise ValueError("Duplicate products")
return value
class IncentiveIn(VoucherIn):
incentives: List[Incentive]
class Config:
anystr_strip_whitespace = True
alias_generator = to_camel
json_encoders = {
date: lambda v: v.strftime("%d-%b-%Y"),
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I"),
}
@validator("date_", pre=True)
def parse_date(cls, value):
if isinstance(value, date):
return value
return datetime.strptime(value, "%d-%b-%Y").date()
@classmethod
def load_form(cls, data: str = Form(...)):
json_data = json.loads(data)
return cls.parse_obj(json_data)
class IncentiveEmployee(BaseModel):
id_: Optional[uuid.UUID]
employee_id: uuid.UUID
cost_centre_id: uuid.UUID
journal: Optional[Journal]
days_worked: Decimal = Field(ge=0, multiple_of=0.5)
points: Decimal = Field(ge=0, multiple_of=0.01)

@ -13,7 +13,25 @@ class AccountLink(BaseModel):
name: Optional[str]
class Config:
fields = {'id_': 'id'}
fields = {"id_": "id"}
class CostCentreLink(BaseModel):
id_: uuid.UUID = Field(...)
name: Optional[str]
class Config:
fields = {"id_": "id"}
class EmployeeLink(BaseModel):
id_: uuid.UUID = Field(...)
name: Optional[str]
designation: Optional[str]
cost_centre: CostCentreLink
class Config:
alias_generator = to_camel
class ProductGroupIn(BaseModel):
@ -25,7 +43,7 @@ class ProductGroup(ProductGroupIn):
is_fixture: bool
class Config:
fields = {'id_': 'id'}
fields = {"id_": "id"}
anystr_strip_whitespace = True
alias_generator = to_camel
@ -34,7 +52,7 @@ class ProductGroupLink(BaseModel):
id_: uuid.UUID = Field(...)
class Config:
fields = {'id_': 'id'}
fields = {"id_": "id"}
class ProductLink(BaseModel):
@ -42,7 +60,7 @@ class ProductLink(BaseModel):
name: Optional[str]
class Config:
fields = {'id_': 'id'}
fields = {"id_": "id"}
class ProductIn(BaseModel):
@ -59,7 +77,7 @@ class ProductIn(BaseModel):
is_sold: bool
class Config:
fields = {'id_': 'id'}
fields = {"id_": "id"}
anystr_strip_whitespace = True
alias_generator = to_camel
@ -95,13 +113,6 @@ class RecipeItem(BaseModel):
price: int
class CostCentreLink(BaseModel):
id_: uuid.UUID = Field(...)
class Config:
fields = {'id_': 'id'}
class CostCentreIn(BaseModel):
name: str = Field(..., min_length=1)
@ -111,7 +122,7 @@ class CostCentre(CostCentreIn):
is_fixture: bool
class Config:
fields = {'id_': 'id'}
fields = {"id_": "id"}
anystr_strip_whitespace = True
alias_generator = to_camel
@ -123,7 +134,7 @@ class AccountBase(BaseModel):
cost_centre: CostCentreLink
class Config:
fields = {'id_': 'id'}
fields = {"id_": "id"}
anystr_strip_whitespace = True
alias_generator = to_camel
@ -148,27 +159,21 @@ class EmployeeIn(AccountBase):
@validator("joining_date", pre=True)
def parse_joining_date(cls, value):
return datetime.strptime(
value,
"%d-%b-%Y"
).date()
return datetime.strptime(value, "%d-%b-%Y").date()
@validator("leaving_date", pre=True)
def parse_leaving_date(cls, value):
if value is None or value == "":
return None
else:
return datetime.strptime(
value,
"%d-%b-%Y"
).date()
return datetime.strptime(value, "%d-%b-%Y").date()
@validator('leaving_date')
@validator("leaving_date")
def leaving_date_more_than_joining_date(cls, v, values, **kwargs):
if values['is_active']:
if values["is_active"]:
return None
if v < values['joining_date']:
raise ValueError('Leaving Date cannot be less than Joining Date')
if v < values["joining_date"]:
raise ValueError("Leaving Date cannot be less than Joining Date")
return v
@ -189,6 +194,4 @@ class AccountType(BaseModel):
name: str
class Config:
fields = {'id_': 'id'}
fields = {"id_": "id"}

@ -8,7 +8,12 @@ from fastapi import Form
from pydantic import BaseModel, validator, Field
from brewman.schemas import to_camel
from brewman.schemas.master import AccountLink, CostCentreLink, ProductLink
from brewman.schemas.master import (
AccountLink,
CostCentreLink,
ProductLink,
EmployeeLink,
)
class UserLink(BaseModel):
@ -60,25 +65,28 @@ class Inventory(BaseModel):
class EmployeeBenefit(BaseModel):
id_: Optional[uuid.UUID]
journal_id: Optional[uuid.UUID]
employee_id: uuid.UUID
employee: Optional[EmployeeLink]
gross_salary: int = Field(ge=0)
days_worked: int = Field(ge=0)
esi_ee: int = Field(ge=0)
pf_ee: int = Field(ge=0)
esi_er: int = Field(ge=0)
pf_er: int = Field(ge=0)
esi_employee: Optional[int] = Field(ge=0)
pf_employee: Optional[int] = Field(ge=0)
esi_employer: Optional[int] = Field(ge=0)
pf_employer: Optional[int] = Field(ge=0)
class Config:
alias_generator = to_camel
class Incentive(BaseModel):
id: uuid.UUID
voucher_id: uuid.UUID
journal_id: uuid.UUID
days_worked: int
points: Decimal
employee_id: uuid.UUID
name: str
designation: str
department: str
days_worked: Decimal = Field(ge=0, multiple_of=0.5)
points: Decimal = Field(ge=0, multiple_of=0.01)
class Config:
alias_generator = to_camel
class VoucherIn(BaseModel):
@ -99,7 +107,7 @@ class Voucher(VoucherIn):
reconcile_date: Optional[date]
creation_date: Optional[datetime]
last_edit_date: Optional[datetime]
user: UserLink
user: Optional[UserLink]
posted: Optional[bool]
poster_id: Optional[uuid.UUID]
journals: List[Journal]
@ -107,6 +115,9 @@ class Voucher(VoucherIn):
vendor: Optional[AccountLink]
source: Optional[CostCentreLink]
destination: Optional[CostCentreLink]
incentives: Optional[List[Incentive]]
incentive: Optional[Decimal]
employee_benefits: List[EmployeeBenefit]
files: List[Any]
class Config:
@ -114,7 +125,7 @@ class Voucher(VoucherIn):
alias_generator = to_camel
json_encoders = {
date: lambda v: v.strftime("%d-%b-%Y"),
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I")
datetime: lambda v: v.strftime("%d-%b-%Y %H:%I"),
}
@validator("date_", pre=True)
@ -141,10 +152,7 @@ class Voucher(VoucherIn):
return None
elif isinstance(value, date):
return value
return datetime.strptime(
value,
"%d-%b-%Y"
).date()
return datetime.strptime(value, "%d-%b-%Y").date()
@validator("journals")
def validate_enough_journals(cls, value: List[Journal]):
@ -160,7 +168,11 @@ class Voucher(VoucherIn):
@validator("journals")
def is_distinct(cls, value: List[Journal]):
journal_set = set(hash(x.account.id_) ^ hash(None if x.cost_centre is None else x.cost_centre.id_) for x in value)
journal_set = set(
hash(x.account.id_)
^ hash(None if x.cost_centre is None else x.cost_centre.id_)
for x in value
)
if len(value) != len(journal_set):
raise ValueError("Duplicate journals")
return value

@ -41,8 +41,8 @@ export class VoucherService {
}
getIncentive(date: string): Observable<Voucher> {
const options = {params: new HttpParams().set('t', 'Incentive').set('d', date)};
return <Observable<Voucher>>this.http.get<Voucher>(url, options)
const options = {params: new HttpParams().set('d', date)};
return <Observable<Voucher>>this.http.get<Voucher>(`${url}/incentive`, options)
.pipe(
catchError(this.log.handleError(serviceName, 'list'))
);

@ -2,6 +2,7 @@ import {Account} from './account';
import {User} from './user';
import {CostCentre} from './cost-centre';
import {Product} from './product';
import {Employee} from "../employee/employee";
export class Voucher {
id: string;
@ -45,7 +46,7 @@ export class EmployeeBenefit {
pfEmployee: number;
esiEmployer: number;
pfEmployer: number;
journal: Journal; // Should be employee as we need designation
employee: Employee;
}
export class Incentive {

@ -15,9 +15,9 @@ export class EmployeeBenefitsResolver implements Resolve<Voucher> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Voucher> {
const id = route.paramMap.get('id');
if (id === null) {
return this.ser.getOfType('Salary Deduction');
return this.ser.getOfType('Employee Benefit');
} else {
return this.ser.get(id, 'Employee-Benefits');
return this.ser.get(id, 'Employee Benefit');
}
}
}

@ -11,7 +11,7 @@ const employeeBenefitsRoutes: Routes = [
component: EmployeeBenefitsComponent,
canActivate: [AuthGuard],
data: {
permission: 'Salary Deduction'
permission: 'employee-benefit'
},
resolve: {
voucher: EmployeeBenefitsResolver
@ -23,7 +23,7 @@ const employeeBenefitsRoutes: Routes = [
component: EmployeeBenefitsComponent,
canActivate: [AuthGuard],
data: {
permission: 'Salary Deduction'
permission: 'employee-benefit'
},
resolve: {
voucher: EmployeeBenefitsResolver

@ -37,19 +37,19 @@
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.journal.account.name}}</mat-cell>
<mat-cell *matCellDef="let row">{{row.employee.name}}</mat-cell>
</ng-container>
<!-- Designation Column -->
<ng-container matColumnDef="designation">
<mat-header-cell *matHeaderCellDef>Designation</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.journal.account.designation}}</mat-cell>
<mat-cell *matCellDef="let row">{{row.employee.designation}}</mat-cell>
</ng-container>
<!-- Department Column -->
<ng-container matColumnDef="department">
<mat-header-cell *matHeaderCellDef>Department</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.journal.account.costCentre.name}}</mat-cell>
<mat-cell *matCellDef="let row">{{row.employee.costCentre.name}}</mat-cell>
</ng-container>
<!-- GrossSalary Column -->

@ -6,7 +6,7 @@ import {ActivatedRoute, Router} from '@angular/router';
import {BehaviorSubject, Observable, of as observableOf} from 'rxjs';
import {EmployeeBenefitsDataSource} from './employee-benefits-datasource';
import {VoucherService} from '../core/voucher.service';
import {EmployeeBenefit, Journal, Voucher} from '../core/voucher';
import {EmployeeBenefit, Voucher} from '../core/voucher';
import * as moment from 'moment';
import {AuthService} from '../auth/auth.service';
import {ConfirmDialogComponent} from '../shared/confirm-dialog/confirm-dialog.component';
@ -106,7 +106,7 @@ export class EmployeeBenefitsComponent implements OnInit, AfterViewInit {
}
addRow() {
const oldFiltered = this.voucher.employeeBenefits.filter((x) => x.journal.account.id === this.employee.id);
const oldFiltered = this.voucher.employeeBenefits.filter((x) => x.employee.id === this.employee.id);
if (oldFiltered.length) {
this.toaster.show('Danger', 'Employee has already been added');
return;
@ -121,7 +121,7 @@ export class EmployeeBenefitsComponent implements OnInit, AfterViewInit {
const pf = this.getPf(grossSalary, daysWorked, daysInMonth);
this.voucher.employeeBenefits.push({
journal: new Journal({account: new Account(this.employee)}),
employee: this.employee,
grossSalary: grossSalary,
daysWorked: daysWorked,
esiEmployee: esi.ee,

@ -10,7 +10,7 @@ const employeeFunctionsRoutes: Routes = [
component: EmployeeFunctionsComponent,
canActivate: [AuthGuard],
data: {
permission: 'Salary Deduction'
permission: 'employee-benefit'
},
runGuardsAndResolvers: 'always'
}

@ -11,7 +11,7 @@ const incentiveRoutes: Routes = [
component: IncentiveComponent,
canActivate: [AuthGuard],
data: {
permission: 'Incentive'
permission: 'incentive'
},
resolve: {
voucher: IncentiveResolver
@ -23,7 +23,7 @@ const incentiveRoutes: Routes = [
component: IncentiveComponent,
canActivate: [AuthGuard],
data: {
permission: 'Incentive'
permission: 'incentive'
},
resolve: {
voucher: IncentiveResolver

@ -51,7 +51,7 @@
<button matPrefix (click)="less(row, i)">
<mat-icon>remove</mat-icon>
</button>
<input matInput formControlName="points" autocomplete="off">
<input matInput formControlName="points" autocomplete="off" (change)="change(row, i)">
<button matSuffix color="warn" (click)="more(row, i)">
<mat-icon>add</mat-icon>
</button>

@ -109,6 +109,11 @@ export class IncentiveComponent implements OnInit {
}
}
change(row: Incentive, i: number) {
row.points = +(this.form.get('incentives').get('' + i).get('points').value);
this.form.get('incentives').get('' + i).setValue({'points': '' + row.points});
}
more(row: Incentive, i: number) {
row.points += 1;
this.form.get('incentives').get('' + i).setValue({'points': '' + row.points});
@ -160,7 +165,6 @@ export class IncentiveComponent implements OnInit {
this.voucher.incentives.forEach((item, index) => {
item.points = array.controls[index].value.points;
});
this.voucher.narration = formModel.narration;
return this.voucher;
}