2012-08-06 17:06:10 +00:00
|
|
|
import uuid
|
2020-10-07 15:18:43 +00:00
|
|
|
|
2018-07-14 05:22:39 +00:00
|
|
|
from datetime import date
|
2014-04-29 10:08:44 +00:00
|
|
|
|
2016-12-24 11:41:01 +00:00
|
|
|
from sqlalchemy import (
|
2020-10-07 15:18:43 +00:00
|
|
|
Boolean,
|
2016-12-24 11:41:01 +00:00
|
|
|
Column,
|
2020-10-07 15:18:43 +00:00
|
|
|
Date,
|
|
|
|
ForeignKey,
|
2016-12-24 11:41:01 +00:00
|
|
|
Integer,
|
|
|
|
Numeric,
|
|
|
|
PickleType,
|
2020-10-07 15:18:43 +00:00
|
|
|
Unicode,
|
|
|
|
UniqueConstraint,
|
|
|
|
func,
|
2016-12-24 11:41:01 +00:00
|
|
|
)
|
2020-06-30 06:02:09 +00:00
|
|
|
from sqlalchemy.dialects.postgresql import UUID
|
2020-10-07 15:18:43 +00:00
|
|
|
from sqlalchemy.orm import Session, relationship
|
|
|
|
|
2018-07-14 05:22:39 +00:00
|
|
|
from .meta import Base
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2013-07-07 20:03:02 +00:00
|
|
|
|
2016-03-14 09:58:17 +00:00
|
|
|
class Product(Base):
|
2019-04-06 04:13:12 +00:00
|
|
|
__tablename__ = "products"
|
2020-05-10 15:06:19 +00:00
|
|
|
__table_args__ = (UniqueConstraint("name", "units"),)
|
|
|
|
|
2020-06-30 06:02:09 +00:00
|
|
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
2020-05-10 15:06:19 +00:00
|
|
|
code = Column("code", Integer, unique=True)
|
|
|
|
name = Column("name", Unicode(255), nullable=False)
|
|
|
|
units = Column("units", Unicode(255), nullable=False)
|
|
|
|
fraction = Column("fraction", Numeric, nullable=False)
|
|
|
|
fraction_units = Column("fraction_units", Unicode(255), nullable=False)
|
|
|
|
product_yield = Column("product_yield", Numeric, nullable=False)
|
2020-10-07 15:18:43 +00:00
|
|
|
product_group_id = Column(
|
|
|
|
"product_group_id",
|
|
|
|
UUID(as_uuid=True),
|
|
|
|
ForeignKey("product_groups.id"),
|
|
|
|
nullable=False,
|
|
|
|
)
|
2020-10-07 16:59:24 +00:00
|
|
|
account_id = Column(
|
|
|
|
"account_id", UUID(as_uuid=True), ForeignKey("accounts.id"), nullable=False
|
|
|
|
)
|
2019-04-06 04:13:12 +00:00
|
|
|
price = Column("cost_price", Numeric, nullable=False)
|
|
|
|
sale_price = Column("sale_price", Numeric, nullable=False)
|
2020-05-10 15:06:19 +00:00
|
|
|
is_active = Column("is_active", Boolean, nullable=False)
|
|
|
|
is_fixture = Column("is_fixture", Boolean, nullable=False)
|
2019-04-06 04:13:12 +00:00
|
|
|
is_purchased = Column("is_purchased", Boolean, nullable=False)
|
|
|
|
is_sold = Column("is_sold", Boolean, nullable=False)
|
|
|
|
|
|
|
|
batches = relationship("Batch", backref="product")
|
|
|
|
inventories = relationship("Inventory", backref="product")
|
|
|
|
recipes = relationship("Recipe", backref="product")
|
2020-10-07 16:59:24 +00:00
|
|
|
account = relationship(
|
|
|
|
"Account", primaryjoin="Account.id==Product.account_id", backref="products"
|
|
|
|
)
|
2019-04-06 04:13:12 +00:00
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
code=None,
|
|
|
|
name=None,
|
|
|
|
units=None,
|
|
|
|
fraction=None,
|
|
|
|
fraction_units=None,
|
|
|
|
product_yield=None,
|
|
|
|
product_group_id=None,
|
|
|
|
account_id=None,
|
|
|
|
price=None,
|
|
|
|
sale_price=None,
|
|
|
|
is_active=None,
|
|
|
|
is_purchased=None,
|
|
|
|
is_sold=None,
|
2020-06-01 15:10:52 +00:00
|
|
|
id_=None,
|
2019-04-06 04:13:12 +00:00
|
|
|
is_fixture=False,
|
|
|
|
):
|
2012-08-06 17:06:10 +00:00
|
|
|
self.code = code
|
|
|
|
self.name = name
|
|
|
|
self.units = units
|
|
|
|
self.fraction = fraction
|
|
|
|
self.fraction_units = fraction_units
|
2014-03-12 17:19:29 +00:00
|
|
|
self.product_yield = product_yield
|
2012-08-06 17:06:10 +00:00
|
|
|
self.product_group_id = product_group_id
|
2018-07-07 11:01:44 +00:00
|
|
|
self.account_id = account_id
|
2012-10-11 21:00:36 +00:00
|
|
|
self.price = price
|
2016-03-14 09:58:17 +00:00
|
|
|
self.sale_price = sale_price
|
2014-04-29 10:08:44 +00:00
|
|
|
self.is_active = is_active
|
2016-03-14 09:58:17 +00:00
|
|
|
self.is_purchased = is_purchased
|
|
|
|
self.is_sold = is_sold
|
2020-06-01 15:10:52 +00:00
|
|
|
self.id = id_
|
2013-09-28 10:27:17 +00:00
|
|
|
self.is_fixture = is_fixture
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def full_name(self):
|
|
|
|
return "{0} ({1})".format(self.name, self.units)
|
|
|
|
|
2020-06-01 15:10:52 +00:00
|
|
|
def create(self, db: Session):
|
|
|
|
code = db.query(func.max(Product.code)).one()[0]
|
|
|
|
self.code = 1 if code is None else code + 1
|
|
|
|
db.add(self)
|
2012-10-13 14:06:34 +00:00
|
|
|
return self
|
|
|
|
|
2013-10-14 17:53:00 +00:00
|
|
|
def can_delete(self, advanced_delete):
|
|
|
|
if self.is_fixture:
|
2020-05-10 15:06:19 +00:00
|
|
|
return False, f"{self.name} is a fixture and cannot be edited or deleted."
|
2014-04-29 10:08:44 +00:00
|
|
|
if self.is_active:
|
2019-04-06 04:13:12 +00:00
|
|
|
return False, "Product is active"
|
2013-10-14 17:53:00 +00:00
|
|
|
if len(self.inventories) > 0 and not advanced_delete:
|
2019-04-06 04:13:12 +00:00
|
|
|
return False, "Product has entries"
|
|
|
|
return True, ""
|
2013-10-14 17:53:00 +00:00
|
|
|
|
2020-05-10 10:35:39 +00:00
|
|
|
@classmethod
|
2020-05-11 20:01:21 +00:00
|
|
|
def query(cls, q, is_purchased=None, active=None, db=None):
|
2020-05-10 10:35:39 +00:00
|
|
|
query_ = db.query(Product)
|
|
|
|
if active is not None:
|
|
|
|
query_ = query_.filter(Product.is_active == active)
|
|
|
|
if is_purchased is not None:
|
|
|
|
query_ = query_.filter(Product.is_purchased == is_purchased)
|
2020-05-11 20:01:21 +00:00
|
|
|
if q is not None:
|
|
|
|
for item in q.split():
|
2020-05-10 10:35:39 +00:00
|
|
|
if item.strip() != "":
|
|
|
|
query_ = query_.filter(Product.name.ilike("%" + item + "%"))
|
2020-05-10 16:55:37 +00:00
|
|
|
return query_
|
2020-05-10 10:35:39 +00:00
|
|
|
|
2013-10-14 17:53:00 +00:00
|
|
|
@classmethod
|
|
|
|
def suspense(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("aa79a643-9ddc-4790-ac7f-a41f9efb4c15")
|
2013-10-14 17:53:00 +00:00
|
|
|
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2014-04-29 10:08:44 +00:00
|
|
|
class Recipe(Base):
|
2019-04-06 04:13:12 +00:00
|
|
|
__tablename__ = "recipes"
|
|
|
|
|
2020-06-30 06:02:09 +00:00
|
|
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
2020-10-07 16:59:24 +00:00
|
|
|
product_id = Column(
|
|
|
|
"product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False
|
|
|
|
)
|
2019-04-06 04:13:12 +00:00
|
|
|
|
|
|
|
quantity = Column("quantity", Numeric, nullable=False)
|
|
|
|
cost_price = Column("cost_price", Numeric, nullable=False)
|
|
|
|
sale_price = Column("sale_price", Numeric, nullable=False)
|
|
|
|
notes = Column("notes", Unicode(255))
|
|
|
|
|
|
|
|
valid_from = Column("valid_from", Date, nullable=False)
|
|
|
|
valid_to = Column("valid_to", Date, nullable=False)
|
|
|
|
|
|
|
|
effective_from = Column("effective_from", Date, nullable=False)
|
|
|
|
effective_to = Column("effective_to", Date)
|
|
|
|
|
|
|
|
recipe_items = relationship("RecipeItem", backref="recipe")
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
product_id=None,
|
|
|
|
quantity=None,
|
|
|
|
cost_price=None,
|
|
|
|
sale_price=None,
|
|
|
|
valid_from=None,
|
|
|
|
valid_to=None,
|
|
|
|
notes=None,
|
|
|
|
effective_from=None,
|
2020-06-01 15:10:52 +00:00
|
|
|
id_=None,
|
2019-04-06 04:13:12 +00:00
|
|
|
):
|
2014-04-29 10:08:44 +00:00
|
|
|
self.product_id = product_id
|
|
|
|
self.quantity = quantity
|
2016-03-14 09:58:17 +00:00
|
|
|
self.cost_price = cost_price
|
2014-04-29 10:08:44 +00:00
|
|
|
self.sale_price = sale_price
|
2016-03-14 09:58:17 +00:00
|
|
|
self.valid_from = valid_from
|
|
|
|
self.valid_to = valid_to
|
2019-04-06 04:13:12 +00:00
|
|
|
self.notes = "" if notes is None else notes
|
2016-03-14 09:58:17 +00:00
|
|
|
self.effective_from = date.today() if effective_from is None else effective_from
|
|
|
|
self.effective_to = None
|
2020-06-01 15:10:52 +00:00
|
|
|
self.id = id_
|
2014-04-29 10:08:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
class RecipeItem(Base):
|
2019-04-06 04:13:12 +00:00
|
|
|
__tablename__ = "recipe_items"
|
|
|
|
__table_args__ = (UniqueConstraint("recipe_id", "product_id"),)
|
|
|
|
|
2020-10-07 16:59:24 +00:00
|
|
|
id = Column(
|
|
|
|
"recipe_item_id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
|
|
|
|
)
|
|
|
|
recipe_id = Column(
|
|
|
|
"recipe_id", UUID(as_uuid=True), ForeignKey("recipes.id"), nullable=False
|
|
|
|
)
|
|
|
|
product_id = Column(
|
|
|
|
"product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False
|
|
|
|
)
|
2019-04-06 04:13:12 +00:00
|
|
|
quantity = Column("quantity", Integer, nullable=False)
|
|
|
|
price = Column("price", Integer, nullable=False)
|
|
|
|
|
|
|
|
product = relationship("Product")
|
|
|
|
|
2020-10-07 16:59:24 +00:00
|
|
|
def __init__(
|
|
|
|
self, recipe_id=None, product_id=None, quantity=None, price=None, id_=None
|
|
|
|
):
|
2014-04-29 10:08:44 +00:00
|
|
|
self.recipe_id = recipe_id
|
2016-03-14 09:58:17 +00:00
|
|
|
self.product_id = product_id
|
2014-04-29 10:08:44 +00:00
|
|
|
self.quantity = quantity
|
|
|
|
self.price = price
|
2020-06-01 15:10:52 +00:00
|
|
|
self.id = id_
|
2014-04-29 10:08:44 +00:00
|
|
|
|
|
|
|
|
2012-08-06 17:06:10 +00:00
|
|
|
class ProductGroup(Base):
|
2019-04-06 04:13:12 +00:00
|
|
|
__tablename__ = "product_groups"
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2020-06-30 06:02:09 +00:00
|
|
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
2020-05-10 15:06:19 +00:00
|
|
|
name = Column("name", Unicode(255), unique=True)
|
|
|
|
is_fixture = Column("is_fixture", Boolean, nullable=False)
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2019-04-06 04:13:12 +00:00
|
|
|
products = relationship("Product", backref="product_group")
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2020-06-01 15:10:52 +00:00
|
|
|
def __init__(self, name=None, id_=None, is_fixture=False):
|
2012-08-06 17:06:10 +00:00
|
|
|
self.name = name
|
2020-06-01 15:10:52 +00:00
|
|
|
self.id = id_
|
2013-09-28 10:27:17 +00:00
|
|
|
self.is_fixture = is_fixture
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2014-04-29 10:08:44 +00:00
|
|
|
@classmethod
|
|
|
|
def menu_item(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("dad46805-f577-4e5b-8073-9b788e0173fc")
|
2014-04-29 10:08:44 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def semi(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("e6bf81b9-1e9b-499f-81d5-ab5662e9d9b1")
|
2014-04-29 10:08:44 +00:00
|
|
|
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2015-02-12 12:12:46 +00:00
|
|
|
class CostCentre(Base):
|
2019-04-06 04:13:12 +00:00
|
|
|
__tablename__ = "cost_centres"
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2020-06-30 06:02:09 +00:00
|
|
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
2020-05-10 15:06:19 +00:00
|
|
|
name = Column("name", Unicode(255), unique=True)
|
|
|
|
is_fixture = Column("is_fixture", Boolean, nullable=False)
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2019-04-06 04:13:12 +00:00
|
|
|
accounts = relationship("AccountBase", backref="cost_centre")
|
|
|
|
journals = relationship("Journal", backref="cost_centre")
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def __name__(self):
|
|
|
|
return self.name
|
|
|
|
|
2020-06-01 15:10:52 +00:00
|
|
|
def __init__(self, name=None, id_=None, is_fixture=False):
|
2012-08-06 17:06:10 +00:00
|
|
|
self.name = name
|
2020-06-01 15:10:52 +00:00
|
|
|
self.id = id_
|
2013-09-28 10:27:17 +00:00
|
|
|
self.is_fixture = is_fixture
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@classmethod
|
2015-02-12 12:12:46 +00:00
|
|
|
def cost_centre_purchase(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("7b845f95-dfef-fa4a-897c-f0baf15284a3")
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@classmethod
|
2015-02-12 12:12:46 +00:00
|
|
|
def cost_centre_kitchen(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("b2d398ce-e3cc-c542-9feb-5d7783e899df")
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2012-10-11 11:56:51 +00:00
|
|
|
@classmethod
|
2015-02-12 12:12:46 +00:00
|
|
|
def cost_centre_overall(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("36f59436-522a-0746-ae94-e0f746bf6c0d")
|
2012-10-11 11:56:51 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def overall(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return {
|
|
|
|
"id": uuid.UUID("36f59436-522a-0746-ae94-e0f746bf6c0d"),
|
|
|
|
"name": "Overall",
|
|
|
|
}
|
2012-10-11 11:56:51 +00:00
|
|
|
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2018-07-07 11:01:44 +00:00
|
|
|
class AccountBase(Base):
|
2019-04-06 04:13:12 +00:00
|
|
|
__tablename__ = "accounts"
|
|
|
|
|
2020-06-30 06:02:09 +00:00
|
|
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
2019-04-06 04:13:12 +00:00
|
|
|
code = Column("code", Integer, nullable=False)
|
|
|
|
name = Column("name", Unicode(255), unique=True, nullable=False)
|
|
|
|
type = Column("type", Integer, nullable=False)
|
|
|
|
account_type = Column("account_type", Unicode(50), nullable=False)
|
|
|
|
is_starred = Column("is_starred", Boolean, nullable=False)
|
|
|
|
is_active = Column("is_active", Boolean, nullable=False)
|
|
|
|
is_reconcilable = Column("is_reconcilable", Boolean, nullable=False)
|
2020-10-07 16:59:24 +00:00
|
|
|
cost_centre_id = Column(
|
|
|
|
"cost_centre_id",
|
|
|
|
UUID(as_uuid=True),
|
|
|
|
ForeignKey("cost_centres.id"),
|
|
|
|
nullable=False,
|
|
|
|
)
|
2019-04-06 04:13:12 +00:00
|
|
|
is_fixture = Column("is_fixture", Boolean, nullable=False)
|
|
|
|
|
|
|
|
__mapper_args__ = {"polymorphic_on": account_type}
|
|
|
|
|
2020-05-14 05:56:28 +00:00
|
|
|
journals = relationship("Journal", back_populates="account")
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def __name__(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
@property
|
|
|
|
def type_object(self):
|
2018-07-07 11:01:44 +00:00
|
|
|
return AccountType.by_id(self.type)
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2019-04-06 04:13:12 +00:00
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
code=None,
|
|
|
|
name=None,
|
2020-06-01 15:10:52 +00:00
|
|
|
type_=None,
|
2019-04-06 04:13:12 +00:00
|
|
|
is_starred=None,
|
|
|
|
is_active=None,
|
|
|
|
is_reconcilable=False,
|
|
|
|
cost_centre_id=None,
|
2020-06-01 15:10:52 +00:00
|
|
|
id_=None,
|
2019-04-06 04:13:12 +00:00
|
|
|
is_fixture=False,
|
|
|
|
):
|
2012-08-06 17:06:10 +00:00
|
|
|
self.code = code
|
|
|
|
self.name = name
|
2020-06-01 15:10:52 +00:00
|
|
|
self.type = type_
|
2018-07-07 11:01:44 +00:00
|
|
|
self.is_starred = is_starred
|
2012-08-06 17:06:10 +00:00
|
|
|
self.is_active = is_active
|
2012-11-04 09:57:46 +00:00
|
|
|
self.is_reconcilable = is_reconcilable
|
2015-02-12 12:12:46 +00:00
|
|
|
self.cost_centre_id = cost_centre_id
|
2020-06-01 15:10:52 +00:00
|
|
|
self.id = id_
|
2013-09-28 10:27:17 +00:00
|
|
|
self.is_fixture = is_fixture
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@classmethod
|
2020-05-10 10:35:39 +00:00
|
|
|
def query(cls, q, type_, reconcilable=None, active=None, db=None):
|
|
|
|
query_ = db.query(cls)
|
|
|
|
if type_ is not None:
|
|
|
|
if not isinstance(type_, int):
|
|
|
|
type_ = int(type_)
|
|
|
|
query_ = query_.filter(cls.type == type_)
|
2013-10-03 10:28:16 +00:00
|
|
|
if reconcilable is not None:
|
2020-05-10 10:35:39 +00:00
|
|
|
query_ = query_.filter(cls.is_reconcilable == reconcilable)
|
2013-10-03 10:28:16 +00:00
|
|
|
if active is not None:
|
2020-05-10 10:35:39 +00:00
|
|
|
query_ = query_.filter(cls.is_active == active)
|
|
|
|
if q is not None:
|
|
|
|
for item in q.split():
|
|
|
|
query_ = query_.filter(cls.name.ilike("%" + item + "%"))
|
|
|
|
return query_.order_by(cls.name)
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2020-06-01 15:10:52 +00:00
|
|
|
def create(self, db: Session):
|
2020-10-07 16:59:24 +00:00
|
|
|
code = (
|
|
|
|
db.query(func.max(AccountBase.code))
|
|
|
|
.filter(AccountBase.type == self.type)
|
|
|
|
.one()[0]
|
|
|
|
)
|
2020-06-01 15:10:52 +00:00
|
|
|
self.code = 1 if code is None else code + 1
|
|
|
|
db.add(self)
|
2012-08-06 17:06:10 +00:00
|
|
|
return self
|
|
|
|
|
2013-09-29 19:39:02 +00:00
|
|
|
def can_delete(self, advanced_delete):
|
2013-09-28 10:27:17 +00:00
|
|
|
if self.is_fixture:
|
2020-06-01 15:10:52 +00:00
|
|
|
return False, f"{self.name} is a fixture and cannot be edited or deleted."
|
2012-12-07 13:26:26 +00:00
|
|
|
if self.is_active:
|
2019-04-06 04:13:12 +00:00
|
|
|
return False, "Account is active"
|
2013-09-29 19:39:02 +00:00
|
|
|
if len(self.journals) > 0 and not advanced_delete:
|
2019-04-06 04:13:12 +00:00
|
|
|
return False, "Account has journal entries"
|
|
|
|
return True, ""
|
2012-12-07 13:26:26 +00:00
|
|
|
|
2017-02-06 07:39:15 +00:00
|
|
|
@classmethod
|
2020-06-01 15:10:52 +00:00
|
|
|
def get_code(cls, type_, db: Session):
|
2020-10-07 16:59:24 +00:00
|
|
|
code = (
|
|
|
|
db.query(func.max(AccountBase.code))
|
|
|
|
.filter(AccountBase.type == type_)
|
|
|
|
.one()[0]
|
|
|
|
)
|
2017-02-06 07:39:15 +00:00
|
|
|
return 1 if code is None else code + 1
|
|
|
|
|
2012-09-12 08:22:28 +00:00
|
|
|
@classmethod
|
|
|
|
def all_purchases(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("240dd899-c413-854c-a7eb-67a29d154490")
|
2012-09-12 08:22:28 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def cash_in_hand(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return {"id": "ed2341bb-80b8-9649-90db-f9aaca183bb3", "name": "Cash in Hand"}
|
2012-09-12 08:22:28 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def local_purchase(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return {"id": "d2b75912-505f-2548-9093-466dfff6a0f9", "name": "Local Purchase"}
|
2012-09-12 08:22:28 +00:00
|
|
|
|
2012-11-08 18:43:04 +00:00
|
|
|
@classmethod
|
|
|
|
def salary(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return {"id": "5c2b54d0-c174-004d-a0d5-92cdaadcefa7", "name": "Staff Salary"}
|
2012-11-08 18:43:04 +00:00
|
|
|
|
2020-05-29 20:28:17 +00:00
|
|
|
@classmethod
|
|
|
|
def salary_id(cls):
|
|
|
|
return uuid.UUID("5c2b54d0-c174-004d-a0d5-92cdaadcefa7")
|
|
|
|
|
2014-12-25 11:10:47 +00:00
|
|
|
@classmethod
|
2020-05-12 15:22:07 +00:00
|
|
|
def incentive(cls):
|
|
|
|
return {"id": "b7eff754-e8ba-e047-ab06-9132c15c7640", "name": "Incentives"}
|
2014-12-25 11:10:47 +00:00
|
|
|
|
2015-02-12 12:12:46 +00:00
|
|
|
@classmethod
|
2020-05-12 15:22:07 +00:00
|
|
|
def incentive_id(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("b7eff754-e8ba-e047-ab06-9132c15c7640")
|
2015-02-12 12:12:46 +00:00
|
|
|
|
2012-11-28 07:58:16 +00:00
|
|
|
@classmethod
|
|
|
|
def esi_pf_expense(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("d2a1a286-e900-764b-a1a5-9f4b00dbb940")
|
2012-11-28 07:58:16 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def esi_pf_payable(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("42277912-cc18-854b-b134-9f4b00dba419")
|
2012-11-28 07:58:16 +00:00
|
|
|
|
2013-09-29 19:39:02 +00:00
|
|
|
@classmethod
|
|
|
|
def suspense(cls):
|
2019-04-06 04:13:12 +00:00
|
|
|
return uuid.UUID("3854e317-6f3b-5142-ab26-9c44d4cddd08")
|
2013-09-29 19:39:02 +00:00
|
|
|
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2018-07-07 11:01:44 +00:00
|
|
|
class Employee(AccountBase):
|
2019-04-06 04:13:12 +00:00
|
|
|
__tablename__ = "employees"
|
|
|
|
__mapper_args__ = {"polymorphic_identity": "employees"}
|
|
|
|
|
2020-06-30 06:02:09 +00:00
|
|
|
id = Column("id", UUID(as_uuid=True), ForeignKey(AccountBase.id), primary_key=True)
|
2020-05-14 16:19:22 +00:00
|
|
|
designation = Column("designation", Unicode(255), nullable=False)
|
|
|
|
salary = Column("salary", Integer, nullable=False)
|
|
|
|
points = Column("points", Numeric(precision=5, scale=2), nullable=False)
|
|
|
|
joining_date = Column("joining_date", Date, nullable=False)
|
|
|
|
leaving_date = Column("leaving_date", Date, nullable=True)
|
2019-04-06 04:13:12 +00:00
|
|
|
|
2020-10-07 16:59:24 +00:00
|
|
|
attendances = relationship(
|
|
|
|
"Attendance", backref="employee", cascade=None, cascade_backrefs=False
|
|
|
|
)
|
|
|
|
fingerprints = relationship(
|
|
|
|
"Fingerprint", backref="employee", cascade=None, cascade_backrefs=False
|
|
|
|
)
|
2019-04-06 04:13:12 +00:00
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
code=None,
|
|
|
|
name=None,
|
|
|
|
is_starred=None,
|
|
|
|
is_active=None,
|
|
|
|
cost_centre_id=None,
|
|
|
|
designation=None,
|
|
|
|
salary=None,
|
2020-05-10 08:02:08 +00:00
|
|
|
points=None,
|
2019-04-06 04:13:12 +00:00
|
|
|
joining_date=None,
|
|
|
|
leaving_date=None,
|
|
|
|
):
|
2012-08-06 17:06:10 +00:00
|
|
|
self.designation = designation
|
|
|
|
self.salary = salary
|
2020-05-10 08:02:08 +00:00
|
|
|
self.points = points
|
2012-08-06 17:06:10 +00:00
|
|
|
self.joining_date = joining_date
|
|
|
|
self.leaving_date = leaving_date
|
2019-04-06 04:13:12 +00:00
|
|
|
super().__init__(
|
|
|
|
code=code,
|
|
|
|
name=name,
|
2020-06-01 15:10:52 +00:00
|
|
|
type_=10,
|
2019-04-06 04:13:12 +00:00
|
|
|
is_starred=is_starred,
|
|
|
|
is_active=is_active,
|
|
|
|
is_reconcilable=False,
|
|
|
|
cost_centre_id=cost_centre_id,
|
|
|
|
)
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2020-06-01 15:10:52 +00:00
|
|
|
def create(self, db: Session):
|
2020-10-07 16:59:24 +00:00
|
|
|
code = (
|
|
|
|
db.query(func.max(AccountBase.code))
|
|
|
|
.filter(AccountBase.type == self.type)
|
|
|
|
.one()[0]
|
|
|
|
)
|
2020-06-30 06:02:09 +00:00
|
|
|
self.code = 1 if code is None else code + 1
|
2020-06-01 15:10:52 +00:00
|
|
|
self.name += f" ({str(self.code)})"
|
|
|
|
db.add(self)
|
2012-08-06 17:06:10 +00:00
|
|
|
return self
|
|
|
|
|
2013-09-29 19:39:02 +00:00
|
|
|
def can_delete(self, advanced_delete):
|
|
|
|
return super(Employee, self).can_delete(advanced_delete)
|
|
|
|
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2018-07-07 11:01:44 +00:00
|
|
|
class Account(AccountBase):
|
2019-04-06 04:13:12 +00:00
|
|
|
__mapper_args__ = {"polymorphic_identity": ""}
|
2012-08-06 17:06:10 +00:00
|
|
|
|
2013-09-29 19:39:02 +00:00
|
|
|
def can_delete(self, advanced_delete):
|
|
|
|
if len(self.products) > 0:
|
2019-04-06 04:13:12 +00:00
|
|
|
return False, "Account has products"
|
2018-07-07 11:01:44 +00:00
|
|
|
return super(Account, self).can_delete(advanced_delete)
|
2013-09-29 19:39:02 +00:00
|
|
|
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
class AttendanceType:
|
2020-05-12 15:22:07 +00:00
|
|
|
def __init__(self, id_, name, value=None):
|
|
|
|
self.id = id_
|
2012-08-06 17:06:10 +00:00
|
|
|
self.name = name
|
|
|
|
self.value = value
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def list(cls):
|
2020-06-02 03:05:36 +00:00
|
|
|
return [
|
2019-04-06 04:13:12 +00:00
|
|
|
AttendanceType(0, "Not Set", 0),
|
|
|
|
AttendanceType(1, "Present", 1),
|
|
|
|
AttendanceType(2, "Off Day", 1),
|
|
|
|
AttendanceType(3, "On Leave", 0),
|
|
|
|
AttendanceType(4, "Absent", 0),
|
|
|
|
AttendanceType(5, "Half Day", 0.5),
|
|
|
|
AttendanceType(6, "Double Duty", 2),
|
|
|
|
AttendanceType(7, "Paid Leave Availed", 1),
|
|
|
|
AttendanceType(8, "Casual Leave Availed", 1),
|
|
|
|
AttendanceType(9, "Compensatory Off", 1),
|
|
|
|
AttendanceType(10, "Half Day + PL", 1),
|
|
|
|
AttendanceType(11, "Half Day + CL", 1),
|
|
|
|
]
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def by_name(cls, name):
|
2020-06-02 03:05:36 +00:00
|
|
|
return next(i for i in cls.list() if i.name == name)
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@classmethod
|
2020-06-01 15:10:52 +00:00
|
|
|
def by_id(cls, id_):
|
2020-06-02 03:05:36 +00:00
|
|
|
return next(i for i in cls.list() if i.id == id_)
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
|
2018-07-07 11:01:44 +00:00
|
|
|
class AccountType:
|
2019-04-06 04:13:12 +00:00
|
|
|
def __init__(
|
2020-10-07 15:18:43 +00:00
|
|
|
self,
|
|
|
|
id_,
|
|
|
|
name,
|
|
|
|
balance_sheet=None,
|
|
|
|
debit=None,
|
|
|
|
cash_flow_classification=None,
|
|
|
|
order=None,
|
|
|
|
show_in_list=None,
|
2019-04-06 04:13:12 +00:00
|
|
|
):
|
2020-06-01 15:10:52 +00:00
|
|
|
self.id = id_
|
2012-08-06 17:06:10 +00:00
|
|
|
self.name = name
|
|
|
|
self.balance_sheet = balance_sheet
|
|
|
|
self.debit = debit
|
2017-02-06 07:39:15 +00:00
|
|
|
self.cash_flow_classification = cash_flow_classification
|
|
|
|
# Cash flow Classifications are:
|
|
|
|
# Cash
|
|
|
|
# Operating
|
|
|
|
# Investing
|
|
|
|
# Financing
|
2012-08-06 17:06:10 +00:00
|
|
|
self.order = order
|
|
|
|
self.show_in_list = show_in_list
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def list(cls):
|
2020-06-01 15:10:52 +00:00
|
|
|
return [
|
2020-07-16 07:39:22 +00:00
|
|
|
AccountType(1, "Cash", True, True, "Cash", 10000, True),
|
|
|
|
AccountType(2, "Purchase", False, True, "Operating", 20000, True),
|
|
|
|
AccountType(3, "Sale", False, False, "Operating", 10000, True),
|
|
|
|
AccountType(4, "Assets", True, True, "Investing", 20000, True),
|
|
|
|
AccountType(5, "Capital", True, False, "Financing", 70000, True),
|
|
|
|
AccountType(6, "Debtors", True, True, "Operating", 30000, True),
|
|
|
|
AccountType(7, "Expenses", False, True, "Operating", 40000, True),
|
|
|
|
AccountType(9, "Creditors", True, False, "Operating", 60000, True),
|
|
|
|
AccountType(10, "Salary", True, True, "Operating", 40000, False),
|
|
|
|
AccountType(11, "Liabilities", True, False, "Operating", 50000, True),
|
|
|
|
AccountType(12, "Revenue", False, False, "Operating", 30000, True),
|
|
|
|
AccountType(13, "Tax", True, False, "Operating", 80000, True),
|
2019-04-06 04:13:12 +00:00
|
|
|
]
|
2018-07-07 11:01:44 +00:00
|
|
|
# list.append(AccountType(8, 'Discount', False, False, True, 30, True))
|
|
|
|
# list.append(AccountType(14, 'Total', False, False, False, 900, False))
|
|
|
|
# list.append(AccountType(15, 'Net', False, False, False, 1000, False))
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def by_name(cls, name):
|
2020-06-02 03:05:36 +00:00
|
|
|
return next(i for i in cls.list() if i.name == name)
|
2012-08-06 17:06:10 +00:00
|
|
|
|
|
|
|
@classmethod
|
2020-06-01 15:10:52 +00:00
|
|
|
def by_id(cls, id_):
|
2020-06-02 03:05:36 +00:00
|
|
|
return next(i for i in cls.list() if i.id == id_)
|
2013-07-07 20:03:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
class DbSetting(Base):
|
2019-04-06 04:13:12 +00:00
|
|
|
__tablename__ = "settings"
|
2013-07-07 20:03:02 +00:00
|
|
|
|
2020-06-30 06:02:09 +00:00
|
|
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
2020-05-14 16:19:22 +00:00
|
|
|
name = Column("name", Unicode(255), unique=True, nullable=False)
|
|
|
|
data = Column("data", PickleType)
|
2013-07-07 20:03:02 +00:00
|
|
|
|
2020-06-01 15:10:52 +00:00
|
|
|
def __init__(self, id_=None, name=None, data=None):
|
|
|
|
self.id = id_
|
2013-07-07 20:03:02 +00:00
|
|
|
self.name = name
|
|
|
|
self.data = data
|