brewman/brewman/brewman/models/voucher.py

473 lines
15 KiB
Python

import uuid
from datetime import datetime
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
class VoucherType:
def __init__(self, id_, name):
self.id = id_
self.name = name
@classmethod
def list(cls):
list_ = [
VoucherType(1, "Journal"),
VoucherType(2, "Purchase"),
VoucherType(3, "Issue"),
VoucherType(4, "Payment"),
VoucherType(5, "Receipt"),
VoucherType(6, "Purchase Return"),
VoucherType(7, "Opening Accounts"),
VoucherType(8, "Opening Batches"),
VoucherType(9, "Verification"),
VoucherType(10, "Opening Balance"),
VoucherType(11, "Closing Balance"),
VoucherType(12, "Employee Benefit"),
VoucherType(13, "Incentive"),
]
return list_
@classmethod
def by_name(cls, name):
list_ = cls.list()
for item in list_:
if item.name == name:
return item
@classmethod
def by_id(cls, id_):
list_ = cls.list()
for item in list_:
if item.id == id_:
return item
class Voucher(Base):
__tablename__ = "vouchers"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
date = Column("date", Date, nullable=False, index=True)
narration = Column("narration", Unicode(1000), nullable=False)
is_reconciled = Column("is_reconciled", Boolean, nullable=False)
reconcile_date = Column("reconcile_date", Date, nullable=False)
is_starred = Column("is_starred", Boolean, nullable=False)
creation_date = Column("creation_date", DateTime(timezone=True), nullable=False)
last_edit_date = Column("last_edit_date", DateTime(timezone=True), nullable=False)
_type = Column("voucher_type", Integer, nullable=False)
user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id"), nullable=False)
posted = Column("is_posted", Boolean, nullable=False)
poster_id = Column("poster_id", UUID(as_uuid=True), ForeignKey("auth_users.id"))
user = relationship("User", primaryjoin="User.id==Voucher.user_id", cascade=None)
poster = relationship("User", primaryjoin="User.id==Voucher.poster_id", cascade=None)
journals = relationship(
"Journal",
back_populates="voucher",
cascade="delete, delete-orphan",
cascade_backrefs=False,
)
inventories = relationship(
"Inventory",
back_populates="voucher",
cascade="delete, delete-orphan",
cascade_backrefs=False,
)
employee_benefits = relationship(
"EmployeeBenefit",
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):
return self._type
# for item in VoucherType.list():
# if self._type == item.id:
# return item
def _set_type(self, value):
if type(value) == int:
self._type = value
else:
self._type = value.id
type = property(_get_type, _set_type)
type = synonym("_type", descriptor=type)
def __init__(
self,
date=None,
is_reconciled=False,
reconcile_date=None,
is_starred=None,
narration="",
posted=False,
creation_date=None,
last_edit_date=None,
type_=None,
user_id=None,
poster_id=None,
):
self.date = date
self.is_reconciled = is_reconciled
self.reconcile_date = reconcile_date or date
self.is_starred = is_starred if is_starred is not None else False
self.narration = narration
self.posted = posted
self.creation_date = creation_date or datetime.utcnow()
self.last_edit_date = last_edit_date or datetime.utcnow()
self.type = type_
self.user_id = user_id
self.poster_id = poster_id
class Journal(Base):
__tablename__ = "journals"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
debit = Column("debit", Integer, nullable=False)
amount = Column("amount", Numeric(precision=15, scale=2), nullable=False)
voucher_id = Column(
"voucher_id",
UUID(as_uuid=True),
ForeignKey("vouchers.id"),
nullable=False,
index=True,
)
account_id = Column("account_id", UUID(as_uuid=True), ForeignKey("accounts.id"), nullable=False)
cost_centre_id = Column(
"cost_centre_id",
UUID(as_uuid=True),
ForeignKey("cost_centres.id"),
nullable=False,
)
voucher = relationship("Voucher", back_populates="journals")
account = relationship("AccountBase", back_populates="journals")
@hybrid_property
def signed_amount(self):
return self.debit * self.amount
@property
def __name__(self):
return self.name
def __init__(
self,
id_=None,
debit=None,
amount=None,
voucher_id=None,
account_id=None,
cost_centre_id=None,
):
self.id = id_
self.debit = debit
self.amount = amount
self.voucher_id = voucher_id
self.account_id = account_id
self.cost_centre_id = cost_centre_id
class EmployeeBenefit(Base):
__tablename__ = "employee_benefit"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
voucher_id = Column("voucher_id", UUID(as_uuid=True), ForeignKey("vouchers.id"), nullable=False)
journal_id = Column("journal_id", UUID(as_uuid=True), ForeignKey("journals.id"), nullable=False)
gross_salary = Column("gross_salary", Integer)
days_worked = Column("days_worked", Integer)
esi_ee = Column("esi_employee", Integer)
pf_ee = Column("pf_employee", Integer)
esi_er = Column("esi_employer", Integer)
pf_er = Column("pf_employer", Integer)
journal = relationship(
Journal,
backref=backref("employee_benefit", uselist=False),
cascade=None,
cascade_backrefs=False,
)
def __init__(
self,
id_=None,
voucher_id=None,
journal_id=None,
journal=None,
gross_salary=None,
days_worked=None,
esi_ee=None,
pf_ee=None,
esi_er=None,
pf_er=None,
):
self.id = id_
self.voucher_id = voucher_id
self.gross_salary = gross_salary
self.days_worked = days_worked
self.esi_ee = esi_ee
self.pf_ee = pf_ee
self.esi_er = esi_er
self.pf_er = pf_er
if journal is None:
self.journal_id = journal_id
else:
self.journal = journal
class Incentive(Base):
__tablename__ = "incentives"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
voucher_id = Column("voucher_id", UUID(as_uuid=True), ForeignKey("vouchers.id"), nullable=False)
journal_id = Column("journal_id", UUID(as_uuid=True), ForeignKey("journals.id"), 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(
Journal,
backref=backref("incentive", uselist=False),
cascade=None,
cascade_backrefs=False,
)
def __init__(
self,
id_=None,
voucher_id=None,
journal_id=None,
journal=None,
days_worked=None,
points=None,
):
self.id = id_
self.voucher_id = voucher_id
if journal is None:
self.journal_id = journal_id
else:
self.journal = journal
self.days_worked = days_worked
self.points = points
class Inventory(Base):
__tablename__ = "inventories"
__table_args__ = (UniqueConstraint("voucher_id", "batch_id"),)
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
voucher_id = Column(
"voucher_id",
UUID(as_uuid=True),
ForeignKey("vouchers.id"),
nullable=False,
index=True,
)
product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False)
batch_id = Column("batch_id", UUID(as_uuid=True), ForeignKey("batches.id"), nullable=False)
quantity = Column("quantity", Numeric(precision=15, scale=2), nullable=False)
rate = Column("rate", Numeric(precision=15, scale=2), nullable=False)
tax = Column("tax", Numeric(precision=15, scale=5), nullable=False)
discount = Column("discount", Numeric(precision=15, scale=5), nullable=False)
voucher = relationship("Voucher", back_populates="inventories")
def __init__(
self,
id_=None,
voucher_id=None,
product_id=None,
batch_id=None,
quantity=None,
rate=None,
tax=None,
discount=None,
batch=None,
product=None,
):
self.id = id_
self.voucher_id = voucher_id
if product is None:
self.product_id = product_id
else:
self.product = product
if batch is None:
self.batch_id = batch_id
else:
self.batch = batch
self.quantity = quantity
self.rate = rate
self.tax = tax
self.discount = discount
@hybrid_property
def amount(self):
return self.quantity * self.rate * (1 + self.tax) * (1 - self.discount)
class Batch(Base):
__tablename__ = "batches"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
name = Column("name", Date, nullable=False)
product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False)
quantity_remaining = Column("quantity_remaining", Numeric(precision=15, scale=2), nullable=False)
rate = Column("rate", Numeric(precision=15, scale=2), nullable=False)
tax = Column("tax", Numeric(precision=15, scale=5), nullable=False)
discount = Column("discount", Numeric(precision=15, scale=5), nullable=False)
inventories = relationship("Inventory", backref="batch", cascade=None, cascade_backrefs=False)
def __init__(
self,
name=None,
product_id=None,
quantity_remaining=None,
rate=None,
tax=None,
discount=None,
product=None,
):
self.name = name
self.product_id = product_id
self.quantity_remaining = quantity_remaining
self.rate = rate
self.tax = tax
self.discount = discount
if product is None:
self.product_id = product_id
else:
self.product = product
def amount(self):
return self.quantity_remaining * self.rate * (1 + self.tax) * (1 - self.discount)
@classmethod
def list(cls, q, include_nil, date, db: Session):
query = db.query(cls).join(cls.product)
if not include_nil:
query = query.filter(cls.quantity_remaining > 0)
if date is not None:
query = query.filter(cls.name <= date)
if q is not None:
for item in q.split():
query = query.filter(Product.name.ilike(f"%{item}%"))
return query.order_by(Product.name).order_by(cls.name).all()
@classmethod
def suspense(cls):
return uuid.UUID("a955790e-93cf-493c-a816-c7d92b127383")
class Attendance(Base):
__tablename__ = "attendances"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
employee_id = Column("employee_id", UUID(as_uuid=True), ForeignKey("employees.id"))
date = Column("date", Date, nullable=False)
attendance_type = Column("attendance_type", Integer)
amount = Column("amount", Numeric(precision=5, scale=2))
creation_date = Column("creation_date", DateTime(timezone=True))
user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id"))
is_valid = Column("is_valid", Boolean)
user = relationship("User", primaryjoin="User.id==Attendance.user_id")
def __init__(
self,
id_=None,
employee_id=None,
date=None,
attendance_type=None,
amount=None,
creation_date=None,
user_id=None,
is_valid=None,
):
self.id = id_
self.employee_id = employee_id
self.date = date
self.attendance_type = attendance_type
self.amount = amount if amount is not None else 0
self.creation_date = creation_date or datetime.utcnow()
self.user_id = user_id
self.is_valid = is_valid if is_valid is not None else True
def create(self, db: Session):
old = (
db.query(Attendance)
.filter(Attendance.date == self.date)
.filter(Attendance.employee_id == self.employee_id)
.filter(Attendance.is_valid == True) # noqa: E712
.first()
)
if old is None or old.attendance_type != self.attendance_type:
if old is not None:
old.is_valid = False
db.add(self)
class Fingerprint(Base):
__tablename__ = "fingerprints"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
employee_id = Column("employee_id", UUID(as_uuid=True), ForeignKey("employees.id"))
date = Column("date", DateTime)
def __init__(self, id_=None, employee_id=None, date=None):
self.id = id_
self.employee_id = employee_id
self.date = date
self.fingerprint_type = 0
class DbImage(Base):
__tablename__ = "images"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
resource_id = Column("resource_id", UUID(as_uuid=True), nullable=False)
resource_type = Column("resource_type", Unicode(255), nullable=False)
image = Column("image", BYTEA, nullable=False)
thumbnail = Column("thumbnail", BYTEA, nullable=False)
creation_date = Column("creation_date", DateTime(timezone=True), nullable=False)
def __init__(
self,
resource_id=None,
resource_type=None,
image=None,
thumbnail=None,
creation_date=None,
id_=None,
):
self.resource_id = resource_id
self.resource_type = resource_type
self.image = image
self.thumbnail = thumbnail
self.creation_date = creation_date or datetime.utcnow()
self.id = id_