Feature: The app checks if the database schema is not created and creates it automatially on first run.
Fix: While user login try to catch None password error. Fix: Rename Yeild to the correct spelling Yield. Fix: Wrong column type for IsReconciled in Voucher. Fix: Redirect user on login to last page. Fix: Validate input in save/update of employee and product
This commit is contained in:
parent
f4551c8b5a
commit
69071182a3
brewman
models
static/partial
views
@ -8,14 +8,118 @@ from sqlalchemy.orm import sessionmaker
|
||||
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), expire_on_commit=False))
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
def initialize_sql(engine):
|
||||
# from brewman.models.messaging import Tag, Thread, Subscriber, thread_tag, Post
|
||||
# from brewman.models.voucher import Attendance, Batch, Fingerprint, Inventory, Journal, Product, SalaryDeduction, Voucher, VoucherType
|
||||
# from brewman.models.master import Product, AttendanceType, CostCenter, Employee, Ledger, LedgerBase, LedgerType, ProductGroup
|
||||
# from brewman.models.auth import Client, Group, Role, User, role_group, user_group
|
||||
# from .master import DbSetting
|
||||
DBSession.configure(bind=engine)
|
||||
Base.metadata.bind = engine
|
||||
# Base.metadata.create_all(engine)
|
||||
if not schema_exists(engine):
|
||||
fixtures(engine)
|
||||
|
||||
|
||||
def schema_exists(engine):
|
||||
from brewman.models.master import DbSetting
|
||||
with engine.connect() as connection:
|
||||
return engine.dialect.has_table(connection, DbSetting.__tablename__)
|
||||
|
||||
|
||||
def fixtures(engine):
|
||||
import transaction
|
||||
import uuid
|
||||
from brewman.models.messaging import Tag, Thread, Subscriber, thread_tag, Post
|
||||
from brewman.models.voucher import Attendance, Batch, Fingerprint, Inventory, Journal, Product, SalaryDeduction, Voucher, VoucherType
|
||||
from brewman.models.master import Product, AttendanceType, CostCenter, Employee, Ledger, LedgerBase, LedgerType, ProductGroup
|
||||
from brewman.models.auth import Client, Group, Role, User, role_group, user_group
|
||||
|
||||
Base.metadata.create_all(engine)
|
||||
|
||||
user = User('Admin', '123456', False, uuid.UUID('8de98592-76d9-c74d-bb3f-d6184d388b5a'))
|
||||
DBSession.add(user)
|
||||
|
||||
groups = [Group('Owner', uuid.UUID('52e08c0c-048a-784f-be10-6e129ad4b5d4')),
|
||||
Group('Accountant', uuid.UUID('bc4c2d23-437a-984d-abd4-7d5fce677547')),
|
||||
Group('Accounts Manager', uuid.UUID('cfc44fa7-3392-5b45-b311-5959333f568f'))]
|
||||
|
||||
for group in groups:
|
||||
DBSession.add(group)
|
||||
user.groups.append(group)
|
||||
|
||||
roles = [Role('Attendance', uuid.UUID('09d05434-a09a-fa45-963b-769a2e3fc667')),
|
||||
Role('Trial Balance', uuid.UUID('3b099fec-ddc5-4243-b30e-afb78d9ca14a')),
|
||||
Role('Cash Flow', uuid.UUID('c4d3ae29-420b-ea4c-ae90-00a356263fd9')),
|
||||
Role('Cost Centers', uuid.UUID('6fcc1a20-6aec-e840-b334-1632b34aeab8')),
|
||||
Role('Users', uuid.UUID('c5b7d9d7-f178-0e45-8ea4-bf4e08ec901b')),
|
||||
Role('Daybook', uuid.UUID('c3edb554-a057-8942-8030-37b8e926d583')),
|
||||
Role('Edit Posted Vouchers', uuid.UUID('d6675817-ddf5-bf40-9de6-fa223eb4aaa6')),
|
||||
Role('Employees', uuid.UUID('e4edd0ac-7f5d-e64d-8611-73fdc4cd8ba2')),
|
||||
Role('Fingerprints', uuid.UUID('d9c45323-f997-ba46-9407-8a7145f0828b')),
|
||||
Role('Issue', uuid.UUID('03b602eb-f58a-b94f-af58-8cb47d7849d0')),
|
||||
Role('Journal', uuid.UUID('7661388f-62ce-1c41-8e0d-0326ee5d4018')),
|
||||
Role('Accounts', uuid.UUID('f438262f-72dd-2f4e-9186-5abc3af44fba')),
|
||||
Role('Product Ledger', uuid.UUID('018a2408-e804-1446-90c5-b015829da6ba')),
|
||||
Role('Backdated Vouchers', uuid.UUID('b67b2062-5ca7-134f-8258-5d284dd92426')),
|
||||
Role('Payment', uuid.UUID('f85c0b52-c3fd-7141-8957-7a56cdc014a4')),
|
||||
Role('Post Vouchers', uuid.UUID('36e741da-1a57-b047-a59e-dcd58fcf4338')),
|
||||
Role('Products', uuid.UUID('74fa6d21-eebb-e14c-8153-bebc57190ab4')),
|
||||
Role('Product Groups', uuid.UUID('08413a22-cf88-fd43-b2b7-365d2951d99f')),
|
||||
Role('Profit & Loss', uuid.UUID('0492ebb3-76f3-204e-ab94-bbfe880f0691')),
|
||||
Role('Purchase', uuid.UUID('12335acb-8630-2d41-a191-1517c8d172de')),
|
||||
Role('Purchase Entries', uuid.UUID('78a6422b-aa11-174c-9dfa-412a99e87e02')),
|
||||
Role('Purchase Return', uuid.UUID('ab33196e-d9e4-114c-ac8c-997954363756')),
|
||||
Role('Receipt', uuid.UUID('1f1ce53e-76ff-a346-974a-65db6f606e5f')),
|
||||
Role('Closing Stock', uuid.UUID('97515732-24e4-c94d-9585-d4bd7f6c7891')),
|
||||
Role('Ledger', uuid.UUID('a2120944-243f-3f49-be57-0ad633ce4801')),
|
||||
Role('Raw Material Cost', uuid.UUID('d462842b-baf1-2343-95e5-ffdba9bbc163')),
|
||||
Role('Edit Other User\'s Vouchers', uuid.UUID('a8328891-7ce2-a943-8c29-2eabc1ffeea3')),
|
||||
Role('Clients', uuid.UUID('cfad44f0-f2a9-7045-89d7-9019cf0f371a')),
|
||||
Role('Salary Deduction', uuid.UUID('92d70e80-1c32-384d-959e-abf84b804696')),
|
||||
Role('Messages', uuid.UUID('f586d128-b6d9-4090-a913-78fcbdb68e59')),
|
||||
Role('Lock Date', uuid.UUID('d52de0be-9388-4b0b-a359-7e122ab6e53a')),
|
||||
Role('Net Transactions', uuid.UUID('2c40f7cf-67fc-4efa-a670-8d16a2e7884d')),
|
||||
Role('Balance Sheet', uuid.UUID('40deb018-b8f2-460a-88be-8972c9fcdf04')),
|
||||
Role('Advanced Delete', uuid.UUID('197ebcd2-bc4a-4b65-a138-ce942ece32ea')),
|
||||
Role('Rebase', uuid.UUID('de204a88-5f9d-4579-a2d6-aa2f25efde42')),
|
||||
Role('Reset Stock', uuid.UUID('aecaf82f-aa41-4634-b754-0c1308b621b1')),
|
||||
Role('Reconcile', uuid.UUID('a5cb51cb-e38e-4705-84a7-cc1e9a8b866b')),
|
||||
Role('Stock Movement', uuid.UUID('20b707ee-2b59-41ad-be87-76d5fe1efca8')),
|
||||
Role('Purchases', uuid.UUID('cf7019c8-3fd3-45b0-9a42-601029ce5b71')),
|
||||
Role('Dashboard', uuid.UUID('53eecc09-bd06-4890-b6f5-6885dda762d4'))]
|
||||
|
||||
for role in roles:
|
||||
DBSession.add(role)
|
||||
groups[0].roles.append(role)
|
||||
|
||||
cost_centers = [CostCenter('Overall', uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), True),
|
||||
CostCenter('Purchase', uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3'), True),
|
||||
CostCenter('Kitchen', uuid.UUID('b2d398ce-e3cc-c542-9feb-5d7783e899df'), True)]
|
||||
|
||||
for cost_center in cost_centers:
|
||||
DBSession.add(cost_center)
|
||||
|
||||
ledgers = [Ledger(1, 'All Purchases', 2, True, False, uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3'),
|
||||
uuid.UUID('240dd899-c413-854c-a7eb-67a29d154490'), True),
|
||||
Ledger(1, 'Local Purchase', 9, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'),
|
||||
uuid.UUID('d2b75912-505f-2548-9093-466dfff6a0f9'), True),
|
||||
Ledger(1, 'ESI/PF - Payable', 11, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'),
|
||||
uuid.UUID('42277912-cc18-854b-b134-9f4b00dba419'), True),
|
||||
Ledger(2, 'ESI/PF - Expense', 7, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'),
|
||||
uuid.UUID('d2a1a286-e900-764b-a1a5-9f4b00dbb940'), True),
|
||||
Ledger(1, 'Cash in Hand', 1, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'),
|
||||
uuid.UUID('ed2341bb-80b8-9649-90db-f9aaca183bb3'), True),
|
||||
Ledger(1, 'Staff Salary', 7, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'),
|
||||
uuid.UUID('5c2b54d0-c174-004d-a0d5-92cdaadcefa7'), True),
|
||||
Ledger(1, 'Suspense', 4, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'),
|
||||
uuid.UUID('3854e317-6f3b-5142-ab26-9c44d4cddd08'), True)]
|
||||
|
||||
for ledger in ledgers:
|
||||
DBSession.add(ledger)
|
||||
|
||||
product_group = ProductGroup('Suspense', uuid.UUID('ae59a20c-87bb-444a-8abb-915ad5e58b83'), True)
|
||||
DBSession.add(product_group)
|
||||
|
||||
product = Product(1, 'Suspense', '', 1, '', 1, False, uuid.UUID('ae59a20c-87bb-444a-8abb-915ad5e58b83'),
|
||||
uuid.UUID('240dd899-c413-854c-a7eb-67a29d154490'), 0, True,
|
||||
uuid.UUID('aa79a643-9ddc-4790-ac7f-a41f9efb4c15'), True)
|
||||
DBSession.add(product)
|
||||
|
||||
transaction.commit()
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
import random
|
||||
import string
|
||||
import uuid
|
||||
from sqlalchemy.schema import ForeignKey, Table
|
||||
from brewman.models.guidtype import GUID
|
||||
from hashlib import md5
|
||||
|
||||
from sqlalchemy.schema import ForeignKey, Table
|
||||
from sqlalchemy import Column, Boolean, Unicode, Integer
|
||||
|
||||
from sqlalchemy.orm import synonym, relationship
|
||||
|
||||
from brewman.models.guidtype import GUID
|
||||
from brewman.models import Base
|
||||
from brewman.models import DBSession
|
||||
|
||||
|
||||
def encrypt(val):
|
||||
return md5(val.encode('utf-8') + "Salt".encode('utf-8')).hexdigest()
|
||||
|
||||
@ -68,7 +68,6 @@ user_group = Table(
|
||||
Column('GroupID', GUID(), ForeignKey('auth_groups.GroupID'))
|
||||
)
|
||||
|
||||
|
||||
role_group = Table(
|
||||
'auth_rolegroups', Base.metadata,
|
||||
Column('RoleGroupID', GUID(), primary_key=True, default=uuid.uuid4),
|
||||
@ -101,10 +100,11 @@ class User(Base):
|
||||
def __name__(self):
|
||||
return self.name
|
||||
|
||||
def __init__(self, name=None, password=None, locked_out=None):
|
||||
def __init__(self, name=None, password=None, locked_out=None, id=None):
|
||||
self.name = name
|
||||
self.password = password
|
||||
self.locked_out = locked_out
|
||||
self.id = id
|
||||
|
||||
@classmethod
|
||||
def by_name(cls, name):
|
||||
@ -120,6 +120,8 @@ class User(Base):
|
||||
|
||||
@classmethod
|
||||
def auth(cls, name, password):
|
||||
if password is None:
|
||||
return False, None
|
||||
user = cls.by_name(name)
|
||||
if not user:
|
||||
return False, None
|
||||
@ -150,8 +152,10 @@ class Group(Base):
|
||||
id = Column('GroupID', GUID(), primary_key=True, default=uuid.uuid4)
|
||||
name = Column('Name', Unicode(255), unique=True)
|
||||
|
||||
def __init__(self, name=None):
|
||||
|
||||
def __init__(self, name=None, id=None):
|
||||
self.name = name
|
||||
self.id = id
|
||||
|
||||
@classmethod
|
||||
def by_id(cls, id):
|
||||
@ -170,8 +174,9 @@ class Role(Base):
|
||||
|
||||
groups = relationship("Group", secondary=role_group, backref="roles")
|
||||
|
||||
def __init__(self, name=None):
|
||||
def __init__(self, name=None, id=None):
|
||||
self.name = name
|
||||
self.id = id
|
||||
|
||||
@classmethod
|
||||
def list(cls):
|
||||
|
@ -17,7 +17,7 @@ class Product(Base):
|
||||
units = Column('Units', Unicode(255), nullable=False)
|
||||
fraction = Column('Fraction', Numeric, nullable=False)
|
||||
fraction_units = Column('FractionUnits', Unicode(255), nullable=False)
|
||||
yeild = Column('Yeild', Numeric, nullable=False)
|
||||
product_yield = Column('ProductYield', Numeric, nullable=False)
|
||||
show_for_purchase = Column('ShowForPurchase', Boolean, nullable=False)
|
||||
product_group_id = Column('ProductGroupID', GUID(), ForeignKey('entities_productgroups.ProductGroupID'),
|
||||
nullable=False)
|
||||
@ -31,20 +31,21 @@ class Product(Base):
|
||||
|
||||
ledger = relationship('Ledger', primaryjoin="Ledger.id==Product.ledger_id", backref='products')
|
||||
|
||||
def __init__(self, code=None, name=None, units=None, fraction=None, fraction_units=None, yeild=None,
|
||||
def __init__(self, code=None, name=None, units=None, fraction=None, fraction_units=None, product_yield=None,
|
||||
show_for_purchase=None, product_group_id=None, ledger_id=None, price=None, discontinued=None,
|
||||
is_fixture=False):
|
||||
id=None,is_fixture=False):
|
||||
self.code = code
|
||||
self.name = name
|
||||
self.units = units
|
||||
self.fraction = fraction
|
||||
self.fraction_units = fraction_units
|
||||
self.yeild = yeild
|
||||
self.product_yield = product_yield
|
||||
self.show_for_purchase = show_for_purchase
|
||||
self.product_group_id = product_group_id
|
||||
self.ledger_id = ledger_id
|
||||
self.price = price
|
||||
self.discontinued = discontinued
|
||||
self.id = id
|
||||
self.is_fixture = is_fixture
|
||||
|
||||
@property
|
||||
@ -108,8 +109,9 @@ class ProductGroup(Base):
|
||||
|
||||
products = relationship('Product', backref='product_group')
|
||||
|
||||
def __init__(self, name=None, is_fixture=False):
|
||||
def __init__(self, name=None, id=None, is_fixture=False):
|
||||
self.name = name
|
||||
self.id = id
|
||||
self.is_fixture = is_fixture
|
||||
|
||||
@classmethod
|
||||
@ -135,8 +137,9 @@ class CostCenter(Base):
|
||||
def __name__(self):
|
||||
return self.name
|
||||
|
||||
def __init__(self, name=None, is_fixture=False):
|
||||
def __init__(self, name=None, id=None, is_fixture=False):
|
||||
self.name = name
|
||||
self.id = id
|
||||
self.is_fixture = is_fixture
|
||||
|
||||
@classmethod
|
||||
@ -190,13 +193,14 @@ class LedgerBase(Base):
|
||||
return LedgerType.by_id(self.type)
|
||||
|
||||
def __init__(self, code=None, name=None, type=None, is_active=None, is_reconcilable=False, costcenter_id=None,
|
||||
is_fixture=False):
|
||||
id=None, is_fixture=False):
|
||||
self.code = code
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.is_active = is_active
|
||||
self.is_reconcilable = is_reconcilable
|
||||
self.costcenter_id = costcenter_id
|
||||
self.id = id
|
||||
self.is_fixture = is_fixture
|
||||
|
||||
@classmethod
|
||||
|
@ -54,7 +54,7 @@ class Voucher(Base):
|
||||
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)
|
||||
is_reconciled = Column('IsReconciled', Boolean, nullable=False)
|
||||
narration = Column('Narration', Unicode(1000), nullable=False)
|
||||
posted = Column('Posted', Boolean, nullable=False)
|
||||
creation_date = Column('CreationDate', DateTime(timezone=True), nullable=False)
|
||||
|
@ -37,17 +37,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="txtFractionUnits" class="col-md-2 control-label">FractionUnits</label>
|
||||
<label for="txtFractionUnits" class="col-md-2 control-label">Fraction Units</label>
|
||||
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="txtFractionUnits" class="form-control" ng-model="product.FractionUnits"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="txtYeild" class="col-md-2 control-label">Yeild</label>
|
||||
<label for="txtYield" class="col-md-2 control-label">Yield</label>
|
||||
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="txtYeild" class="form-control" ng-model="product.Yeild"/>
|
||||
<input type="text" id="txtYield" class="form-control" ng-model="product.ProductYield"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
from decimal import Decimal
|
||||
from datetime import date, datetime, timedelta, time
|
||||
import uuid
|
||||
import re
|
||||
@ -23,7 +24,7 @@ def forbidden(request):
|
||||
response.status_int = 401
|
||||
return response
|
||||
else:
|
||||
return HTTPFound(location=request.route_url('login'))
|
||||
return HTTPFound(location=request.route_url('login', _query={'came_from': request.path}))
|
||||
|
||||
|
||||
@view_config(route_name='favicon')
|
||||
@ -58,3 +59,20 @@ def get_lock_info():
|
||||
def to_uuid(value):
|
||||
p = re.compile('^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$')
|
||||
return uuid.UUID(value) if p.match(value) else None
|
||||
|
||||
def to_decimal(value, default=0):
|
||||
import re
|
||||
_parser = re.compile(r""" # A numeric string consists of:
|
||||
(?P<sign>[-+])? # an optional sign, followed by either...
|
||||
(
|
||||
(?=\d|\.\d) # ...a number (with at least one digit)
|
||||
(?P<int>\d*) # having a (possibly empty) integer part
|
||||
(\.(?P<frac>\d*))? # followed by an optional fractional part
|
||||
|
|
||||
(?P<signal>s)? # ...an (optionally signaling)
|
||||
NaN # NaN
|
||||
(?P<diag>\d*) # with (possibly empty) diagnostic info.
|
||||
)
|
||||
\Z
|
||||
""", re.VERBOSE | re.IGNORECASE).match
|
||||
return Decimal(value) if _parser(value.strip()) is not None else default
|
||||
|
@ -29,16 +29,45 @@ def html(request):
|
||||
@view_config(request_method='POST', route_name='api_employee', renderer='json', permission='Employees')
|
||||
@TryCatchFunction
|
||||
def save(request):
|
||||
is_active = request.json_body['IsActive']
|
||||
joining_date = datetime.datetime.strptime(request.json_body['JoiningDate'], '%d-%b-%Y')
|
||||
leaving_date = None if is_active else datetime.datetime.strptime(request.json_body['LeavingDate'],
|
||||
'%d-%b-%Y')
|
||||
name = request.json_body.get('Name', '').strip()
|
||||
if name == '':
|
||||
raise ValidationError('Name cannot be blank')
|
||||
|
||||
item = Employee(0, request.json_body['Name'], is_active,
|
||||
uuid.UUID(request.json_body['CostCenter']['CostCenterID']),
|
||||
request.json_body['Designation'], int(request.json_body['Salary']),
|
||||
int(request.json_body['ServicePoints']),
|
||||
joining_date, leaving_date).create()
|
||||
cost_center_id = uuid.UUID(request.json_body['CostCenter']['CostCenterID'])
|
||||
designation = request.json_body.get('Designation', '').strip()
|
||||
|
||||
try:
|
||||
salary = int(request.json_body['Salary'])
|
||||
if salary < 0:
|
||||
raise ValidationError("Salary must be an integer >= 0")
|
||||
except (ValueError, KeyError):
|
||||
raise ValidationError("Salary must be an integer >= 0")
|
||||
|
||||
try:
|
||||
service_points = int(request.json_body['ServicePoints'])
|
||||
if service_points < 0:
|
||||
raise ValidationError("Service Points must be an integer >= 0")
|
||||
except (ValueError, KeyError):
|
||||
raise ValidationError("Service Points must be an integer >= 0")
|
||||
|
||||
try:
|
||||
joining_date = datetime.datetime.strptime(request.json_body['JoiningDate'], '%d-%b-%Y')
|
||||
except (ValueError, KeyError, TypeError):
|
||||
raise ValidationError("Joining Date is not a valid date")
|
||||
|
||||
is_active = request.json_body['IsActive']
|
||||
try:
|
||||
if is_active:
|
||||
leaving_date = None
|
||||
else:
|
||||
leaving_date = datetime.datetime.strptime(request.json_body['LeavingDate'], '%d-%b-%Y')
|
||||
if leaving_date < joining_date:
|
||||
raise ValidationError("Leaving Date cannot be less than Joining Date")
|
||||
except (ValueError, KeyError, TypeError):
|
||||
raise ValidationError("Leaving Date is not a valid date")
|
||||
|
||||
item = Employee(0, name, is_active, cost_center_id, designation, salary, service_points, joining_date,
|
||||
leaving_date).create()
|
||||
transaction.commit()
|
||||
return employee_info(item.id)
|
||||
|
||||
@ -49,15 +78,44 @@ def update(request):
|
||||
item = Employee.by_id(uuid.UUID(request.matchdict['id']))
|
||||
if item.is_fixture:
|
||||
raise ValidationError("{0} is a fixture and cannot be edited or deleted.".format(item.name))
|
||||
item.name = request.json_body['Name']
|
||||
|
||||
item.name = request.json_body.get('Name', '').strip()
|
||||
if item.name == '':
|
||||
raise ValidationError('Name cannot be blank')
|
||||
|
||||
item.cost_center_id = uuid.UUID(request.json_body['CostCenter']['CostCenterID'])
|
||||
item.designation = request.json_body.get('Designation', '').strip()
|
||||
|
||||
try:
|
||||
item.salary = int(request.json_body['Salary'])
|
||||
if item.salary < 0:
|
||||
raise ValidationError("Salary must be an integer >= 0")
|
||||
except (ValueError, KeyError):
|
||||
raise ValidationError("Salary must be an integer >= 0")
|
||||
|
||||
try:
|
||||
item.service_points = int(request.json_body['ServicePoints'])
|
||||
if item.service_points < 0:
|
||||
raise ValidationError("Service Points must be an integer >= 0")
|
||||
except (ValueError, KeyError):
|
||||
raise ValidationError("Service Points must be an integer >= 0")
|
||||
|
||||
try:
|
||||
item.joining_date = datetime.datetime.strptime(request.json_body['JoiningDate'], '%d-%b-%Y')
|
||||
except (ValueError, KeyError, TypeError):
|
||||
raise ValidationError("Joining Date is not a valid date")
|
||||
|
||||
item.is_active = request.json_body['IsActive']
|
||||
item.costcenter_id = uuid.UUID(request.json_body['CostCenter']['CostCenterID'])
|
||||
item.designation = request.json_body['Designation']
|
||||
item.salary = int(request.json_body['Salary'])
|
||||
item.service_points = int(request.json_body['ServicePoints'])
|
||||
item.joining_date = datetime.datetime.strptime(request.json_body['JoiningDate'], '%d-%b-%Y')
|
||||
item.leaving_date = None if item.is_active else datetime.datetime.strptime(request.json_body['LeavingDate'],
|
||||
'%d-%b-%Y')
|
||||
try:
|
||||
if item.is_active:
|
||||
item.leaving_date = None
|
||||
else:
|
||||
item.leaving_date = datetime.datetime.strptime(request.json_body['LeavingDate'], '%d-%b-%Y')
|
||||
if item.leaving_date < item.joining_date:
|
||||
raise ValidationError("Leaving Date cannot be less than Joining Date")
|
||||
except (ValueError, KeyError, TypeError):
|
||||
raise ValidationError("Leaving Date is not a valid date")
|
||||
|
||||
transaction.commit()
|
||||
return employee_info(item.id)
|
||||
|
||||
@ -141,8 +199,8 @@ def employee_info(id):
|
||||
|
||||
def delete_with_data(employee):
|
||||
suspense_ledger = Ledger.by_id(Ledger.suspense())
|
||||
query = Voucher.query().options(joinedload_all(Voucher.journals, Journal.ledger, innerjoin=True))\
|
||||
.filter(Voucher.journals.any(Journal.ledger_id == employee.id))\
|
||||
query = Voucher.query().options(joinedload_all(Voucher.journals, Journal.ledger, innerjoin=True)) \
|
||||
.filter(Voucher.journals.any(Journal.ledger_id == employee.id)) \
|
||||
.all()
|
||||
|
||||
for voucher in query:
|
||||
|
@ -1,4 +1,4 @@
|
||||
from decimal import Decimal
|
||||
from decimal import Decimal, InvalidOperation
|
||||
import uuid
|
||||
from pyramid.response import Response
|
||||
from pyramid.security import authenticated_userid
|
||||
@ -27,21 +27,42 @@ def html(request):
|
||||
@TryCatchFunction
|
||||
def save(request):
|
||||
json = request.json_body
|
||||
|
||||
name = json.get('Name', '').strip()
|
||||
if name == '':
|
||||
raise ValidationError('Name cannot be blank')
|
||||
|
||||
units = json.get('Units', '').strip()
|
||||
fraction = Decimal(json.get('Fraction', 0))
|
||||
|
||||
try:
|
||||
fraction = Decimal(json.get('Fraction', 0))
|
||||
if fraction <= 0 or fraction > 1:
|
||||
raise ValidationError("Fraction must be a decimal > 0 and <= 1")
|
||||
except (ValueError, InvalidOperation):
|
||||
raise ValidationError("Fraction must be a decimal > 0 and <= 1")
|
||||
|
||||
fraction_units = json.get('FractionUnits', '').strip()
|
||||
yeild = Decimal(json.get('Yeild', 1))
|
||||
|
||||
try:
|
||||
product_yield = Decimal(json.get('ProductYield', 1))
|
||||
if product_yield < 0 or product_yield > 1:
|
||||
raise ValidationError("Yield must be a decimal >= 0 <= 1")
|
||||
except (ValueError, InvalidOperation):
|
||||
raise ValidationError("Yield must be a decimal >= 0 <= 1")
|
||||
|
||||
show_for_purchase = json.get('ShowForPurchase', True)
|
||||
product_group = json.get('ProductGroup', None)
|
||||
if product_group is None:
|
||||
raise ValidationError('Please choose a product group')
|
||||
product_group_id = uuid.UUID(product_group['ProductGroupID'])
|
||||
price = Decimal(json.get('Price', 0))
|
||||
try:
|
||||
price = Decimal(json.get('Price', 0))
|
||||
if price < 0:
|
||||
raise ValidationError("Price must be a decimal > 0")
|
||||
except (ValueError, InvalidOperation):
|
||||
raise ValidationError("Price must be a decimal > 0")
|
||||
discontinued = json.get('Discontinued', False)
|
||||
item = Product(0, name, units, fraction, fraction_units, yeild, show_for_purchase, product_group_id,
|
||||
item = Product(0, name, units, fraction, fraction_units, product_yield, show_for_purchase, product_group_id,
|
||||
Ledger.all_purchases(), price, discontinued).create()
|
||||
transaction.commit()
|
||||
return product_info(item.id)
|
||||
@ -55,13 +76,30 @@ def update(request):
|
||||
raise ValidationError("{0} is a fixture and cannot be edited or deleted.".format(item.full_name))
|
||||
item.name = request.json_body['Name'].strip()
|
||||
item.units = request.json_body['Units'].strip()
|
||||
item.fraction = Decimal(request.json_body['Fraction'])
|
||||
try:
|
||||
item.fraction = Decimal(request.json_body['Fraction'])
|
||||
if item.fraction <= 0 or item.fraction > 1:
|
||||
raise ValidationError("Fraction must be a decimal > 0 and <= 1")
|
||||
except (ValueError, InvalidOperation):
|
||||
raise ValidationError("Fraction must be a decimal > 0 and <= 1")
|
||||
item.fraction_units = request.json_body['FractionUnits']
|
||||
item.yeild = Decimal(request.json_body['Yeild'])
|
||||
|
||||
try:
|
||||
item.product_yield = Decimal(request.json_body['ProductYield'])
|
||||
if item.product_yield < 0 or item.product_yield > 1:
|
||||
raise ValidationError("Yield must be a decimal >= 0 <= 1")
|
||||
except (ValueError, InvalidOperation):
|
||||
raise ValidationError("Yield must be a decimal >= 0 <= 1")
|
||||
|
||||
item.show_for_purchase = request.json_body['ShowForPurchase']
|
||||
item.product_group_id = uuid.UUID(request.json_body['ProductGroup']['ProductGroupID'])
|
||||
item.ledger_id = Ledger.all_purchases()
|
||||
item.price = Decimal(request.json_body['Price'])
|
||||
try:
|
||||
item.price = Decimal(request.json_body['Price'])
|
||||
if item.price < 0:
|
||||
raise ValidationError("Price must be a decimal > 0")
|
||||
except (ValueError, InvalidOperation):
|
||||
raise ValidationError("Price must be a decimal > 0")
|
||||
item.discontinued = request.json_body['Discontinued']
|
||||
transaction.commit()
|
||||
return product_info(item.id)
|
||||
@ -131,9 +169,10 @@ def product_info(id):
|
||||
else:
|
||||
product = Product.by_id(id)
|
||||
product = {'ProductID': product.id, 'Code': product.code, 'Name': product.name, 'Units': product.units,
|
||||
'Fraction': product.fraction, 'FractionUnits': product.fraction_units, 'Yeild': product.yeild,
|
||||
'ShowForPurchase': product.show_for_purchase, 'Discontinued': product.discontinued,
|
||||
'IsFixture': product.is_fixture, 'ProductGroup': {'ProductGroupID': product.product_group_id},
|
||||
'Fraction': product.fraction, 'FractionUnits': product.fraction_units,
|
||||
'ProductYield': product.product_yield, 'ShowForPurchase': product.show_for_purchase,
|
||||
'Discontinued': product.discontinued, 'IsFixture': product.is_fixture,
|
||||
'ProductGroup': {'ProductGroupID': product.product_group_id},
|
||||
'Ledger': {'LedgerID': product.ledger_id}, 'Price': product.price}
|
||||
return product
|
||||
|
||||
|
@ -6,7 +6,7 @@ from brewman.models.voucher import Batch
|
||||
@view_config(request_method='GET', route_name='api_batch', renderer='json', permission='Authenticated')
|
||||
def batch_term(request):
|
||||
filter = request.GET.get('term', None)
|
||||
filter = filter if filter is not None and filter is not '' else None
|
||||
filter = filter if filter is not None and filter.strip() is not '' else None
|
||||
count = request.GET.get('count', None)
|
||||
count = None if count is None or count == '' else int(count)
|
||||
date = request.GET.get('date', None)
|
||||
|
Loading…
x
Reference in New Issue
Block a user