337 lines
12 KiB
Python
337 lines
12 KiB
Python
from datetime import datetime
|
|
import uuid
|
|
|
|
from sqlalchemy.ext.hybrid import hybrid_property
|
|
from sqlalchemy import Column, Integer, Boolean, Unicode, DateTime, Numeric, ForeignKey
|
|
from sqlalchemy.orm import relationship, synonym, backref
|
|
|
|
from brewman.models.guidtype import GUID
|
|
from brewman.models import Base, DBSession
|
|
from brewman.models.master import Product
|
|
|
|
|
|
class VoucherType:
|
|
def __init__(self, id, name):
|
|
self.id = id
|
|
self.name = name
|
|
|
|
@classmethod
|
|
def list(cls):
|
|
list = []
|
|
list.append(VoucherType(1, 'Journal'))
|
|
list.append(VoucherType(2, 'Purchase'))
|
|
list.append(VoucherType(3, 'Issue'))
|
|
list.append(VoucherType(4, 'Payment'))
|
|
list.append(VoucherType(5, 'Receipt'))
|
|
list.append(VoucherType(6, 'Purchase Return'))
|
|
list.append(VoucherType(7, 'Opening Ledgers'))
|
|
list.append(VoucherType(8, 'Opening Batches'))
|
|
list.append(VoucherType(9, 'Verification'))
|
|
list.append(VoucherType(10, 'Opening Balance'))
|
|
list.append(VoucherType(11, 'Closing Balance'))
|
|
list.append(VoucherType(12, 'Salary Deduction'))
|
|
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__ = 'entities_vouchers'
|
|
|
|
id = Column('VoucherID', GUID(), primary_key=True, default=uuid.uuid4)
|
|
date = Column('Date', DateTime, nullable=False)
|
|
reconcile_date = Column('ReconcileDate', DateTime, nullable=False)
|
|
is_reconciled = Column('IsReconciled', DateTime, nullable=False)
|
|
narration = Column('Narration', Unicode(1000), nullable=False)
|
|
posted = Column('Posted', Boolean, nullable=False)
|
|
creation_date = Column('CreationDate', DateTime(timezone=True), nullable=False)
|
|
last_edit_date = Column('LastEditDate', DateTime(timezone=True), nullable=False)
|
|
_type = Column('VoucherType', Integer, nullable=False)
|
|
user_id = Column('UserID', GUID(), ForeignKey('auth_users.UserID'), nullable=False)
|
|
poster_id = Column('PosterID', GUID(), ForeignKey('auth_users.UserID'))
|
|
|
|
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', backref='voucher', cascade="delete, delete-orphan", cascade_backrefs=False)
|
|
inventories = relationship('Inventory', backref='voucher', cascade="delete, delete-orphan", cascade_backrefs=False)
|
|
salary_deductions = relationship('SalaryDeduction', 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)
|
|
|
|
@property
|
|
def __name__(self):
|
|
return self.name
|
|
|
|
def __init__(self, date=None, reconcile_date=None, narration='', posted=False, creation_date=None,
|
|
last_edit_date=None, type=None, user_id=None, poster_id=None, is_reconciled=False):
|
|
self.date = date
|
|
self.reconcile_date = reconcile_date if reconcile_date and is_reconciled else date
|
|
self.narration = narration
|
|
self.posted = posted
|
|
self.creation_date = datetime.utcnow() if creation_date is None else creation_date
|
|
self.last_edit_date = datetime.utcnow() if last_edit_date is None else last_edit_date
|
|
self.type = type
|
|
self.user_id = user_id
|
|
self.poster_id = poster_id
|
|
self.is_reconciled = is_reconciled
|
|
|
|
@classmethod
|
|
def by_id(cls, id):
|
|
return DBSession.query(cls).filter(cls.id == id).first()
|
|
|
|
@classmethod
|
|
def list(cls):
|
|
return DBSession.query(cls).all()
|
|
|
|
@classmethod
|
|
def query(cls):
|
|
return DBSession.query(cls)
|
|
|
|
|
|
class Journal(Base):
|
|
__tablename__ = 'entities_journals'
|
|
|
|
id = Column('JournalID', GUID(), primary_key=True, default=uuid.uuid4)
|
|
debit = Column('Debit', Integer)
|
|
amount = Column('Amount', Numeric)
|
|
voucher_id = Column('VoucherID', GUID(), ForeignKey('entities_vouchers.VoucherID'), nullable=False)
|
|
ledger_id = Column('LedgerID', GUID(), ForeignKey('entities_ledgers.LedgerID'), nullable=False)
|
|
cost_center_id = Column('CostCenterID', GUID(), ForeignKey('entities_costcenters.CostCenterID'), nullable=False)
|
|
|
|
@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, ledger_id=None, cost_center_id=None):
|
|
self.id = id
|
|
self.debit = debit
|
|
self.amount = amount
|
|
self.voucher_id = voucher_id
|
|
self.ledger_id = ledger_id
|
|
self.cost_center_id = cost_center_id
|
|
|
|
@classmethod
|
|
def by_id(cls, id):
|
|
return DBSession.query(cls).filter(cls.id == id).first()
|
|
|
|
@classmethod
|
|
def list(cls, voucher_id):
|
|
return DBSession.query(cls).filter(cls.voucher_id == voucher_id).all()
|
|
|
|
@classmethod
|
|
def query(cls):
|
|
return DBSession.query(cls)
|
|
|
|
|
|
class SalaryDeduction(Base):
|
|
__tablename__ = 'entities_salarydeductions'
|
|
id = Column('SalaryDeductionID', GUID(), primary_key=True, default=uuid.uuid4)
|
|
voucher_id = Column('VoucherID', GUID(), ForeignKey('entities_vouchers.VoucherID'), nullable=False)
|
|
journal_id = Column('JournalID', GUID(), ForeignKey('entities_journals.JournalID'), nullable=False)
|
|
gross_salary = Column('GrossSalary', Integer)
|
|
days_worked = Column('DaysWorked', Integer)
|
|
esi_ee = Column('EsiEmployee', Integer)
|
|
pf_ee = Column('PfEmployee', Integer)
|
|
esi_er = Column('EsiEmployer', Integer)
|
|
pf_er = Column('PfEmployer', Integer)
|
|
|
|
journal = relationship(Journal, backref=backref('salary_deduction', 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.journal_id = journal_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_id is None and journal is not None:
|
|
self.journal = journal
|
|
|
|
|
|
class Inventory(Base):
|
|
__tablename__ = 'entities_inventories'
|
|
# __tableagrs__ = (UniqueConstraint('VoucherID', 'ProductID'))
|
|
id = Column('InventoryID', GUID(), primary_key=True, default=uuid.uuid4)
|
|
voucher_id = Column('VoucherID', GUID(), ForeignKey('entities_vouchers.VoucherID'), nullable=False)
|
|
product_id = Column('ProductID', GUID(), ForeignKey('entities_products.ProductID'), nullable=False)
|
|
batch_id = Column('BatchID', GUID(), ForeignKey('entities_batches.BatchID'), nullable=False)
|
|
quantity = Column('Quantity', Numeric)
|
|
rate = Column('Rate', Numeric)
|
|
tax = Column('Tax', Numeric)
|
|
discount = Column('Discount', Numeric)
|
|
|
|
def __init__(self, id=None, voucher_id=None, product_id=None, batch_id=None, quantity=None, rate=None,
|
|
tax=None, discount=None, batch=None):
|
|
self.id = id
|
|
self.voucher_id = voucher_id
|
|
self.product_id = product_id
|
|
self.batch_id = batch_id
|
|
self.quantity = quantity
|
|
self.rate = rate
|
|
self.tax = tax
|
|
self.discount = discount
|
|
if batch_id is None and batch is not None:
|
|
self.batch = batch
|
|
|
|
@hybrid_property
|
|
def amount(self):
|
|
return self.quantity * self.rate * (1 + self.tax) * (1 - self.discount)
|
|
|
|
|
|
class Batch(Base):
|
|
__tablename__ = 'entities_batches'
|
|
|
|
id = Column('BatchID', GUID(), primary_key=True, default=uuid.uuid4)
|
|
name = Column('Name', DateTime)
|
|
product_id = Column('ProductID', GUID(), ForeignKey('entities_products.ProductID'), nullable=False)
|
|
quantity_remaining = Column('QuantityRemaining', Numeric)
|
|
rate = Column('Rate', Numeric)
|
|
tax = Column('Tax', Numeric)
|
|
discount = Column('Discount', Numeric)
|
|
|
|
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):
|
|
self.name = name
|
|
self.product_id = product_id
|
|
self.quantity_remaining = quantity_remaining
|
|
self.rate = rate
|
|
self.tax = tax
|
|
self.discount = discount
|
|
|
|
def amount(self):
|
|
return self.quantity_remaining * self.rate * (1 + self.tax) * (1 - self.discount)
|
|
|
|
@classmethod
|
|
def list(cls, name, include_nil, date):
|
|
query = DBSession.query(Batch).join(Batch.product)
|
|
if not include_nil:
|
|
query = query.filter(cls.quantity_remaining > 0)
|
|
if date is not None:
|
|
query = query.filter(cls.name <= date)
|
|
for item in name.split():
|
|
query = query.filter(Product.name.ilike('%' + item + '%'))
|
|
return query.order_by(Product.name).order_by(cls.name).all()
|
|
|
|
|
|
@classmethod
|
|
def by_id(cls, id):
|
|
return DBSession.query(cls).filter(cls.id == id).first()
|
|
|
|
@classmethod
|
|
def suspense(cls):
|
|
return uuid.UUID('a955790e-93cf-493c-a816-c7d92b127383')
|
|
|
|
|
|
class Attendance(Base):
|
|
__tablename__ = 'entities_attendances'
|
|
|
|
id = Column('AttendanceID', GUID(), primary_key=True, default=uuid.uuid4)
|
|
employee_id = Column('EmployeeID', GUID(), ForeignKey('entities_employees.LedgerID'))
|
|
date = Column('Date', DateTime)
|
|
attendance_type = Column('AttendanceType', Integer)
|
|
amount = Column('Amount', Numeric)
|
|
creation_date = Column('CreationDate', DateTime(timezone=True))
|
|
user_id = Column('UserID', GUID(), ForeignKey('auth_users.UserID'))
|
|
is_valid = Column('IsValid', 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 = datetime.utcnow() if creation_date is None else creation_date
|
|
self.user_id = user_id
|
|
self.is_valid = is_valid if is_valid is not None else True
|
|
|
|
@classmethod
|
|
def by_id(cls, id):
|
|
return DBSession.query(cls).filter(cls.id == id).first()
|
|
|
|
@classmethod
|
|
def query(cls):
|
|
return DBSession.query(cls)
|
|
|
|
def create(self):
|
|
old = DBSession.query(Attendance).filter(Attendance.date == self.date) \
|
|
.filter(Attendance.employee_id == self.employee_id) \
|
|
.filter(Attendance.is_valid == True).first()
|
|
if old is None or old.attendance_type != self.attendance_type:
|
|
if old is not None:
|
|
old.is_valid = False
|
|
DBSession.add(self)
|
|
|
|
|
|
class Fingerprint(Base):
|
|
__tablename__ = 'entities_fingerprints'
|
|
|
|
id = Column('FingerprintID', GUID(), primary_key=True, default=uuid.uuid4)
|
|
employee_id = Column('EmployeeID', GUID(), ForeignKey('entities_employees.LedgerID'))
|
|
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
|
|
|
|
@classmethod
|
|
def by_id(cls, id):
|
|
return DBSession.query(cls).filter(cls.id == id).first()
|
|
|
|
@classmethod
|
|
def query(cls):
|
|
return DBSession.query(cls)
|
|
|
|
def create(self):
|
|
old = DBSession.query(Fingerprint).filter(Fingerprint.date == self.date) \
|
|
.filter(Fingerprint.employee_id == self.employee_id).first()
|
|
if old is None:
|
|
DBSession.add(self)
|
|
return self
|
|
else:
|
|
return old
|
|
|