Feature: Credit Service Charge with adjustable service points

Refactor: Renamed column, table, and uses of Cost Center to Cost Centre
Refactor: Renamed costcenter to cost_centre
This commit is contained in:
tanshu committed 2015-02-12 17:42:46 +05:30
1 parent fdcedb262c
commit 6a815692bd
58 files changed
+822 -505

No files matched your search

+3 -2
View File
@@ -59,7 +59,7 @@ def main(global_config, **settings):
config.add_route('api_account_type_list', '/api/AccountTypes') config.add_route('api_account_type_list', '/api/AccountTypes')
add_route(config, 'cost_center', '/CostCenter') add_route(config, 'cost_centre', '/CostCentre')
add_route(config, 'account', '/Account') add_route(config, 'account', '/Account')
add_route(config, 'employee', '/Employee') add_route(config, 'employee', '/Employee')
add_route(config, 'user', '/User') add_route(config, 'user', '/User')
@@ -84,6 +84,8 @@ def main(global_config, **settings):
config.add_route('api_issues_grid', '/api/Issues/Services/{date}') config.add_route('api_issues_grid', '/api/Issues/Services/{date}')
config.add_route('salary_deduction_id', '/SalaryDeduction/{id}') config.add_route('salary_deduction_id', '/SalaryDeduction/{id}')
config.add_route('salary_deduction', '/SalaryDeduction') config.add_route('salary_deduction', '/SalaryDeduction')
config.add_route('service_charge_id', '/ServiceCharge/{id}')
config.add_route('service_charge', '/ServiceCharge')
config.add_route('db_image', '/api/DbImage/{id}/{type}') config.add_route('db_image', '/api/DbImage/{id}/{type}')
config.add_route('api_voucher_id', '/api/Voucher/{id}') config.add_route('api_voucher_id', '/api/Voucher/{id}')
@@ -106,7 +108,6 @@ def main(global_config, **settings):
config.add_route('attendance_report', '/AttendanceReport') config.add_route('attendance_report', '/AttendanceReport')
config.add_route('api_credit_salary', '/api/CreditSalary') config.add_route('api_credit_salary', '/api/CreditSalary')
config.add_route('api_credit_service_charge', '/api/CreditServiceCharge')
config.add_route('employee_functions', '/EmployeeFunctions') config.add_route('employee_functions', '/EmployeeFunctions')
config.add_route('api_fingerprint', '/api/Fingerprint') config.add_route('api_fingerprint', '/api/Fingerprint')
+8 -7
View File
@@ -27,7 +27,7 @@ def fixtures(engine):
import uuid import uuid
from brewman.models.messaging import Tag, Thread, Subscriber, thread_tag, Post 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.voucher import Attendance, Batch, Fingerprint, Inventory, Journal, Product, SalaryDeduction, Voucher, VoucherType
from brewman.models.master import Product, AttendanceType, CostCenter, Employee, Ledger, LedgerBase, LedgerType, ProductGroup, MenuItem, Recipe, RecipeItem from brewman.models.master import Product, AttendanceType, CostCentre, Employee, Ledger, LedgerBase, LedgerType, ProductGroup, MenuItem, Recipe, RecipeItem
from brewman.models.auth import Client, Group, Role, User, role_group, user_group, LoginHistory from brewman.models.auth import Client, Group, Role, User, role_group, user_group, LoginHistory
Base.metadata.create_all(engine) Base.metadata.create_all(engine)
@@ -46,7 +46,7 @@ def fixtures(engine):
roles = [Role('Attendance', uuid.UUID('09d05434-a09a-fa45-963b-769a2e3fc667')), roles = [Role('Attendance', uuid.UUID('09d05434-a09a-fa45-963b-769a2e3fc667')),
Role('Trial Balance', uuid.UUID('3b099fec-ddc5-4243-b30e-afb78d9ca14a')), Role('Trial Balance', uuid.UUID('3b099fec-ddc5-4243-b30e-afb78d9ca14a')),
Role('Cash Flow', uuid.UUID('c4d3ae29-420b-ea4c-ae90-00a356263fd9')), Role('Cash Flow', uuid.UUID('c4d3ae29-420b-ea4c-ae90-00a356263fd9')),
Role('Cost Centers', uuid.UUID('6fcc1a20-6aec-e840-b334-1632b34aeab8')), Role('Cost Centres', uuid.UUID('6fcc1a20-6aec-e840-b334-1632b34aeab8')),
Role('Users', uuid.UUID('c5b7d9d7-f178-0e45-8ea4-bf4e08ec901b')), Role('Users', uuid.UUID('c5b7d9d7-f178-0e45-8ea4-bf4e08ec901b')),
Role('Daybook', uuid.UUID('c3edb554-a057-8942-8030-37b8e926d583')), Role('Daybook', uuid.UUID('c3edb554-a057-8942-8030-37b8e926d583')),
Role('Edit Posted Vouchers', uuid.UUID('d6675817-ddf5-bf40-9de6-fa223eb4aaa6')), Role('Edit Posted Vouchers', uuid.UUID('d6675817-ddf5-bf40-9de6-fa223eb4aaa6')),
@@ -84,18 +84,19 @@ def fixtures(engine):
Role('Stock Movement', uuid.UUID('20b707ee-2b59-41ad-be87-76d5fe1efca8')), Role('Stock Movement', uuid.UUID('20b707ee-2b59-41ad-be87-76d5fe1efca8')),
Role('Purchases', uuid.UUID('cf7019c8-3fd3-45b0-9a42-601029ce5b71')), Role('Purchases', uuid.UUID('cf7019c8-3fd3-45b0-9a42-601029ce5b71')),
Role('Dashboard', uuid.UUID('53eecc09-bd06-4890-b6f5-6885dda762d4')), Role('Dashboard', uuid.UUID('53eecc09-bd06-4890-b6f5-6885dda762d4')),
Role('Service Charge', uuid.UUID('99b56390-96c2-4f3d-8b0f-5ae3c868594f')),
Role('Maintenance', uuid.UUID('770532e4-21de-4712-8a6b-4ff9fd63a503'))] Role('Maintenance', uuid.UUID('770532e4-21de-4712-8a6b-4ff9fd63a503'))]
for role in roles: for role in roles:
DBSession.add(role) DBSession.add(role)
groups[0].roles.append(role) groups[0].roles.append(role)
cost_centers = [CostCenter('Overall', uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), True), cost_centres = [CostCentre('Overall', uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), True),
CostCenter('Purchase', uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3'), True), CostCentre('Purchase', uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3'), True),
CostCenter('Kitchen', uuid.UUID('b2d398ce-e3cc-c542-9feb-5d7783e899df'), True)] CostCentre('Kitchen', uuid.UUID('b2d398ce-e3cc-c542-9feb-5d7783e899df'), True)]
for cost_center in cost_centers: for cost_centre in cost_centres:
DBSession.add(cost_center) DBSession.add(cost_centre)
ledgers = [Ledger(1, 'All Purchases', 2, True, False, uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3'), ledgers = [Ledger(1, 'All Purchases', 2, True, False, uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3'),
uuid.UUID('240dd899-c413-854c-a7eb-67a29d154490'), True), uuid.UUID('240dd899-c413-854c-a7eb-67a29d154490'), True),
+19 -15
View File
@@ -197,15 +197,15 @@ class ProductGroup(Base):
return uuid.UUID('e6bf81b9-1e9b-499f-81d5-ab5662e9d9b1') return uuid.UUID('e6bf81b9-1e9b-499f-81d5-ab5662e9d9b1')
class CostCenter(Base): class CostCentre(Base):
__tablename__ = 'cost_centers' __tablename__ = 'cost_centres'
id = Column('CostCenterID', GUID(), primary_key=True, default=uuid.uuid4) id = Column('CostCentreID', GUID(), primary_key=True, default=uuid.uuid4)
name = Column('Name', Unicode(255), unique=True) name = Column('Name', Unicode(255), unique=True)
is_fixture = Column('IsFixture', Boolean, nullable=False) is_fixture = Column('IsFixture', Boolean, nullable=False)
ledgers = relationship('LedgerBase', backref='costcenter') ledgers = relationship('LedgerBase', backref='cost_centre')
journals = relationship('Journal', backref='costcenter') journals = relationship('Journal', backref='cost_centre')
@property @property
def __name__(self): def __name__(self):
@@ -225,20 +225,20 @@ class CostCenter(Base):
return DBSession.query(cls).order_by(cls.name).all() return DBSession.query(cls).order_by(cls.name).all()
@classmethod @classmethod
def cost_center_purchase(cls): def cost_centre_purchase(cls):
return uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3') return uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3')
@classmethod @classmethod
def cost_center_kitchen(cls): def cost_centre_kitchen(cls):
return uuid.UUID('b2d398ce-e3cc-c542-9feb-5d7783e899df') return uuid.UUID('b2d398ce-e3cc-c542-9feb-5d7783e899df')
@classmethod @classmethod
def cost_center_overall(cls): def cost_centre_overall(cls):
return uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d') return uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d')
@classmethod @classmethod
def overall(cls): def overall(cls):
return {'CostCenterID': uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), 'Name': 'Overall'} return {'CostCentreID': uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), 'Name': 'Overall'}
class LedgerBase(Base): class LedgerBase(Base):
@@ -251,7 +251,7 @@ class LedgerBase(Base):
ledger_type = Column('ledger_type', Unicode(50), nullable=False) ledger_type = Column('ledger_type', Unicode(50), nullable=False)
is_active = Column('IsActive', Boolean) is_active = Column('IsActive', Boolean)
is_reconcilable = Column('IsReconcilable', Boolean) is_reconcilable = Column('IsReconcilable', Boolean)
costcenter_id = Column('CostCenterID', GUID(), ForeignKey('cost_centers.CostCenterID')) cost_centre_id = Column('CostCentreID', GUID(), ForeignKey('cost_centres.CostCentreID'))
is_fixture = Column('IsFixture', Boolean, nullable=False) is_fixture = Column('IsFixture', Boolean, nullable=False)
__mapper_args__ = {'polymorphic_on': ledger_type} __mapper_args__ = {'polymorphic_on': ledger_type}
@@ -266,14 +266,14 @@ class LedgerBase(Base):
def type_object(self): def type_object(self):
return LedgerType.by_id(self.type) return LedgerType.by_id(self.type)
def __init__(self, code=None, name=None, type=None, is_active=None, is_reconcilable=False, costcenter_id=None, def __init__(self, code=None, name=None, type=None, is_active=None, is_reconcilable=False, cost_centre_id=None,
id=None, is_fixture=False): id=None, is_fixture=False):
self.code = code self.code = code
self.name = name self.name = name
self.type = type self.type = type
self.is_active = is_active self.is_active = is_active
self.is_reconcilable = is_reconcilable self.is_reconcilable = is_reconcilable
self.costcenter_id = costcenter_id self.cost_centre_id = cost_centre_id
self.id = id self.id = id
self.is_fixture = is_fixture self.is_fixture = is_fixture
@@ -351,6 +351,10 @@ class LedgerBase(Base):
def service_charge(cls): def service_charge(cls):
return {'LedgerID': 'b7eff754-e8ba-e047-ab06-9132c15c7640', 'Name': 'Service Charges'} return {'LedgerID': 'b7eff754-e8ba-e047-ab06-9132c15c7640', 'Name': 'Service Charges'}
@classmethod
def service_charge_id(cls):
return uuid.UUID('b7eff754-e8ba-e047-ab06-9132c15c7640')
@classmethod @classmethod
def esi_pf_expense(cls): def esi_pf_expense(cls):
return uuid.UUID('d2a1a286-e900-764b-a1a5-9f4b00dbb940') return uuid.UUID('d2a1a286-e900-764b-a1a5-9f4b00dbb940')
@@ -378,7 +382,7 @@ class Employee(LedgerBase):
attendances = relationship('Attendance', backref='employee', cascade=None, cascade_backrefs=False) attendances = relationship('Attendance', backref='employee', cascade=None, cascade_backrefs=False)
fingerprints = relationship('Fingerprint', backref='employee', cascade=None, cascade_backrefs=False) fingerprints = relationship('Fingerprint', backref='employee', cascade=None, cascade_backrefs=False)
def __init__(self, code=None, name=None, is_active=None, costcenter_id=None, designation=None, salary=None, def __init__(self, code=None, name=None, is_active=None, cost_centre_id=None, designation=None, salary=None,
service_points=None, joining_date=None, leaving_date=None): service_points=None, joining_date=None, leaving_date=None):
self.designation = designation self.designation = designation
self.salary = salary self.salary = salary
@@ -386,7 +390,7 @@ class Employee(LedgerBase):
self.joining_date = joining_date self.joining_date = joining_date
self.leaving_date = leaving_date self.leaving_date = leaving_date
super().__init__(code=code, name=name, type=10, is_active=is_active, is_reconcilable=False, super().__init__(code=code, name=name, type=10, is_active=is_active, is_reconcilable=False,
costcenter_id=costcenter_id) cost_centre_id=cost_centre_id)
def create(self): def create(self):
code = DBSession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == self.type).one()[0] code = DBSession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == self.type).one()[0]
@@ -403,7 +407,7 @@ class Employee(LedgerBase):
@classmethod @classmethod
def list(cls): def list(cls):
return DBSession.query(Employee).order_by(desc(Employee.is_active)).order_by(Ledger.costcenter_id).order_by( return DBSession.query(Employee).order_by(desc(Employee.is_active)).order_by(Ledger.cost_centre_id).order_by(
Employee.designation).order_by(Employee.name).all() Employee.designation).order_by(Employee.name).all()
@classmethod @classmethod
+5 -5
View File
@@ -1,4 +1,4 @@
from brewman.models.master import CostCenter from brewman.models.master import CostCentre
from brewman.models.validation_exception import ValidationError from brewman.models.validation_exception import ValidationError
__author__ = 'tanshu' __author__ = 'tanshu'
@@ -36,7 +36,7 @@ def check_batch_insert(voucher):
# Issue # Issue
purchase = None purchase = None
for item in voucher.journals: for item in voucher.journals:
if item.cost_center_id == CostCenter.cost_center_purchase(): if item.cost_centre_id == CostCentre.cost_centre_purchase():
purchase = item purchase = item
if purchase == None: if purchase == None:
return return
@@ -54,7 +54,7 @@ def check_batch_insert(voucher):
def issue_new(voucher): def issue_new(voucher):
consuming = filter(lambda x: x.cost_center_id == CostCenter.cost_center_purchase(), voucher.journals) consuming = filter(lambda x: x.cost_centre_id == CostCentre.cost_centre_purchase(), voucher.journals)
if not len(consuming): if not len(consuming):
consuming = False consuming = False
elif consuming[0].debit == 1: elif consuming[0].debit == 1:
@@ -74,7 +74,7 @@ def issue_new(voucher):
def issue_update(voucher): def issue_update(voucher):
consuming = filter(lambda x: x.cost_center_id == CostCenter.cost_center_purchase(), voucher.journals) consuming = filter(lambda x: x.cost_centre_id == CostCentre.cost_centre_purchase(), voucher.journals)
if not len(consuming): if not len(consuming):
consuming = False consuming = False
elif consuming[0].debit == 1: elif consuming[0].debit == 1:
@@ -150,7 +150,7 @@ def journals_valid(voucher):
def is_distinct_journal(journals): def is_distinct_journal(journals):
found = set() found = set()
for item in journals: for item in journals:
itemHash = hash(item.ledger_id) ^ hash(item.cost_center_id) itemHash = hash(item.ledger_id) ^ hash(item.cost_centre_id)
if itemHash in found: if itemHash in found:
raise ValidationError("Duplicate journals") raise ValidationError("Duplicate journals")
else: else:
+28 -6
View File
@@ -2,9 +2,8 @@ from datetime import datetime
import uuid import uuid
from sqlalchemy.dialects.postgresql import BYTEA from sqlalchemy.dialects.postgresql import BYTEA
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy import Column, Integer, Boolean, Unicode, DateTime, Numeric, ForeignKey, UniqueConstraint, Index from sqlalchemy import Column, Integer, Boolean, Unicode, DateTime, Numeric, ForeignKey, UniqueConstraint
from sqlalchemy.orm import relationship, synonym, backref from sqlalchemy.orm import relationship, synonym, backref
from brewman.models.guidtype import GUID from brewman.models.guidtype import GUID
@@ -32,6 +31,7 @@ class VoucherType:
list.append(VoucherType(10, 'Opening Balance')) list.append(VoucherType(10, 'Opening Balance'))
list.append(VoucherType(11, 'Closing Balance')) list.append(VoucherType(11, 'Closing Balance'))
list.append(VoucherType(12, 'Salary Deduction')) list.append(VoucherType(12, 'Salary Deduction'))
list.append(VoucherType(13, 'Service Charge'))
return list return list
@classmethod @classmethod
@@ -72,7 +72,8 @@ class Voucher(Base):
inventories = relationship('Inventory', 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", salary_deductions = relationship('SalaryDeduction', backref='voucher', cascade="delete, delete-orphan",
cascade_backrefs=False) cascade_backrefs=False)
service_charges = relationship('ServiceCharge', backref='voucher', cascade="delete, delete-orphan",
cascade_backrefs=False)
def _get_type(self): def _get_type(self):
@@ -128,7 +129,7 @@ class Journal(Base):
amount = Column('Amount', Numeric) amount = Column('Amount', Numeric)
voucher_id = Column('VoucherID', GUID(), ForeignKey('vouchers.VoucherID'), nullable=False, index=True) voucher_id = Column('VoucherID', GUID(), ForeignKey('vouchers.VoucherID'), nullable=False, index=True)
ledger_id = Column('LedgerID', GUID(), ForeignKey('ledgers.LedgerID'), nullable=False) ledger_id = Column('LedgerID', GUID(), ForeignKey('ledgers.LedgerID'), nullable=False)
cost_center_id = Column('CostCenterID', GUID(), ForeignKey('cost_centers.CostCenterID'), nullable=False) cost_centre_id = Column('CostCentreID', GUID(), ForeignKey('cost_centres.CostCentreID'), nullable=False)
@hybrid_property @hybrid_property
def signed_amount(self): def signed_amount(self):
@@ -138,13 +139,13 @@ class Journal(Base):
def __name__(self): def __name__(self):
return self.name return self.name
def __init__(self, id=None, debit=None, amount=None, voucher_id=None, ledger_id=None, cost_center_id=None): def __init__(self, id=None, debit=None, amount=None, voucher_id=None, ledger_id=None, cost_centre_id=None):
self.id = id self.id = id
self.debit = debit self.debit = debit
self.amount = amount self.amount = amount
self.voucher_id = voucher_id self.voucher_id = voucher_id
self.ledger_id = ledger_id self.ledger_id = ledger_id
self.cost_center_id = cost_center_id self.cost_centre_id = cost_centre_id
@classmethod @classmethod
def by_id(cls, id): def by_id(cls, id):
@@ -189,6 +190,27 @@ class SalaryDeduction(Base):
self.journal = journal self.journal = journal
class ServiceCharge(Base):
__tablename__ = 'service_charges'
id = Column('id', GUID(), primary_key=True, default=uuid.uuid4)
voucher_id = Column('voucher_id', GUID(), ForeignKey('vouchers.VoucherID'), nullable=False)
journal_id = Column('journal_id', GUID(), ForeignKey('journals.JournalID'), nullable=False)
days_worked = Column('days_worked', Integer, nullable=False)
points = Column('points', Numeric(precision=5, scale=2), nullable=False)
journal = relationship(Journal, backref=backref('service_charge', 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
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
class Inventory(Base): class Inventory(Base):
__tablename__ = 'inventories' __tablename__ = 'inventories'
__table_args__ = (UniqueConstraint('VoucherID', 'BatchID'), ) __table_args__ = (UniqueConstraint('VoucherID', 'BatchID'), )
+5 -3
View File
@@ -43,6 +43,7 @@
<script src="/js/angular-route.min.js"></script> <script src="/js/angular-route.min.js"></script>
<script src="/js/angular-sanitize.min.js"></script> <script src="/js/angular-sanitize.min.js"></script>
<script src="/js/loading-bar.min.js"></script> <script src="/js/loading-bar.min.js"></script>
<script src="/js/ui-bootstrap-custom-0.12.0.min.js"></script>
<script src="/script/overlord.js"></script> <script src="/script/overlord.js"></script>
<script src="/script/angular_directive.js"></script> <script src="/script/angular_directive.js"></script>
@@ -53,7 +54,6 @@
<script src="/script/login.js"></script> <script src="/script/login.js"></script>
<script src="/script/settings.js"></script> <script src="/script/settings.js"></script>
<script src="/script/message.js"></script> <script src="/script/message.js"></script>
<script src="/js/ui-bootstrap-custom-0.12.0.min.js"></script>
<script src="/script/journal.js"></script> <script src="/script/journal.js"></script>
<script src="/script/payment.js"></script> <script src="/script/payment.js"></script>
@@ -62,6 +62,7 @@
<script src="/script/purchase-return.js"></script> <script src="/script/purchase-return.js"></script>
<script src="/script/issue.js"></script> <script src="/script/issue.js"></script>
<script src="/script/salary-deduction.js"></script> <script src="/script/salary-deduction.js"></script>
<script src="/script/service-charge.js"></script>
<script src="/script/employee-attendance.js"></script> <script src="/script/employee-attendance.js"></script>
<script src="/script/employee-functions.js"></script> <script src="/script/employee-functions.js"></script>
@@ -88,7 +89,7 @@
<script src="/script/user.js"></script> <script src="/script/user.js"></script>
<script src="/script/group.js"></script> <script src="/script/group.js"></script>
<script src="/script/client.js"></script> <script src="/script/client.js"></script>
<script src="/script/cost-center.js"></script> <script src="/script/cost-centre.js"></script>
<script src="/script/product.js"></script> <script src="/script/product.js"></script>
<script src="/script/product-group.js"></script> <script src="/script/product-group.js"></script>
@@ -171,6 +172,7 @@
<li><a href="/EmployeeAttendance">Employee Attendance</a></li> <li><a href="/EmployeeAttendance">Employee Attendance</a></li>
<li><a href="/EmployeeFunctions">Employee Functions</a></li> <li><a href="/EmployeeFunctions">Employee Functions</a></li>
<li><a href="/SalaryDeduction">Credit Esi / Pf</a></li> <li><a href="/SalaryDeduction">Credit Esi / Pf</a></li>
<li><a href="/ServiceCharge">Service Charges</a></li>
<li><a href="/AccountsTesting/Employees/SalarySheet.aspx">Salary Sheet</a></li> <li><a href="/AccountsTesting/Employees/SalarySheet.aspx">Salary Sheet</a></li>
<li><a href="/AccountsTesting/Employees/PaymentSheet.aspx">Employee Payment Sheet</a></li> <li><a href="/AccountsTesting/Employees/PaymentSheet.aspx">Employee Payment Sheet</a></li>
<li><a href="/features/elements.html">Display Salary Sheet</a></li> <li><a href="/features/elements.html">Display Salary Sheet</a></li>
@@ -182,7 +184,7 @@
class="caret"></b></a> class="caret"></b></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="/Accounts">Accounts</a></li> <li><a href="/Accounts">Accounts</a></li>
<li><a href="/CostCenters">Cost Centers</a></li> <li><a href="/CostCentres">Cost Centres</a></li>
<li><a href="/Products">Products</a></li> <li><a href="/Products">Products</a></li>
<li><a href="/Recipes">Recipes</a></li> <li><a href="/Recipes">Recipes</a></li>
<li><a href="/ProductGroups">Product Groups</a></li> <li><a href="/ProductGroups">Product Groups</a></li>
+3 -3
View File
@@ -37,11 +37,11 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="ddlCostCenter" class="col-md-2 control-label">Cost Center</label> <label for="ddlCostCentre" class="col-md-2 control-label">Cost Centre</label>
<div class="col-md-10"> <div class="col-md-10">
<select id="ddlCostCenter" class="form-control" ng-model="account.CostCenter.CostCenterID" <select id="ddlCostCentre" class="form-control" ng-model="account.CostCentre.CostCentreID"
ng-options="l.CostCenterID as l.Name for l in costCenters"> </select> ng-options="l.CostCentreID as l.Name for l in costCentres"> </select>
</div> </div>
</div> </div>
+2 -2
View File
@@ -18,7 +18,7 @@
<th>Type</th> <th>Type</th>
<th>Is Active?</th> <th>Is Active?</th>
<th>Is Reconcilable?</th> <th>Is Reconcilable?</th>
<th>Cost Center</th> <th>Cost Centre</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -28,7 +28,7 @@
<td>{{item.Type}}</td> <td>{{item.Type}}</td>
<td>{{item.IsActive}}</td> <td>{{item.IsActive}}</td>
<td>{{item.IsReconcilable}}</td> <td>{{item.IsReconcilable}}</td>
<td>{{item.CostCenter}}</td> <td>{{item.CostCentre}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -1,11 +1,11 @@
<form class="form-horizontal" role=form> <form class="form-horizontal" role=form>
<h2>Cost Center Detail</h2> <h2>Cost Centre Detail</h2>
<div class="form-group"> <div class="form-group">
<label for="txtName" class="col-md-2 control-label">Name</label> <label for="txtName" class="col-md-2 control-label">Name</label>
<div class="col-md-10"> <div class="col-md-10">
<input type="text" id="txtName" class="form-control" ng-model="costCenter.Name" focus-on="foName"/> <input type="text" id="txtName" class="form-control" ng-model="costCentre.Name" focus-on="foName"/>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@@ -1,4 +1,4 @@
<h2>Cost Centers <a href="/CostCenter" class="btn btn-success pull-right">Add <i class="glyphicon glyphicon-plus"></i></a></h2> <h2>Cost Centres <a href="/CostCentre" class="btn btn-success pull-right">Add <i class="glyphicon glyphicon-plus"></i></a></h2>
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<thead> <thead>
<tr> <tr>
+4 -4
View File
@@ -16,7 +16,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="txtDesignation" class="col-md-2 control-label">Name</label> <label for="txtDesignation" class="col-md-2 control-label">Designation</label>
<div class="col-md-10"> <div class="col-md-10">
<input type="text" id="txtDesignation" class="form-control" ng-model="employee.Designation"/> <input type="text" id="txtDesignation" class="form-control" ng-model="employee.Designation"/>
@@ -46,11 +46,11 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="ddlCostCenter" class="col-md-2 control-label">Cost Center</label> <label for="ddlCostCentre" class="col-md-2 control-label">Cost Centre</label>
<div class="col-md-10"> <div class="col-md-10">
<select id="ddlCostCenter" class="form-control" ng-model="employee.CostCenter.CostCenterID" <select id="ddlCostCentre" class="form-control" ng-model="employee.CostCentre.CostCentreID"
ng-options="l.CostCenterID as l.Name for l in costCenters"> </select> ng-options="l.CostCentreID as l.Name for l in costCentres"> </select>
</div> </div>
</div> </div>
@@ -19,37 +19,6 @@
</button> </button>
</div> </div>
</div> </div>
<h2>Credit Service Charge</h2>
<div class="form-group">
<label for="txtScMonth" class="col-md-2 control-label">Month</label>
<div class="col-md-3">
<div class="input-group">
<input id="txtScMonth" type="text" class="form-control" datepicker-popup="dd-MMM-yyyy"
datepicker-mode="month" is-open="scmOpen" ng-focus="scmOpen = true" ng-model="sc.Month"/>
<span class="input-group-btn">
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
<label for="txtScCreditDate" class="col-md-2 control-label">Credit Date</label>
<div class="col-md-3">
<div class="input-group">
<input id="txtScCreditDate" type="text" class="form-control" datepicker-popup="dd-MMM-yyyy"
is-open="sccdOpen" ng-focus="sccdOpen = true" ng-model="sc.CreditDate"/>
<span class="input-group-btn">
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
<div class="col-md-2">
<button class="btn btn-block btn-success" tan-click="creditServiceCharge()">Credit <i
class="glyphicon glyphicon-screenshot"></i>
</button>
</div>
</div>
<h2>Attendance Record</h2> <h2>Attendance Record</h2>
<div class="form-group"> <div class="form-group">
+1 -1
View File
@@ -30,7 +30,7 @@
<td>{{item.Designation}}</td> <td>{{item.Designation}}</td>
<td>{{item.Salary}}</td> <td>{{item.Salary}}</td>
<td>{{item.ServicePoints}}</td> <td>{{item.ServicePoints}}</td>
<td>{{item.CostCenter}}</td> <td>{{item.CostCentre}}</td>
<td>{{item.JoiningDate}}</td> <td>{{item.JoiningDate}}</td>
<td>{{item.LeavingDate}}</td> <td>{{item.LeavingDate}}</td>
</tr> </tr>
@@ -0,0 +1,76 @@
<form class="form-horizontal" role=form id="form">
<h2>Employee Service Charge</h2>
<div class="form-group">
<label for="txtDate" class="col-md-2 control-label">Date</label>
<div class="col-md-10">
<div class="input-group">
<input class="form-control" id="txtDate" type="text" datepicker-popup="dd-MMM-yyyy"
is-open="dOpen" ng-focus="dOpen = true" ng-model="voucher.Date"/>
<span class="input-group-btn">
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
</div>
<div class="form-group">
<label for="txtInfo" class="col-md-2 control-label"></label>
<div class="col-md-10">
Total Service Charge: <strong>{{voucher.ServiceCharge | number:2}}</strong>
Total Points: <strong>{{TotalPoints() | number:2}}</strong>
Point Value: <strong>{{PointValue() | number:2}}</strong>
</div>
</div>
<table class="table table-condensed table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Designation</th>
<th>Department</th>
<th>Days Worked</th>
<th>Service Points</th>
<th class="text-right">Amount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="serviceCharge in voucher.ServiceCharges">
<td>{{serviceCharge.Name}}</td>
<td>{{serviceCharge.Designation}}</td>
<td>{{serviceCharge.Department}}</td>
<td>{{serviceCharge.DaysWorked}}</td>
<td>
<div class="input-group">
<span class="input-group-btn" style="width:auto">
<button class="btn btn-danger" ng-click="less(serviceCharge)"><i class="glyphicon glyphicon-minus"></i></button>
</span>
<input type="number" class="form-control" ng-model="serviceCharge.Points" step=".25">
<span class="input-group-btn" style="width:auto">
<button class="btn btn-success" ng-click="more(serviceCharge)"><i class="glyphicon glyphicon-plus"></i></button>
</span>
</div>
</td>
<td class="text-right">{{employeeAmount(serviceCharge) | number:0}}</td>
</tr>
</tbody>
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-primary" tan-click="save()" ng-disabled="preventAlteration(voucher)">
{{voucher.VoucherID | save_button}}
</button>
<button class="btn btn-inverse" tan-click="post()" ng-hide="!voucher.VoucherID"
ng-disabled="voucher.Posted || !perms['Post Vouchers']">{{voucher.Posted | posted}}
</button>
<button class="btn btn-danger" ng-hide="!voucher.VoucherID" ng-disabled="preventAlteration(voucher)"
ng-click="confirm()">Delete
</button>
</div>
</div>
<div class="col-md-offset-2 col-md-10">
<small>Created on {{voucher.CreationDate | localTime}} and Last Edited on {{voucher.LastEditDate | localTime}}
by {{voucher.User.Name}}. Posted by {{voucher.Poster}}
</small>
</div>
</form>
+4 -4
View File
@@ -29,13 +29,13 @@
</div> </div>
</div> </div>
<div class="col-md-3" ng-repeat="journal in voucher.Journals | journalDebit:-1"> <div class="col-md-3" ng-repeat="journal in voucher.Journals | journalDebit:-1">
<select id="ddlSourceCostCenter" class="form-control" ng-model="journal.CostCenter.CostCenterID" <select id="ddlSourceCostCentre" class="form-control" ng-model="journal.CostCentre.CostCentreID"
ng-options="l.CostCenterID as l.Name for l in costCenters"> </select> ng-options="l.CostCentreID as l.Name for l in costCentres"> </select>
</div> </div>
<div class="col-md-5" ng-repeat="journal in voucher.Journals | journalDebit:1"> <div class="col-md-5" ng-repeat="journal in voucher.Journals | journalDebit:1">
<div class="input-group"> <div class="input-group">
<select id="ddlDestinationCostCenter" class="form-control" ng-model="journal.CostCenter.CostCenterID" <select id="ddlDestinationCostCentre" class="form-control" ng-model="journal.CostCentre.CostCentreID"
ng-options="l.CostCenterID as l.Name for l in costCenters"> </select> ng-options="l.CostCentreID as l.Name for l in costCentres"> </select>
<span class="input-group-addon">₹</span> <span class="input-group-addon">₹</span>
<input type="text" class="form-control" placeholder="Amount" value="{{journal.Amount | number:2}}"/> <input type="text" class="form-control" placeholder="Amount" value="{{journal.Amount | number:2}}"/>
</div> </div>
@@ -29,7 +29,7 @@
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<thead> <thead>
<tr> <tr>
<th>Cost Center</th> <th>Cost Centre</th>
<th>Issue</th> <th>Issue</th>
<th>Sale</th> <th>Sale</th>
<th>Rmc</th> <th>Rmc</th>
+1 -1
View File
@@ -52,7 +52,7 @@
<tr ng-repeat="deduction in voucher.SalaryDeductions"> <tr ng-repeat="deduction in voucher.SalaryDeductions">
<td>{{deduction.Journal.Ledger.Name}}</td> <td>{{deduction.Journal.Ledger.Name}}</td>
<td>{{deduction.Journal.Ledger.Designation}}</td> <td>{{deduction.Journal.Ledger.Designation}}</td>
<td>{{deduction.Journal.Ledger.CostCenter.Name}}</td> <td>{{deduction.Journal.Ledger.CostCentre.Name}}</td>
<td>{{deduction.GrossSalary}}</td> <td>{{deduction.GrossSalary}}</td>
<td>{{deduction.DaysWorked}}</td> <td>{{deduction.DaysWorked}}</td>
<td>{{deduction.EsiEmployee}}</td> <td>{{deduction.EsiEmployee}}</td>
+6 -6
View File
@@ -18,7 +18,7 @@ var AccountListController = ['$scope', '$location', '$routeParams', 'Tokenizer',
't': {'Col': 'Type', 'Comparator': 'text'}, 't': {'Col': 'Type', 'Comparator': 'text'},
'a': {'Col': 'IsActive', 'Comparator': 'boolean'}, 'a': {'Col': 'IsActive', 'Comparator': 'boolean'},
'r': {'Col': 'IsReconcilable', 'Comparator': 'boolean'}, 'r': {'Col': 'IsReconcilable', 'Comparator': 'boolean'},
'c': {'Col': 'CostCenter', 'Comparator': 'text'} 'c': {'Col': 'CostCentre', 'Comparator': 'text'}
}, },
def: 'n', def: 'n',
sorter: { sorter: {
@@ -26,7 +26,7 @@ var AccountListController = ['$scope', '$location', '$routeParams', 'Tokenizer',
't': 'Type', 't': 'Type',
'a': 'IsActive', 'a': 'IsActive',
'r': 'IsReconcilable', 'r': 'IsReconcilable',
'c': 'CostCenter' 'c': 'CostCentre'
} }
}; };
$scope.filterAccounts = _.debounce(function (q) { $scope.filterAccounts = _.debounce(function (q) {
@@ -76,11 +76,11 @@ AccountListController.resolve = {
}] }]
}; };
var AccountController = ['$scope', '$location', '$modal', 'account', 'accountTypes', 'costCenters', function ($scope, $location, $modal, account, accountTypes, costCenters) { var AccountController = ['$scope', '$location', '$modal', 'account', 'accountTypes', 'costCentres', function ($scope, $location, $modal, account, accountTypes, costCentres) {
$scope.account = account; $scope.account = account;
$scope.accountTypes = accountTypes; $scope.accountTypes = accountTypes;
$scope.costCenters = costCenters; $scope.costCentres = costCentres;
$scope.save = function () { $scope.save = function () {
$scope.account.$save(function () { $scope.account.$save(function () {
@@ -131,7 +131,7 @@ AccountController.resolve = {
accountTypes: ['AccountType', function (AccountType) { accountTypes: ['AccountType', function (AccountType) {
return AccountType.query({}).$promise; return AccountType.query({}).$promise;
}], }],
costCenters: ['CostCenter', function (CostCenter) { costCentres: ['CostCentre', function (CostCentre) {
return CostCenter.query({}).$promise; return CostCentre.query({}).$promise;
}] }]
}; };
+29 -6
View File
@@ -85,9 +85,9 @@ overlordService.factory('ProductLedger', ['$resource', function ($resource) {
return $resource('/api/ProductLedger/:id'); return $resource('/api/ProductLedger/:id');
}]); }]);
overlordService.factory('CostCenter', ['$resource', function ($resource) { overlordService.factory('CostCentre', ['$resource', function ($resource) {
return $resource('/api/CostCenter/:id', return $resource('/api/CostCentre/:id',
{id: '@CostCenterID'}, { {id: '@CostCentreID'}, {
query: {method: 'GET', params: {list: true}, isArray: true} query: {method: 'GET', params: {list: true}, isArray: true}
}); });
}]); }]);
@@ -139,9 +139,9 @@ overlordService.factory('ProductGroup', ['$resource', function ($resource) {
}); });
}]); }]);
overlordService.factory('CostCenter', ['$resource', function ($resource) { overlordService.factory('CostCentre', ['$resource', function ($resource) {
return $resource('/api/CostCenter/:id', return $resource('/api/CostCentre/:id',
{id: '@CostCenterID'}, { {id: '@CostCentreID'}, {
query: {method: 'GET', params: {list: true}, isArray: true} query: {method: 'GET', params: {list: true}, isArray: true}
}); });
}]); }]);
@@ -270,6 +270,29 @@ overlordService.factory('Tokenizer', ['$filter', function ($filter) {
return obj.toLowerCase().indexOf(text) > -1; return obj.toLowerCase().indexOf(text) > -1;
} }
}, },
'date': function (obj, text) {
var reGoodDate = /^((0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012]|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[- /.](19|20)?[0-9]{2})*$/i,
asDateObject = function (input) {
if (angular.isDate(input)) {
return input;
}
},
op = opLength(text),
ob = op ? asDateObject(obj) : '',
tex = op ? asDateObject(text.substr(op).trim()) : '';
if (op) {
return operators[text.substr(0, op)](ob, tex);
} else {
return obj.toString().indexOf(text) > -1;
}
if (text.indexOf('!') === 0) {
return obj.toLowerCase().indexOf(text.substr(1)) <= -1;
} else {
return obj.toLowerCase().indexOf(text) > -1;
}
},
'boolean': function (obj, text) { 'boolean': function (obj, text) {
return obj === isTrue(text); return obj === isTrue(text);
}, },
-41
View File
@@ -1,41 +0,0 @@
'use strict';
var CostCenterListController = ['$scope', 'costCenters', function ($scope, costCenters) {
$scope.info = costCenters;
}];
CostCenterListController.resolve = {
costCenters: ['CostCenter', function (CostCenter) {
return CostCenter.query({}).$promise;
}]
};
var CostCenterController = ['$scope', '$routeParams', '$location', 'costCenter', function ($scope, $routeParams, $location, costCenter) {
$scope.costCenter = costCenter;
$scope.save = function () {
$scope.costCenter.$save(function (u, putResponseHeaders) {
$scope.toasts.push({Type: 'Success', Message: ''});
$location.path('/CostCenters')
}, function (data, status) {
$scope.toasts.push({Type: 'Danger', Message: data.data});
});
};
$scope.delete = function () {
$scope.costCenter.$delete(function (u, putResponseHeaders) {
$scope.toasts.push({Type: 'Success', Message: ''});
$location.path('/CostCenters')
}, function (data, status) {
$scope.toasts.push({Type: 'Danger', Message: data.data});
});
};
$scope.foName = true;
}];
CostCenterController.resolve = {
costCenter: ['$route', 'CostCenter', function ($route, CostCenter) {
var id = $route.current.params.id;
return CostCenter.get({id: id}).$promise;
}]
};
+41
View File
@@ -0,0 +1,41 @@
'use strict';
var CostCentreListController = ['$scope', 'costCentres', function ($scope, costCentres) {
$scope.info = costCentres;
}];
CostCentreListController.resolve = {
costCentres: ['CostCentre', function (CostCentre) {
return CostCentre.query({}).$promise;
}]
};
var CostCentreController = ['$scope', '$routeParams', '$location', 'costCentre', function ($scope, $routeParams, $location, costCentre) {
$scope.costCentre = costCentre;
$scope.save = function () {
$scope.costCentre.$save(function (u, putResponseHeaders) {
$scope.toasts.push({Type: 'Success', Message: ''});
$location.path('/CostCentres')
}, function (data, status) {
$scope.toasts.push({Type: 'Danger', Message: data.data});
});
};
$scope.delete = function () {
$scope.costCentre.$delete(function (u, putResponseHeaders) {
$scope.toasts.push({Type: 'Success', Message: ''});
$location.path('/CostCentres')
}, function (data, status) {
$scope.toasts.push({Type: 'Danger', Message: data.data});
});
};
$scope.foName = true;
}];
CostCentreController.resolve = {
costCentre: ['$route', 'CostCentre', function ($route, CostCentre) {
var id = $route.current.params.id;
return CostCentre.get({id: id}).$promise;
}]
};
@@ -17,25 +17,6 @@ var EmployeeFunctionsController = ['$scope', '$http', 'asDateFilter', function (
}); });
}; };
$scope.creditServiceCharge = function () {
if (!angular.isDate($scope.sc.Month)) {
return;
}
var ServiceChargeMonth = asDate($scope.sc.Month);
if (!angular.isDate($scope.sc.CreditDate)) {
return;
}
var CreditDate = asDate($scope.sc.CreditDate);
return $http.
post('/api/CreditServiceCharge', {Month: ServiceChargeMonth, CreditDate: CreditDate}).
success(function (data) {
$scope.toasts.push({Type: 'Success', Message: data.message});
}).
error(function (errorMessage) {
$scope.toasts.push({Type: 'Danger', Message: errorMessage});
});
};
$scope.attendanceRecordUrl = function () { $scope.attendanceRecordUrl = function () {
if (!$scope.record.StartDate || !$scope.record.FinishDate) { if (!$scope.record.StartDate || !$scope.record.FinishDate) {
return; return;
+6 -6
View File
@@ -19,7 +19,7 @@ var EmployeeListController = ['$scope', '$location', '$routeParams', 'Tokenizer'
's': {'Col': 'Salary', 'Comparator': 'numeric'}, 's': {'Col': 'Salary', 'Comparator': 'numeric'},
'a': {'Col': 'IsActive', 'Comparator': 'boolean'}, 'a': {'Col': 'IsActive', 'Comparator': 'boolean'},
'des': {'Col': 'Designation', 'Comparator': 'text'}, 'des': {'Col': 'Designation', 'Comparator': 'text'},
'dep': {'Col': 'CostCenter', 'Comparator': 'text'} 'dep': {'Col': 'CostCentre', 'Comparator': 'text'}
}, },
def: 'n', def: 'n',
sorter: { sorter: {
@@ -28,7 +28,7 @@ var EmployeeListController = ['$scope', '$location', '$routeParams', 'Tokenizer'
's': 'Salary', 's': 'Salary',
'a': 'IsActive', 'a': 'IsActive',
'des': 'Designation', 'des': 'Designation',
'dep': 'CostCenter' 'dep': 'CostCentre'
} }
}; };
$scope.filterEmployees = _.debounce(function (q) { $scope.filterEmployees = _.debounce(function (q) {
@@ -79,10 +79,10 @@ EmployeeListController.resolve = {
}] }]
}; };
var EmployeeController = ['$scope', '$routeParams', '$location', 'asDateFilter', '$modal', 'employee', 'costCenters', function ($scope, $routeParams, $location, asDate, $modal, employee, costCenters) { var EmployeeController = ['$scope', '$routeParams', '$location', 'asDateFilter', '$modal', 'employee', 'costCentres', function ($scope, $routeParams, $location, asDate, $modal, employee, costCentres) {
$scope.employee = employee; $scope.employee = employee;
$scope.costCenters = costCenters; $scope.costCentres = costCentres;
$scope.save = function () { $scope.save = function () {
$scope.employee.JoiningDate = asDate($scope.employee.JoiningDate); $scope.employee.JoiningDate = asDate($scope.employee.JoiningDate);
@@ -132,7 +132,7 @@ EmployeeController.resolve = {
var id = $route.current.params.id; var id = $route.current.params.id;
return Employee.get({id: id}).$promise; return Employee.get({id: id}).$promise;
}], }],
costCenters: ['CostCenter', function (CostCenter) { costCentres: ['CostCentre', function (CostCentre) {
return CostCenter.query({}).$promise; return CostCentre.query({}).$promise;
}] }]
}; };
+5 -5
View File
@@ -1,8 +1,8 @@
'use strict'; 'use strict';
var IssueController = ['$scope', '$routeParams', '$location', 'asDateFilter', 'voucher', 'costCenters', 'smallGrid', 'IssueGrid', 'Voucher', '$modal', 'Batch', function ($scope, $routeParams, $location, asDate, voucher, costCenters, smallGrid, IssueGrid, Voucher, $modal, Batch) { var IssueController = ['$scope', '$routeParams', '$location', 'asDateFilter', 'voucher', 'costCentres', 'smallGrid', 'IssueGrid', 'Voucher', '$modal', 'Batch', function ($scope, $routeParams, $location, asDate, voucher, costCentres, smallGrid, IssueGrid, Voucher, $modal, Batch) {
$scope.voucher = voucher; $scope.voucher = voucher;
$scope.costCenters = costCenters; $scope.costCentres = costCentres;
$scope.smallGrid = smallGrid; $scope.smallGrid = smallGrid;
if (angular.isUndefined($routeParams.Source) && angular.isUndefined($routeParams.Destination) && angular.isUndefined($routeParams.id)) { if (angular.isUndefined($routeParams.Source) && angular.isUndefined($routeParams.Destination) && angular.isUndefined($routeParams.id)) {
@@ -81,7 +81,7 @@ var IssueController = ['$scope', '$routeParams', '$location', 'asDateFilter', 'v
function getDebitCredit(journals, type) { function getDebitCredit(journals, type) {
for (var i = 0, l = journals.length; i < l; i++) { for (var i = 0, l = journals.length; i < l; i++) {
if (journals[i].Debit === type) { if (journals[i].Debit === type) {
return journals[i].CostCenter.CostCenterID; return journals[i].CostCentre.CostCentreID;
} }
} }
} }
@@ -279,8 +279,8 @@ IssueController.resolve = {
return []; return [];
} }
}], }],
costCenters: ['CostCenter', function (CostCenter) { costCentres: ['CostCentre', function (CostCentre) {
return CostCenter.query({}).$promise; return CostCentre.query({}).$promise;
}] }]
}; };
+6 -3
View File
@@ -28,6 +28,9 @@ var overlord = angular.module('overlord', ['overlord.directive', 'overlord.filte
when('/SalaryDeduction', {templateUrl: '/partial/salary-deduction.html', controller: SalaryDeductionController, resolve: SalaryDeductionController.resolve}). when('/SalaryDeduction', {templateUrl: '/partial/salary-deduction.html', controller: SalaryDeductionController, resolve: SalaryDeductionController.resolve}).
when('/SalaryDeduction/:id', {templateUrl: '/partial/salary-deduction.html', controller: SalaryDeductionController, resolve: SalaryDeductionController.resolve}). when('/SalaryDeduction/:id', {templateUrl: '/partial/salary-deduction.html', controller: SalaryDeductionController, resolve: SalaryDeductionController.resolve}).
when('/ServiceCharge', {templateUrl: '/partial/employee-service-charge.html', controller: ServiceChargeController, resolve: ServiceChargeController.resolve}).
when('/ServiceCharge/:id', {templateUrl: '/partial/employee-service-charge.html', controller: ServiceChargeController, resolve: ServiceChargeController.resolve}).
when('/Ledger', {templateUrl: '/partial/ledger.html', controller: LedgerController, resolve: LedgerController.resolve}). when('/Ledger', {templateUrl: '/partial/ledger.html', controller: LedgerController, resolve: LedgerController.resolve}).
when('/Ledger/:id', {templateUrl: '/partial/ledger.html', controller: LedgerController, resolve: LedgerController.resolve}). when('/Ledger/:id', {templateUrl: '/partial/ledger.html', controller: LedgerController, resolve: LedgerController.resolve}).
@@ -75,9 +78,9 @@ var overlord = angular.module('overlord', ['overlord.directive', 'overlord.filte
when('/Employee', {templateUrl: '/partial/employee-detail.html', controller: EmployeeController, resolve: EmployeeController.resolve}). when('/Employee', {templateUrl: '/partial/employee-detail.html', controller: EmployeeController, resolve: EmployeeController.resolve}).
when('/Employee/:id', {templateUrl: '/partial/employee-detail.html', controller: EmployeeController, resolve: EmployeeController.resolve}). when('/Employee/:id', {templateUrl: '/partial/employee-detail.html', controller: EmployeeController, resolve: EmployeeController.resolve}).
when('/CostCenters', {templateUrl: '/partial/cost-center-list.html', controller: CostCenterListController, resolve: CostCenterListController.resolve}). when('/CostCentres', {templateUrl: '/partial/cost-centre-list.html', controller: CostCentreListController, resolve: CostCentreListController.resolve}).
when('/CostCenter', {templateUrl: '/partial/cost-center-detail.html', controller: CostCenterController, resolve: CostCenterController.resolve}). when('/CostCentre', {templateUrl: '/partial/cost-centre-detail.html', controller: CostCentreController, resolve: CostCentreController.resolve}).
when('/CostCenter/:id', {templateUrl: '/partial/cost-center-detail.html', controller: CostCenterController, resolve: CostCenterController.resolve}). when('/CostCentre/:id', {templateUrl: '/partial/cost-centre-detail.html', controller: CostCentreController, resolve: CostCentreController.resolve}).
when('/Products', {templateUrl: '/partial/product-list.html', controller: ProductListController, resolve: ProductListController.resolve, reloadOnSearch:false}). when('/Products', {templateUrl: '/partial/product-list.html', controller: ProductListController, resolve: ProductListController.resolve, reloadOnSearch:false}).
when('/Product', {templateUrl: '/partial/product-detail.html', controller: ProductController, resolve: ProductController.resolve}). when('/Product', {templateUrl: '/partial/product-detail.html', controller: ProductController, resolve: ProductController.resolve}).
+114
View File
@@ -0,0 +1,114 @@
'use strict';
var ServiceChargeController = ['$scope', '$location', '$routeParams', 'numberFilter', 'asDateFilter', '$modal', 'voucher', function ($scope, $location, $routeParams, numberFilter, asDate, $modal, voucher) {
$scope.voucher = voucher;
$scope.TotalPoints = function (){
return _($scope.voucher.ServiceCharges).map(function (item) {
return item.DaysWorked * Number(item.Points);
}).reduce(function (sum, item) {
return sum + item;
});
};
$scope.PointValue = function () {
return Math.round($scope.voucher.ServiceCharge * 100 / $scope.TotalPoints()) / 100;
};
$scope.less = function (employee) {
if (employee.Points >= 1) {
employee.Points -= 1;
}
};
$scope.more = function (employee) {
employee.Points += 1;
};
$scope.$watch('voucher.Date', function (newDate, oldDate) {
var nDate = asDate(newDate),
oDate = asDate(oldDate);
if (nDate !== oDate && !angular.isUndefined(nDate)) {
if (angular.isUndefined($routeParams.id)) {
return voucher.$get({type: 'Service Charge', Date: nDate}).$promise;
}
}
}, true);
$scope.employeeAmount = function (employee) {
return Number(employee.Points) * employee.DaysWorked * $scope.PointValue();
}
$scope.preventAlteration = function (voucher) {
if (angular.isUndefined($scope.perms)) {
return false;
} else if (angular.isUndefined(voucher.VoucherID)) {
return !$scope.perms['Service Charge'];
} else if (voucher.Posted && !$scope.perms['Edit Posted Vouchers']) {
return true;
} else if (voucher.User.UserID !== $scope.auth.UserID && !$scope.perms["Edit Other User's Vouchers"]) {
return true;
} else {
return false;
}
};
$scope.save = function () {
$scope.voucher.Date = asDate($scope.voucher.Date);
$scope.voucher.$save({type: 'Service Charge'}, function (u) {
$scope.toasts.push({Type: 'Success', Message: ''});
$location.path('/ServiceCharge/' + u.VoucherID);
}, function (data) {
$scope.toasts.push({Type: 'Danger', Message: data.data});
});
};
$scope.delete = function () {
$scope.voucher.$delete(function () {
$scope.toasts.push({Type: 'Success', Message: ''});
$location.path('/ServiceCharge').replace();
}, function (data) {
$scope.toasts.push({Type: 'Danger', Message: data.data});
});
};
$scope.post = function () {
$scope.voucher.$post(function (u, putResponseHeaders) {
$scope.toasts.push({Type: 'Success', Message: ''});
}, function (data, status) {
$scope.toasts.push({Type: 'Danger', Message: data.data});
});
};
$scope.confirm = function () {
var modalInstance = $modal.open({
backdrop: true,
templateUrl: '/template/modal/confirm.html',
controller: ['$scope', '$modalInstance', function ($scope, $modalInstance) {
$scope.title = "Delete Voucher";
$scope.body = "Are you sure? This cannot be undone.";
$scope.isDelete = true;
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}]
});
modalInstance.result.then(function () {
$scope.delete();
});
};
}];
ServiceChargeController.resolve = {
voucher: ['$route', 'Voucher', function ($route, Voucher) {
var id = $route.current.params.id;
if (angular.isUndefined(id)) {
return Voucher.get({type: 'Service Charge'}).$promise;
} else {
return Voucher.get({id: id}).$promise;
}
}]
};
+9 -10
View File
@@ -2,14 +2,13 @@ import datetime
from decimal import Decimal from decimal import Decimal
import uuid import uuid
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import func, and_, distinct from sqlalchemy import func, and_, distinct
from sqlalchemy.orm import aliased from sqlalchemy.orm import aliased
import transaction import transaction
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import LedgerBase, CostCenter, Ledger, Employee from brewman.models.master import LedgerBase, CostCentre, Ledger, Employee
from brewman.models.validation_exception import TryCatchFunction from brewman.models.validation_exception import TryCatchFunction
from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory, SalaryDeduction, Fingerprint, \ from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory, SalaryDeduction, Fingerprint, \
Attendance, DbImage Attendance, DbImage
@@ -21,10 +20,10 @@ __author__ = 'tanshu'
@view_config(request_method='POST', route_name='api_rebase', renderer='json', permission='Rebase') @view_config(request_method='POST', route_name='api_rebase', renderer='json', permission='Rebase')
@TryCatchFunction @TryCatchFunction
def rebase(request): def rebase(request):
DBSession.execute('SET statement_timeout TO 300000;') # DBSession.execute('SET statement_timeout TO 300000;') # 5 minutes
date = request.matchdict.get('date', None) date = request.matchdict.get('date', None)
date = datetime.datetime.strptime(date, '%d-%b-%Y') date = datetime.datetime.strptime(date, '%d-%b-%Y')
user_id = uuid.UUID(authenticated_userid(request)) user_id = uuid.UUID(request.authenticated_userid)
voucher_l, accounts = opening_ledgers(date, user_id) voucher_l, accounts = opening_ledgers(date, user_id)
voucher_b, batches = opening_batches(date, user_id) voucher_b, batches = opening_batches(date, user_id)
delete_data(date) delete_data(date)
@@ -37,7 +36,7 @@ def rebase(request):
for i in voucher_b.inventories: for i in voucher_b.inventories:
DBSession.add(i) DBSession.add(i)
cleanup_lint(date, accounts, batches) cleanup_lint(date, accounts, batches)
DBSession.execute('RESET statement_timeout;') # DBSession.execute('RESET statement_timeout;')
transaction.commit() transaction.commit()
return {} return {}
@@ -60,12 +59,12 @@ def opening_ledgers(date, user_id):
if ledger.type_object.balance_sheet and ledger.id != LedgerBase.suspense() and amount != 0: if ledger.type_object.balance_sheet and ledger.id != LedgerBase.suspense() and amount != 0:
running_total += amount running_total += amount
journal = Journal(amount=abs(amount), debit=-1 if amount < 0 else 1, ledger_id=ledger.id, journal = Journal(amount=abs(amount), debit=-1 if amount < 0 else 1, ledger_id=ledger.id,
cost_center_id=ledger.costcenter_id) cost_centre_id=ledger.cost_centre_id)
voucher.journals.append(journal) voucher.journals.append(journal)
accounts.append(ledger.id) accounts.append(ledger.id)
if running_total != 0: if running_total != 0:
journal = Journal(amount=abs(amount), debit=-1 if amount * -1 < 0 else 1, ledger_id=LedgerBase.suspense(), journal = Journal(amount=abs(amount), debit=-1 if amount * -1 < 0 else 1, ledger_id=LedgerBase.suspense(),
cost_center_id=CostCenter.cost_center_overall()) cost_centre_id=CostCentre.cost_centre_overall())
voucher.journals.append(journal) voucher.journals.append(journal)
return voucher, accounts return voucher, accounts
@@ -77,7 +76,7 @@ def opening_batches(date, user_id):
query = DBSession.query(Batch, sum_func) \ query = DBSession.query(Batch, sum_func) \
.join(Journal, Voucher.journals).join(Inventory, Voucher.inventories).join(Batch, Inventory.batch) \ .join(Journal, Voucher.journals).join(Inventory, Voucher.inventories).join(Batch, Inventory.batch) \
.filter(Voucher.date < date) \ .filter(Voucher.date < date) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \
.having(sum_func != 0) \ .having(sum_func != 0) \
.group_by(Batch).all() .group_by(Batch).all()
@@ -93,9 +92,9 @@ def opening_batches(date, user_id):
voucher.inventories.append(inventory) voucher.inventories.append(inventory)
batches.append(batch.id) batches.append(batch.id)
voucher.journals.append(Journal(amount=abs(total), debit=-1, ledger_id=LedgerBase.all_purchases(), voucher.journals.append(Journal(amount=abs(total), debit=-1, ledger_id=LedgerBase.all_purchases(),
cost_center_id=CostCenter.cost_center_overall())) cost_centre_id=CostCentre.cost_centre_overall()))
voucher.journals.append(Journal(amount=abs(total), debit=1, ledger_id=LedgerBase.all_purchases(), voucher.journals.append(Journal(amount=abs(total), debit=1, ledger_id=LedgerBase.all_purchases(),
cost_center_id=CostCenter.cost_center_purchase())) cost_centre_id=CostCentre.cost_centre_purchase()))
return voucher, batches return voucher, batches
+12 -10
View File
@@ -1,22 +1,24 @@
import datetime import datetime
from decimal import Decimal from decimal import Decimal
import uuid import uuid
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import func from sqlalchemy import func
import transaction import transaction
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import LedgerBase, CostCenter, Product from brewman.models.master import LedgerBase, CostCentre, Product
from brewman.models.validation_exception import TryCatchFunction, ValidationError from brewman.models.validation_exception import TryCatchFunction, ValidationError
from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory
__author__ = 'tanshu' __author__ = 'tanshu'
@view_config(request_method='POST', route_name='api_reset_stock', renderer='json', permission='Reset Stock') @view_config(request_method='POST', route_name='api_reset_stock', renderer='json', permission='Reset Stock')
@TryCatchFunction @TryCatchFunction
def rebase(request): def rebase(request):
user_id = uuid.UUID(authenticated_userid(request)) user_id = uuid.UUID(request.authenticated_userid)
product = Product.by_id(uuid.UUID(request.matchdict['id'])) product = Product.by_id(uuid.UUID(request.matchdict['id']))
quantity = round(Decimal(request.GET['Quantity']), 2) quantity = round(Decimal(request.GET['Quantity']), 2)
@@ -47,7 +49,7 @@ def get_closing_stock(product, finish_date=None):
.filter(Voucher.id == Inventory.voucher_id) \ .filter(Voucher.id == Inventory.voucher_id) \
.filter(Voucher.id == Journal.voucher_id) \ .filter(Voucher.id == Journal.voucher_id) \
.filter(Inventory.product_id == product.id) \ .filter(Inventory.product_id == product.id) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase())
if finish_date is not None: if finish_date is not None:
query = query.filter(Voucher.date <= finish_date) query = query.filter(Voucher.date <= finish_date)
query = query.one() query = query.one()
@@ -74,11 +76,11 @@ def create_voucher(batch, quantity, date, user_id):
DBSession.add(voucher) DBSession.add(voucher)
if quantity > 0: if quantity > 0:
source = CostCenter.cost_center_overall() source = CostCentre.cost_centre_overall()
destination = CostCenter.cost_center_purchase() destination = CostCentre.cost_centre_purchase()
else: else:
destination = CostCenter.cost_center_overall() destination = CostCentre.cost_centre_overall()
source = CostCenter.cost_center_purchase() source = CostCentre.cost_centre_purchase()
inventory = Inventory(product_id=batch.product.id, quantity=abs(quantity), rate=batch.rate, tax=batch.tax, inventory = Inventory(product_id=batch.product.id, quantity=abs(quantity), rate=batch.rate, tax=batch.tax,
discount=batch.discount, batch=batch) discount=batch.discount, batch=batch)
@@ -86,9 +88,9 @@ def create_voucher(batch, quantity, date, user_id):
DBSession.add(inventory) DBSession.add(inventory)
amount = round(inventory.amount, 2) amount = round(inventory.amount, 2)
source = Journal(debit=-1, ledger_id=LedgerBase.all_purchases(), amount=amount, cost_center_id=source) source = Journal(debit=-1, ledger_id=LedgerBase.all_purchases(), amount=amount, cost_centre_id=source)
voucher.journals.append(source) voucher.journals.append(source)
DBSession.add(source) DBSession.add(source)
destination = Journal(debit=1, ledger_id=LedgerBase.all_purchases(), amount=amount, cost_center_id=destination) destination = Journal(debit=1, ledger_id=LedgerBase.all_purchases(), amount=amount, cost_centre_id=destination)
voucher.journals.append(destination) voucher.journals.append(destination)
DBSession.add(destination) DBSession.add(destination)
+9 -10
View File
@@ -1,15 +1,14 @@
import uuid import uuid
import pkg_resources import pkg_resources
from pyramid.response import Response, FileResponse from pyramid.response import Response, FileResponse
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy.orm import joinedload_all from sqlalchemy.orm import joinedload_all
import transaction import transaction
from brewman import groupfinder from brewman import groupfinder
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import CostCentre, Ledger, LedgerType, LedgerBase
from brewman.models.master import CostCenter, Ledger, LedgerType, LedgerBase
from brewman.models.validation_exception import ValidationError, TryCatchFunction from brewman.models.validation_exception import ValidationError, TryCatchFunction
from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.models.voucher import Voucher, Journal, VoucherType
@@ -28,7 +27,7 @@ def html(request):
def save(request): def save(request):
item = Ledger(code=0, name=request.json_body['Name'], type=int(request.json_body['Type']), item = Ledger(code=0, name=request.json_body['Name'], type=int(request.json_body['Type']),
is_active=request.json_body['IsActive'], is_reconcilable=request.json_body['IsReconcilable'], is_active=request.json_body['IsActive'], is_reconcilable=request.json_body['IsReconcilable'],
costcenter_id=uuid.UUID(request.json_body['CostCenter']['CostCenterID'])).create() cost_centre_id=uuid.UUID(request.json_body['CostCentre']['CostCentreID'])).create()
transaction.commit() transaction.commit()
return account_info(item.id) return account_info(item.id)
@@ -46,7 +45,7 @@ def update(request):
item.name = request.json_body['Name'] item.name = request.json_body['Name']
item.is_active = request.json_body['IsActive'] item.is_active = request.json_body['IsActive']
item.is_reconcilable = request.json_body['IsReconcilable'] item.is_reconcilable = request.json_body['IsReconcilable']
item.costcenter_id = uuid.UUID(request.json_body['CostCenter']['CostCenterID']) item.cost_centre_id = uuid.UUID(request.json_body['CostCentre']['CostCentreID'])
transaction.commit() transaction.commit()
return account_info(item.id) return account_info(item.id)
@@ -54,7 +53,7 @@ def update(request):
@view_config(request_method='DELETE', route_name='api_account_id', renderer='json', permission='Accounts') @view_config(request_method='DELETE', route_name='api_account_id', renderer='json', permission='Accounts')
def delete(request): def delete(request):
account = Ledger.by_id(uuid.UUID(request.matchdict['id'])) account = Ledger.by_id(uuid.UUID(request.matchdict['id']))
can_delete, reason = account.can_delete('Advanced Delete' in groupfinder(authenticated_userid(request), request)) can_delete, reason = account.can_delete('Advanced Delete' in groupfinder(request.authenticated_userid, request))
if can_delete: if can_delete:
delete_with_data(account) delete_with_data(account)
transaction.commit() transaction.commit()
@@ -83,7 +82,7 @@ def show_list(request):
ledgers = [] ledgers = []
for item in list: for item in list:
ledgers.append({'Name': item.name, 'Type': item.type_object.name, 'IsActive': 'Yes' if item.is_active else 'No', ledgers.append({'Name': item.name, 'Type': item.type_object.name, 'IsActive': 'Yes' if item.is_active else 'No',
'IsReconcilable': 'Yes' if item.is_reconcilable else '', 'CostCenter': item.costcenter.name, 'IsReconcilable': 'Yes' if item.is_reconcilable else '', 'CostCentre': item.cost_centre.name,
'IsFixture': item.is_fixture, 'Url': request.route_url('account_id', id=item.id)}) 'IsFixture': item.is_fixture, 'Url': request.route_url('account_id', id=item.id)})
return ledgers return ledgers
@@ -121,13 +120,13 @@ def account_type_list(request):
def account_info(id): def account_info(id):
if id is None: if id is None:
account = {'Code': '(Auto)', 'Type': LedgerType.by_name('Creditors').id, 'IsActive': True, account = {'Code': '(Auto)', 'Type': LedgerType.by_name('Creditors').id, 'IsActive': True,
'IsReconcilable': False, 'CostCenter': CostCenter.overall()} 'IsReconcilable': False, 'CostCentre': CostCentre.overall()}
else: else:
account = Ledger.by_id(id) account = Ledger.by_id(id)
account = {'LedgerID': account.id, 'Code': account.code, 'Name': account.name, 'Type': account.type, account = {'LedgerID': account.id, 'Code': account.code, 'Name': account.name, 'Type': account.type,
'IsActive': account.is_active, 'IsReconcilable': account.is_reconcilable, 'IsActive': account.is_active, 'IsReconcilable': account.is_reconcilable,
'IsFixture': account.is_fixture, 'IsFixture': account.is_fixture,
'CostCenter': {'CostCenterID': account.costcenter_id, 'Name': account.costcenter.name}} 'CostCentre': {'CostCentreID': account.cost_centre_id, 'Name': account.cost_centre.name}}
return account return account
+8 -5
View File
@@ -1,11 +1,12 @@
import datetime import datetime
import uuid import uuid
import pkg_resources import pkg_resources
from pyramid.response import FileResponse from pyramid.response import FileResponse
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import or_ from sqlalchemy import or_
import transaction import transaction
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import AttendanceType, Employee from brewman.models.master import AttendanceType, Employee
from brewman.models.validation_exception import ValidationError, TryCatchFunction from brewman.models.validation_exception import ValidationError, TryCatchFunction
@@ -13,8 +14,10 @@ from brewman.models.voucher import Attendance
from brewman.views.fingerprint import get_prints from brewman.views.fingerprint import get_prints
from brewman.views.services.session import session_period_start, session_period_finish, session_current_date from brewman.views.services.session import session_period_start, session_period_finish, session_current_date
__author__ = 'tanshu' __author__ = 'tanshu'
@view_config(request_method='GET', route_name='attendance_date', permission='Attendance') @view_config(request_method='GET', route_name='attendance_date', permission='Attendance')
@view_config(request_method='GET', route_name='attendance', permission='Attendance') @view_config(request_method='GET', route_name='attendance', permission='Attendance')
@view_config(request_method='GET', route_name='employee_attendance_id', permission='Attendance') @view_config(request_method='GET', route_name='employee_attendance_id', permission='Attendance')
@@ -51,7 +54,7 @@ def attendance_date_report(date):
employees = DBSession().query(Employee) \ employees = DBSession().query(Employee) \
.filter(Employee.joining_date <= date) \ .filter(Employee.joining_date <= date) \
.filter(or_(Employee.is_active, Employee.leaving_date >= date)) \ .filter(or_(Employee.is_active, Employee.leaving_date >= date)) \
.order_by(Employee.costcenter_id).order_by(Employee.designation).order_by(Employee.name).all() .order_by(Employee.cost_centre_id).order_by(Employee.designation).order_by(Employee.name).all()
for item in employees: for item in employees:
att = DBSession().query(Attendance).filter(Attendance.employee_id == item.id).filter( att = DBSession().query(Attendance).filter(Attendance.employee_id == item.id).filter(
Attendance.date == date).filter(Attendance.is_valid == True).first() Attendance.date == date).filter(Attendance.is_valid == True).first()
@@ -59,7 +62,7 @@ def attendance_date_report(date):
prints, hours, worked = get_prints(item.id, date) prints, hours, worked = get_prints(item.id, date)
report['Body'].append({'id': item.id, 'Code': item.code, 'Name': item.name, 'Designation': item.designation, report['Body'].append({'id': item.id, 'Code': item.code, 'Name': item.name, 'Designation': item.designation,
'Department': item.costcenter.name, 'AttendanceTypeID': att, 'Prints': prints, 'Department': item.cost_centre.name, 'AttendanceTypeID': att, 'Prints': prints,
'Hours': hours, 'Worked': worked}) 'Hours': hours, 'Worked': worked})
return report return report
@@ -67,7 +70,7 @@ def attendance_date_report(date):
@view_config(request_method='POST', route_name='api_attendance_date', renderer='json', permission='Attendance') @view_config(request_method='POST', route_name='api_attendance_date', renderer='json', permission='Attendance')
@TryCatchFunction @TryCatchFunction
def save(request): def save(request):
user_id = uuid.UUID(authenticated_userid(request)) user_id = uuid.UUID(request.authenticated_userid)
date = request.matchdict.get('date', None) date = request.matchdict.get('date', None)
date_object = datetime.datetime.strptime(date, '%d-%b-%Y') date_object = datetime.datetime.strptime(date, '%d-%b-%Y')
@@ -129,7 +132,7 @@ def employee_attendance(employee, start_date, finish_date):
def save_employee_attendance(request): def save_employee_attendance(request):
start_date = None start_date = None
finish_date = None finish_date = None
user_id = uuid.UUID(authenticated_userid(request)) user_id = uuid.UUID(request.authenticated_userid)
employee = Employee.by_id(uuid.UUID(request.matchdict['id'])) employee = Employee.by_id(uuid.UUID(request.matchdict['id']))
for item in request.json_body['Body']: for item in request.json_body['Body']:
if start_date is None: if start_date is None:
+2 -2
View File
@@ -29,9 +29,9 @@ def attendance_record(start_date, finish_date):
employees = DBSession().query(Employee)\ employees = DBSession().query(Employee)\
.filter(Employee.joining_date <= finish_date)\ .filter(Employee.joining_date <= finish_date)\
.filter(or_(Employee.is_active, Employee.leaving_date >= start_date))\ .filter(or_(Employee.is_active, Employee.leaving_date >= start_date))\
.order_by(Employee.costcenter_id).order_by(Employee.designation).order_by(Employee.name).all() .order_by(Employee.cost_centre_id).order_by(Employee.designation).order_by(Employee.name).all()
for employee in employees: for employee in employees:
row_display = [employee.code, employee.name, employee.designation, employee.costcenter.name, employee.salary, row_display = [employee.code, employee.name, employee.designation, employee.cost_centre.name, employee.salary,
employee.service_points] employee.service_points]
row_value = ['', '', '', '', employee.salary, employee.service_points] row_value = ['', '', '', '', employee.salary, employee.service_points]
for date in daterange(start_date, finish_date, inclusive=True): for date in daterange(start_date, finish_date, inclusive=True):
+3 -6
View File
@@ -1,22 +1,21 @@
import re import re
import uuid import uuid
import pkg_resources import pkg_resources
from pyramid.response import Response, FileResponse from pyramid.response import Response, FileResponse
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
import transaction import transaction
from brewman import groupfinder from brewman import groupfinder
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.auth import User, Group from brewman.models.auth import User, Group
from brewman.models.validation_exception import TryCatchFunction, ValidationError from brewman.models.validation_exception import TryCatchFunction, ValidationError
class UserView(object): class UserView(object):
def __init__(self, request): def __init__(self, request):
self.request = request self.request = request
self.user = authenticated_userid(request) self.user = request.authenticated_userid
self.permissions = None self.permissions = None
self.has_permission = False self.has_permission = False
if self.user is not None: if self.user is not None:
@@ -117,8 +116,6 @@ class UserView(object):
def show_name(self): def show_name(self):
list = User.query().filter(User.locked_out == False).order_by(User.name).all() list = User.query().filter(User.locked_out == False).order_by(User.name).all()
users = [{'Name': item.name} for item in list] users = [{'Name': item.name} for item in list]
# for item in list:
# users.append({'Name': item.name})
return users return users
-87
View File
@@ -1,87 +0,0 @@
import uuid
import pkg_resources
from pyramid.response import Response, FileResponse
from pyramid.view import view_config
import transaction
from brewman.models import DBSession
from brewman.models.master import CostCenter
from brewman.models.validation_exception import ValidationError, TryCatchFunction
@view_config(route_name='cost_center_list', permission='Authenticated')
@view_config(request_method='GET', route_name='cost_center_id', permission='Cost Centers')
@view_config(request_method='GET', route_name='cost_center', permission='Cost Centers')
def html(request):
package, resource = 'brewman:static/base.html'.split(':', 1)
file = pkg_resources.resource_filename(package, resource)
return FileResponse(file, request=request)
@view_config(request_method='POST', route_name='api_cost_center', renderer='json', permission='Cost Centers')
@TryCatchFunction
def save(request):
item = CostCenter(request.json_body['Name'])
DBSession.add(item)
transaction.commit()
return cost_center_info(item.id)
@view_config(request_method='POST', route_name='api_cost_center_id', renderer='json', permission='Cost Centers')
@TryCatchFunction
def update(request):
item = CostCenter.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']
transaction.commit()
return cost_center_info(item.id)
@view_config(request_method='DELETE', route_name='api_cost_center_id', renderer='json', permission='Cost Centers')
def delete(request):
item = request.matchdict.get('id', None)
item = None if item is None else CostCenter.by_id(uuid.UUID(item))
if item is None:
response = Response("Cost Center not found")
response.status_int = 500
return response
elif item.is_fixture:
raise ValidationError("{0} is a fixture and cannot be edited or deleted.".format(item.name))
else:
response = Response("Cost Center deletion not implemented")
response.status_int = 500
return response
@view_config(request_method='GET', route_name='api_cost_center_id', renderer='json', permission='Cost Centers')
def show_id(request):
return cost_center_info(uuid.UUID(request.matchdict.get('id', None)))
@view_config(request_method='GET', route_name='api_cost_center', renderer='json', permission='Cost Centers')
def show_blank(request):
return cost_center_info(None)
@view_config(request_method='GET', route_name='api_cost_center', request_param='list', renderer='json',
permission='Authenticated')
def show_list(request):
list = CostCenter.list()
cost_centers = []
for item in list:
cost_centers.append({'CostCenterID': item.id, 'Name': item.name, 'IsFixture': item.is_fixture,
'Url': request.route_url('cost_center_id', id=item.id)})
return cost_centers
def cost_center_info(id):
if id is None:
return {}
else:
cost_center = CostCenter.by_id(id)
return {'CostCenterID': cost_center.id, 'Name': cost_center.name, 'IsFixture': cost_center.is_fixture}
+87
View File
@@ -0,0 +1,87 @@
import uuid
import pkg_resources
from pyramid.response import Response, FileResponse
from pyramid.view import view_config
import transaction
from brewman.models import DBSession
from brewman.models.master import CostCentre
from brewman.models.validation_exception import ValidationError, TryCatchFunction
@view_config(route_name='cost_centre_list', permission='Authenticated')
@view_config(request_method='GET', route_name='cost_centre_id', permission='Cost Centres')
@view_config(request_method='GET', route_name='cost_centre', permission='Cost Centres')
def html(request):
package, resource = 'brewman:static/base.html'.split(':', 1)
file = pkg_resources.resource_filename(package, resource)
return FileResponse(file, request=request)
@view_config(request_method='POST', route_name='api_cost_centre', renderer='json', permission='Cost Centres')
@TryCatchFunction
def save(request):
item = CostCentre(request.json_body['Name'])
DBSession.add(item)
transaction.commit()
return cost_centre_info(item.id)
@view_config(request_method='POST', route_name='api_cost_centre_id', renderer='json', permission='Cost Centres')
@TryCatchFunction
def update(request):
item = CostCentre.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']
transaction.commit()
return cost_centre_info(item.id)
@view_config(request_method='DELETE', route_name='api_cost_centre_id', renderer='json', permission='Cost Centres')
def delete(request):
item = request.matchdict.get('id', None)
item = None if item is None else CostCentre.by_id(uuid.UUID(item))
if item is None:
response = Response("Cost Centre not found")
response.status_int = 500
return response
elif item.is_fixture:
raise ValidationError("{0} is a fixture and cannot be edited or deleted.".format(item.name))
else:
response = Response("Cost Centre deletion not implemented")
response.status_int = 500
return response
@view_config(request_method='GET', route_name='api_cost_centre_id', renderer='json', permission='Cost Centres')
def show_id(request):
return cost_centre_info(uuid.UUID(request.matchdict.get('id', None)))
@view_config(request_method='GET', route_name='api_cost_centre', renderer='json', permission='Cost Centres')
def show_blank(request):
return cost_centre_info(None)
@view_config(request_method='GET', route_name='api_cost_centre', request_param='list', renderer='json',
permission='Authenticated')
def show_list(request):
list = CostCentre.list()
cost_centres = []
for item in list:
cost_centres.append({'CostCentreID': item.id, 'Name': item.name, 'IsFixture': item.is_fixture,
'Url': request.route_url('cost_centre_id', id=item.id)})
return cost_centres
def cost_centre_info(id):
if id is None:
return {}
else:
cost_centre = CostCentre.by_id(id)
return {'CostCentreID': cost_centre.id, 'Name': cost_centre.name, 'IsFixture': cost_centre.is_fixture}
+3 -4
View File
@@ -1,15 +1,14 @@
import pkg_resources import pkg_resources
from pyramid.response import FileResponse from pyramid.response import FileResponse
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import func from sqlalchemy import func
from brewman import groupfinder from brewman import groupfinder
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import LedgerBase from brewman.models.master import LedgerBase
from brewman.models.validation_exception import TryCatchFunction from brewman.models.validation_exception import TryCatchFunction
from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.models.voucher import Voucher, Journal, VoucherType
from brewman.views.services.session import session_period_finish, session_period_start, session_current_date from brewman.views.services.session import session_period_finish, session_period_start
@view_config(route_name='dashboard', permission='Authenticated') @view_config(route_name='dashboard', permission='Authenticated')
@@ -22,7 +21,7 @@ def html(request):
@view_config(route_name='api_dashboard', renderer='json') @view_config(route_name='api_dashboard', renderer='json')
@TryCatchFunction @TryCatchFunction
def dashboard(request): def dashboard(request):
user = authenticated_userid(request) user = request.authenticated_userid
if user is None or 'Dashboard' not in groupfinder(user, request): if user is None or 'Dashboard' not in groupfinder(user, request):
return {'Enabled': False} return {'Enabled': False}
start_date = request.GET.get('s', session_period_start(request)) start_date = request.GET.get('s', session_period_start(request))
+11 -12
View File
@@ -1,17 +1,16 @@
import datetime import datetime
import uuid import uuid
from decimal import Decimal from decimal import Decimal
import pkg_resources import pkg_resources
from pyramid.response import Response, FileResponse from pyramid.response import Response, FileResponse
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy.orm import joinedload_all from sqlalchemy.orm import joinedload_all
import transaction import transaction
from brewman import groupfinder from brewman import groupfinder
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import CostCentre, Employee, LedgerBase, Ledger
from brewman.models.master import CostCenter, Employee, LedgerBase, Ledger
from brewman.models.validation_exception import ValidationError, TryCatchFunction from brewman.models.validation_exception import ValidationError, TryCatchFunction
from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.models.voucher import Voucher, Journal, VoucherType
from brewman.views import to_uuid from brewman.views import to_uuid
@@ -34,7 +33,7 @@ def save(request):
if name == '': if name == '':
raise ValidationError('Name cannot be blank') raise ValidationError('Name cannot be blank')
cost_center_id = uuid.UUID(request.json_body['CostCenter']['CostCenterID']) cost_centre_id = uuid.UUID(request.json_body['CostCentre']['CostCentreID'])
designation = request.json_body.get('Designation', '').strip() designation = request.json_body.get('Designation', '').strip()
try: try:
@@ -67,7 +66,7 @@ def save(request):
except (ValueError, KeyError, TypeError): except (ValueError, KeyError, TypeError):
raise ValidationError("Leaving Date is not a valid date") raise ValidationError("Leaving Date is not a valid date")
item = Employee(0, name, is_active, cost_center_id, designation, salary, service_points, joining_date, item = Employee(0, name, is_active, cost_centre_id, designation, salary, service_points, joining_date,
leaving_date).create() leaving_date).create()
transaction.commit() transaction.commit()
return employee_info(item.id) return employee_info(item.id)
@@ -84,7 +83,7 @@ def update(request):
if item.name == '': if item.name == '':
raise ValidationError('Name cannot be blank') raise ValidationError('Name cannot be blank')
item.costcenter_id = uuid.UUID(request.json_body['CostCenter']['CostCenterID']) item.cost_centre_id = uuid.UUID(request.json_body['CostCentre']['CostCentreID'])
item.designation = request.json_body.get('Designation', '').strip() item.designation = request.json_body.get('Designation', '').strip()
try: try:
@@ -125,7 +124,7 @@ def update(request):
@TryCatchFunction @TryCatchFunction
def delete(request): def delete(request):
employee = Employee.by_id(uuid.UUID(request.matchdict['id'])) employee = Employee.by_id(uuid.UUID(request.matchdict['id']))
can_delete, reason = employee.can_delete('Advanced Delete' in groupfinder(authenticated_userid(request), request)) can_delete, reason = employee.can_delete('Advanced Delete' in groupfinder(request.authenticated_userid, request))
if can_delete: if can_delete:
delete_with_data(employee) delete_with_data(employee)
transaction.commit() transaction.commit()
@@ -160,7 +159,7 @@ def show_list(request):
ledgers.append( ledgers.append(
{'Code': item.code, 'Name': item.name, 'Designation': item.designation, 'Salary': item.salary, {'Code': item.code, 'Name': item.name, 'Designation': item.designation, 'Salary': item.salary,
'ServicePoints': item.service_points, 'IsActive': item.is_active, 'ServicePoints': item.service_points, 'IsActive': item.is_active,
'CostCenter': item.costcenter.name, 'Url': request.route_url('employee_id', id=item.id), 'CostCentre': item.cost_centre.name, 'Url': request.route_url('employee_id', id=item.id),
'JoiningDate': item.joining_date.strftime('%d-%b-%Y'), 'JoiningDate': item.joining_date.strftime('%d-%b-%Y'),
'LeavingDate': '' if item.is_active else item.leaving_date.strftime('%d-%b-%Y')}) 'LeavingDate': '' if item.is_active else item.leaving_date.strftime('%d-%b-%Y')})
return ledgers return ledgers
@@ -177,7 +176,7 @@ def show_term(request):
list = [] list = []
for index, item in enumerate(LedgerBase.list(10, filter)): for index, item in enumerate(LedgerBase.list(10, filter)):
list.append({'LedgerID': item.id, 'Name': item.name, 'Designation': item.designation, list.append({'LedgerID': item.id, 'Name': item.name, 'Designation': item.designation,
'CostCenter': {'CostCenterID': item.costcenter.id, 'Name': item.costcenter.name}}) 'CostCentre': {'CostCentreID': item.cost_centre.id, 'Name': item.cost_centre.name}})
if count is not None and index == count - 1: if count is not None and index == count - 1:
break break
return list return list
@@ -185,7 +184,7 @@ def show_term(request):
def employee_info(id): def employee_info(id):
if id is None: if id is None:
employee = {'Code': '(Auto)', 'IsActive': True, 'CostCenter': CostCenter.overall()} employee = {'Code': '(Auto)', 'IsActive': True, 'CostCentre': CostCentre.overall()}
else: else:
employee = Employee.by_id(id) employee = Employee.by_id(id)
if employee is None: if employee is None:
@@ -194,7 +193,7 @@ def employee_info(id):
'IsActive': employee.is_active, 'Designation': employee.designation, 'Salary': employee.salary, 'IsActive': employee.is_active, 'Designation': employee.designation, 'Salary': employee.salary,
'ServicePoints': employee.service_points, 'JoiningDate': employee.joining_date.strftime('%d-%b-%Y'), 'ServicePoints': employee.service_points, 'JoiningDate': employee.joining_date.strftime('%d-%b-%Y'),
'LeavingDate': None if employee.is_active else employee.leaving_date.strftime('%d-%b-%Y'), 'LeavingDate': None if employee.is_active else employee.leaving_date.strftime('%d-%b-%Y'),
'CostCenter': {'CostCenterID': employee.costcenter_id, 'Name': employee.costcenter.name}} 'CostCentre': {'CostCentreID': employee.cost_centre_id, 'Name': employee.cost_centre.name}}
return employee return employee
+7 -9
View File
@@ -1,16 +1,14 @@
import datetime import datetime
import uuid import uuid
import pkg_resources import pkg_resources
from pyramid.response import FileResponse from pyramid.response import FileResponse
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy.orm import joinedload_all
import transaction import transaction
from brewman import groupfinder from brewman import groupfinder
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.auth import User from brewman.models.auth import User
from brewman.models.messaging import Thread, Post, Tag, Subscriber from brewman.models.messaging import Thread, Post, Tag, Subscriber
from brewman.models.tzinfoutc import get_age from brewman.models.tzinfoutc import get_age
from brewman.models.validation_exception import TryCatchFunction, ValidationError from brewman.models.validation_exception import TryCatchFunction, ValidationError
@@ -27,7 +25,7 @@ def html(request):
@view_config(request_method='POST', route_name='api_message', renderer='json', permission='Authenticated') @view_config(request_method='POST', route_name='api_message', renderer='json', permission='Authenticated')
@TryCatchFunction @TryCatchFunction
def save(request): def save(request):
user_id = uuid.UUID(authenticated_userid(request)) user_id = uuid.UUID(request.authenticated_userid)
user_name = User.by_id(user_id).name user_name = User.by_id(user_id).name
title = request.json_body['Title'].strip() title = request.json_body['Title'].strip()
if Thread.by_title(title) is not None: if Thread.by_title(title) is not None:
@@ -60,7 +58,7 @@ def save(request):
@view_config(request_method='POST', route_name='api_message_id', renderer='json', permission='Authenticated') @view_config(request_method='POST', route_name='api_message_id', renderer='json', permission='Authenticated')
@TryCatchFunction @TryCatchFunction
def update(request): def update(request):
user_id = uuid.UUID(authenticated_userid(request)) user_id = uuid.UUID(request.authenticated_userid)
user_name = User.by_id(user_id).name user_name = User.by_id(user_id).name
super_user = 'Messages' in groupfinder(user_id, request) super_user = 'Messages' in groupfinder(user_id, request)
thread = Thread.by_id(uuid.UUID(request.matchdict['id'])) thread = Thread.by_id(uuid.UUID(request.matchdict['id']))
@@ -127,14 +125,14 @@ def update(request):
@view_config(request_method='GET', route_name='api_message', renderer='json', permission='Authenticated') @view_config(request_method='GET', route_name='api_message', renderer='json', permission='Authenticated')
def show_blank(request): def show_blank(request):
user = User.by_id(authenticated_userid(request)).name user = User.by_id(request.authenticated_userid).name
return {'Title': '', 'User': user, 'Tags': [], 'Priority': 4, 'Public': False, return {'Title': '', 'User': user, 'Tags': [], 'Priority': 4, 'Public': False,
'Posts': [], 'Closed': False, 'Subscribers': [user]} 'Posts': [], 'Closed': False, 'Subscribers': [user]}
@view_config(request_method='GET', route_name='api_message_id', renderer='json', permission='Authenticated') @view_config(request_method='GET', route_name='api_message_id', renderer='json', permission='Authenticated')
def show_id(request): def show_id(request):
user_id = authenticated_userid(request) and uuid.UUID(authenticated_userid(request)) user_id = request.authenticated_userid and uuid.UUID(request.authenticated_userid)
thread = Thread.by_id(request.matchdict['id']) thread = Thread.by_id(request.matchdict['id'])
subscriber = [s for s in thread.subscribers if s.user_id == user_id] subscriber = [s for s in thread.subscribers if s.user_id == user_id]
if len(subscriber) > 0: if len(subscriber) > 0:
@@ -146,7 +144,7 @@ def show_id(request):
@view_config(request_method='GET', route_name='api_message', renderer='json', request_param='list') @view_config(request_method='GET', route_name='api_message', renderer='json', request_param='list')
def show_list(request): def show_list(request):
user_id = authenticated_userid(request) and uuid.UUID(authenticated_userid(request)) user_id = request.authenticated_userid and uuid.UUID(request.authenticated_userid)
list = Thread.query() list = Thread.query()
type = request.params.get('type', 'open') type = request.params.get('type', 'open')
+1 -2
View File
@@ -3,7 +3,6 @@ import uuid
import pkg_resources import pkg_resources
from pyramid.response import Response, FileResponse from pyramid.response import Response, FileResponse
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import desc from sqlalchemy import desc
from sqlalchemy.orm import joinedload_all from sqlalchemy.orm import joinedload_all
@@ -109,7 +108,7 @@ def update(request):
@TryCatchFunction @TryCatchFunction
def delete(request): def delete(request):
product = Product.by_id(uuid.UUID(request.matchdict['id'])) product = Product.by_id(uuid.UUID(request.matchdict['id']))
can_delete, reason = product.can_delete('Advanced Delete' in groupfinder(authenticated_userid(request), request)) can_delete, reason = product.can_delete('Advanced Delete' in groupfinder(request.authenticated_userid, request))
if can_delete: if can_delete:
delete_with_data(product) delete_with_data(product)
+4 -4
View File
@@ -6,7 +6,7 @@ from sqlalchemy.sql.expression import func
from pyramid.view import view_config from pyramid.view import view_config
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import Product, CostCenter from brewman.models.master import Product, CostCentre
from brewman.models.voucher import Voucher, Journal, Inventory from brewman.models.voucher import Voucher, Journal, Inventory
from brewman.views.services.session import session_period_finish from brewman.views.services.session import session_period_finish
@@ -38,7 +38,7 @@ def build_report(date):
query = DBSession.query(Product, quantity_sum, amount_sum) \ query = DBSession.query(Product, quantity_sum, amount_sum) \
.join(Product.inventories).join(Inventory.voucher).join(Voucher.journals) \ .join(Product.inventories).join(Inventory.voucher).join(Voucher.journals) \
.filter(Voucher.date <= date) \ .filter(Voucher.date <= date) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \
.group_by(Product) \ .group_by(Product) \
.order_by(amount_sum.desc()).all() .order_by(amount_sum.desc()).all()
@@ -54,7 +54,7 @@ def get_opening_stock(startDate):
opening_stock = DBSession.query(func.sum(Inventory.quantity * Inventory.rate * (1 + Inventory.tax) * Journal.debit)) \ opening_stock = DBSession.query(func.sum(Inventory.quantity * Inventory.rate * (1 + Inventory.tax) * Journal.debit)) \
.join(Journal.voucher).join(Journal.ledger).join(Voucher.inventories) \ .join(Journal.voucher).join(Journal.ledger).join(Voucher.inventories) \
.filter(Voucher.date < startDate) \ .filter(Voucher.date < startDate) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \
.scalar() .scalar()
return 0 if opening_stock is None else opening_stock return 0 if opening_stock is None else opening_stock
@@ -63,6 +63,6 @@ def get_closing_stock(finishDate):
closing_stock = DBSession.query(func.sum(Inventory.quantity * Inventory.rate * (1 + Inventory.tax) * Journal.debit)) \ closing_stock = DBSession.query(func.sum(Inventory.quantity * Inventory.rate * (1 + Inventory.tax) * Journal.debit)) \
.join(Journal.voucher).join(Journal.ledger).join(Voucher.inventories) \ .join(Journal.voucher).join(Journal.ledger).join(Voucher.inventories) \
.filter(Voucher.date <= finishDate) \ .filter(Voucher.date <= finishDate) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \
.scalar() .scalar()
return 0 if closing_stock is None else closing_stock return 0 if closing_stock is None else closing_stock
+5 -5
View File
@@ -8,7 +8,7 @@ import uuid
from pyramid.view import view_config from pyramid.view import view_config
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import Product, CostCenter from brewman.models.master import Product, CostCentre
from brewman.models.validation_exception import ValidationError, TryCatchFunction from brewman.models.validation_exception import ValidationError, TryCatchFunction
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory
@@ -62,18 +62,18 @@ def build_report(request, info):
query = DBSession.query(Voucher, Inventory, Journal).options( query = DBSession.query(Voucher, Inventory, Journal).options(
joinedload(Journal.ledger, innerjoin=True), joinedload(Journal.ledger, innerjoin=True),
joinedload(Journal.costcenter, innerjoin=True)) \ joinedload(Journal.cost_centre, innerjoin=True)) \
.filter(Voucher.id == Inventory.voucher_id) \ .filter(Voucher.id == Inventory.voucher_id) \
.filter(Voucher.id == Journal.voucher_id) \ .filter(Voucher.id == Journal.voucher_id) \
.filter(Inventory.product_id == product_id) \ .filter(Inventory.product_id == product_id) \
.filter(Journal.cost_center_id != CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id != CostCentre.cost_centre_purchase()) \
.filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \
.filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \ .filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \
.order_by(Voucher.date).order_by(Voucher.last_edit_date).all() .order_by(Voucher.date).order_by(Voucher.last_edit_date).all()
for row in query: for row in query:
journalDebit = row.Journal.debit * -1 journalDebit = row.Journal.debit * -1
name = row.Journal.costcenter.name if row.Voucher.type == VoucherType.by_name( name = row.Journal.cost_centre.name if row.Voucher.type == VoucherType.by_name(
'Issue').id else row.Journal.ledger.name 'Issue').id else row.Journal.ledger.name
debitQ = row.Inventory.quantity if journalDebit == 1 else 0 debitQ = row.Inventory.quantity if journalDebit == 1 else 0
debitA = row.Inventory.amount if journalDebit == 1 else 0 debitA = row.Inventory.amount if journalDebit == 1 else 0
@@ -108,7 +108,7 @@ def opening_balance(product_id, start_date):
.filter(Voucher.id == Inventory.voucher_id) \ .filter(Voucher.id == Inventory.voucher_id) \
.filter(Voucher.id == Journal.voucher_id) \ .filter(Voucher.id == Journal.voucher_id) \
.filter(Inventory.product_id == product_id) \ .filter(Inventory.product_id == product_id) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \
.filter(Voucher.date < datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.date < datetime.datetime.strptime(start_date, '%d-%b-%Y')) \
.one() .one()
+1 -1
View File
@@ -6,7 +6,7 @@ from sqlalchemy.sql.expression import func, desc
from pyramid.view import view_config from pyramid.view import view_config
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import CostCenter, LedgerType, LedgerBase from brewman.models.master import CostCentre, LedgerType, LedgerBase
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory
from brewman.views.services.session import session_period_start, session_period_finish from brewman.views.services.session import session_period_start, session_period_finish
+2 -2
View File
@@ -6,7 +6,7 @@ from sqlalchemy.sql.expression import func, desc
from pyramid.view import view_config from pyramid.view import view_config
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import CostCenter, Product from brewman.models.master import CostCentre, Product
from brewman.models.voucher import Voucher, Journal, Inventory, VoucherType from brewman.models.voucher import Voucher, Journal, Inventory, VoucherType
from brewman.views.services.session import session_period_start, session_period_finish from brewman.views.services.session import session_period_start, session_period_finish
@@ -42,7 +42,7 @@ def build_report(request, start_date, finish_date):
.filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \
.filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \ .filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \
.filter(Voucher.type != VoucherType.by_name('Issue').id) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \
.group_by(Product).order_by(desc(amount_sum)).all() .group_by(Product).order_by(desc(amount_sum)).all()
total_amount = 0 total_amount = 0
+10 -10
View File
@@ -7,7 +7,7 @@ from sqlalchemy.sql.expression import func, case
from pyramid.view import view_config from pyramid.view import view_config
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import LedgerBase, CostCenter, Product, ProductGroup from brewman.models.master import LedgerBase, CostCentre, Product, ProductGroup
from brewman.models.voucher import Voucher, Journal, Inventory from brewman.models.voucher import Voucher, Journal, Inventory
from brewman.views.services.session import session_period_start, session_period_finish from brewman.views.services.session import session_period_start, session_period_finish
@@ -50,24 +50,24 @@ def build_report(request, start_date, finish_date):
sum_issue = func.sum(case([(LedgerBase.type == 2, Journal.signed_amount)], else_=0)).label('issue') sum_issue = func.sum(case([(LedgerBase.type == 2, Journal.signed_amount)], else_=0)).label('issue')
sum_sale = (func.sum(case([(LedgerBase.type == 3, Journal.signed_amount)], else_=0)) * -1).label('sale') sum_sale = (func.sum(case([(LedgerBase.type == 3, Journal.signed_amount)], else_=0)) * -1).label('sale')
query = DBSession.query(CostCenter, sum_issue, sum_sale) \ query = DBSession.query(CostCentre, sum_issue, sum_sale) \
.join(CostCenter.journals).join(Journal.voucher).join(Journal.ledger) \ .join(CostCentre.journals).join(Journal.voucher).join(Journal.ledger) \
.filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \
.filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \ .filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \
.filter(Journal.cost_center_id != CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id != CostCentre.cost_centre_purchase()) \
.filter(LedgerBase.type.in_([2, 3])) \ .filter(LedgerBase.type.in_([2, 3])) \
.group_by(CostCenter) \ .group_by(CostCentre) \
.order_by(sum_sale.desc()).all() .order_by(sum_sale.desc()).all()
issues = 0 issues = 0
sales = 0 sales = 0
for cost_center, issue, sale in query: for cost_centre, issue, sale in query:
issues += issue issues += issue
sales += sale sales += sale
rmc = 0 if sale == 0 else issue / sale rmc = 0 if sale == 0 else issue / sale
report['Body'].append( report['Body'].append(
{'Name': cost_center.name, 'Issue': issue, 'Sale': sale, 'Rmc': rmc, {'Name': cost_centre.name, 'Issue': issue, 'Sale': sale, 'Rmc': rmc,
'Url': request.route_url('raw_material_cost_id', id=str(cost_center.id), 'Url': request.route_url('raw_material_cost_id', id=str(cost_centre.id),
_query={'StartDate': start_date, 'FinishDate': finish_date})}) _query={'StartDate': start_date, 'FinishDate': finish_date})})
rmc = 0 if sales == 0 else issues / sales rmc = 0 if sales == 0 else issues / sales
@@ -76,7 +76,7 @@ def build_report(request, start_date, finish_date):
return report return report
def build_report_id(request, cost_center_id, start_date, finish_date): def build_report_id(request, cost_centre_id, start_date, finish_date):
report = {'StartDate': start_date, 'FinishDate': finish_date, 'Body': []} report = {'StartDate': start_date, 'FinishDate': finish_date, 'Body': []}
sum_quantity = func.sum(Inventory.quantity * Journal.debit).label('quantity') sum_quantity = func.sum(Inventory.quantity * Journal.debit).label('quantity')
@@ -88,7 +88,7 @@ def build_report_id(request, cost_center_id, start_date, finish_date):
.filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \
.filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \ .filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \
.filter(Voucher.type == 3) \ .filter(Voucher.type == 3) \
.filter(Journal.cost_center_id == cost_center_id) \ .filter(Journal.cost_centre_id == cost_centre_id) \
.group_by(Product).group_by(Journal.debit).group_by(ProductGroup.name) \ .group_by(Product).group_by(Journal.debit).group_by(ProductGroup.name) \
.order_by(ProductGroup.name).order_by(sum_net.desc()).all() .order_by(ProductGroup.name).order_by(sum_net.desc()).all()
+4 -4
View File
@@ -6,7 +6,7 @@ from sqlalchemy.sql.expression import func
from pyramid.view import view_config from pyramid.view import view_config
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import Product, CostCenter from brewman.models.master import Product, CostCentre
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory
from brewman.views.services.session import session_period_start, session_period_finish from brewman.views.services.session import session_period_start, session_period_finish
@@ -40,7 +40,7 @@ def build_stock_movement(start_date, finish_date):
openings = DBSession.query(Product, quantity_sum) \ openings = DBSession.query(Product, quantity_sum) \
.join(Product.inventories).join(Inventory.voucher).join(Voucher.journals) \ .join(Product.inventories).join(Inventory.voucher).join(Voucher.journals) \
.filter(Voucher.date < start_date) \ .filter(Voucher.date < start_date) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \
.group_by(Product).all() .group_by(Product).all()
for product, quantity in openings: for product, quantity in openings:
dict[product.id] = {'ProductID': product.id, 'Name': product.full_name, 'Group': product.product_group.name, dict[product.id] = {'ProductID': product.id, 'Name': product.full_name, 'Group': product.product_group.name,
@@ -50,7 +50,7 @@ def build_stock_movement(start_date, finish_date):
.filter(Voucher.date >= start_date) \ .filter(Voucher.date >= start_date) \
.filter(Voucher.date <= finish_date) \ .filter(Voucher.date <= finish_date) \
.filter(Voucher.type != VoucherType.by_name('Issue').id) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \
.group_by(Product).all() .group_by(Product).all()
for product, quantity in purchases: for product, quantity in purchases:
if product.id in dict: if product.id in dict:
@@ -63,7 +63,7 @@ def build_stock_movement(start_date, finish_date):
.filter(Voucher.date >= start_date) \ .filter(Voucher.date >= start_date) \
.filter(Voucher.date <= finish_date) \ .filter(Voucher.date <= finish_date) \
.filter(Voucher.type == VoucherType.by_name('Issue').id) \ .filter(Voucher.type == VoucherType.by_name('Issue').id) \
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \
.group_by(Product).all() .group_by(Product).all()
for product, quantity in issues: for product, quantity in issues:
if product.id in dict: if product.id in dict:
@@ -22,9 +22,9 @@ def grid_date(request):
@TryCatchFunction @TryCatchFunction
def grid_voucher(request): def grid_voucher(request):
voucher = Voucher.by_id(uuid.UUID(request.matchdict['date'])) voucher = Voucher.by_id(uuid.UUID(request.matchdict['date']))
source = [j.cost_center_id for j in voucher.journals if j.debit == -1] source = [j.cost_centre_id for j in voucher.journals if j.debit == -1]
source = source[0] source = source[0]
destination = [j.cost_center_id for j in voucher.journals if j.debit == 1] destination = [j.cost_centre_id for j in voucher.journals if j.debit == 1]
destination = destination[0] destination = destination[0]
return get_grid(voucher.date, source, destination) return get_grid(voucher.date, source, destination)
@@ -34,8 +34,8 @@ def get_grid(date, source, destination):
source_journal = aliased(Journal) source_journal = aliased(Journal)
destination_journal = aliased(Journal) destination_journal = aliased(Journal)
source_or = (and_(source_journal.cost_center_id == source, source_journal.debit == -1)) source_or = (and_(source_journal.cost_centre_id == source, source_journal.debit == -1))
destination_or = (and_(destination_journal.cost_center_id == destination, destination_journal.debit == 1)) destination_or = (and_(destination_journal.cost_centre_id == destination, destination_journal.debit == 1))
query = DBSession.query(Voucher, source_journal.amount)\ query = DBSession.query(Voucher, source_journal.amount)\
.join(source_journal, Voucher.journals)\ .join(source_journal, Voucher.journals)\
.join(destination_journal, Voucher.journals)\ .join(destination_journal, Voucher.journals)\
+5 -2
View File
@@ -1,22 +1,25 @@
from datetime import date, timedelta from datetime import date, timedelta
import uuid import uuid
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from brewman import groupfinder from brewman import groupfinder
from brewman.models.auth import Role, User from brewman.models.auth import Role, User
def session_current_date(request): def session_current_date(request):
session = request.session session = request.session
if 'currentDate' not in session: if 'currentDate' not in session:
session['currentDate'] = date.today().strftime('%d-%b-%Y') session['currentDate'] = date.today().strftime('%d-%b-%Y')
return session['currentDate'] return session['currentDate']
def session_current_date_set(request, date): def session_current_date_set(request, date):
session = request.session session = request.session
session['currentDate'] = date session['currentDate'] = date
return session['currentDate'] return session['currentDate']
def session_period_start(request): def session_period_start(request):
session = request.session session = request.session
if 'periodStart' not in session: if 'periodStart' not in session:
@@ -33,7 +36,7 @@ def session_period_finish(request):
@view_config(route_name='api_auth', renderer='json') @view_config(route_name='api_auth', renderer='json')
def user_permission(request): def user_permission(request):
user_id = authenticated_userid(request) user_id = request.authenticated_userid
if user_id is None: if user_id is None:
auth = {'isAuthenticated': False, 'perms': {}} auth = {'isAuthenticated': False, 'perms': {}}
elif 'auth' in request.session: elif 'auth' in request.session:
+65 -17
View File
@@ -1,22 +1,25 @@
import datetime
from decimal import Decimal
import uuid import uuid
import pkg_resources import pkg_resources
from pyramid.response import Response, FileResponse from pyramid.response import Response, FileResponse
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import func from sqlalchemy import func, or_
import transaction import transaction
from brewman import groupfinder from brewman import groupfinder
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.auth import User from brewman.models.auth import User
from brewman.models.master import LedgerBase, CostCenter from brewman.models.master import LedgerBase, CostCentre, Employee, AttendanceType, Ledger
from brewman.models.validation_exception import ValidationError, TryCatchFunction from brewman.models.validation_exception import ValidationError, TryCatchFunction
from brewman.models.voucher import Voucher, VoucherType, Inventory, DbImage from brewman.models.voucher import Voucher, VoucherType, Inventory, DbImage, Attendance, Journal
from brewman.views import get_lock_info from brewman.views import get_lock_info
from .issue import issue_create_voucher, issue_update_voucher from .issue import issue_create_voucher, issue_update_voucher
from .journal import journal_update_voucher, journal_create_voucher from .journal import journal_update_voucher, journal_create_voucher
from .purchase import purchase_create_voucher, purchase_update_voucher from .purchase import purchase_create_voucher, purchase_update_voucher
from .service_charge import service_charge_create_voucher, service_charge_update_voucher
from ..session import get_first_day
__author__ = 'tanshu' __author__ = 'tanshu'
@@ -36,6 +39,8 @@ __author__ = 'tanshu'
@view_config(request_method='GET', route_name='issue', permission='Issue') @view_config(request_method='GET', route_name='issue', permission='Issue')
@view_config(request_method='GET', route_name='salary_deduction_id', permission='Issue') @view_config(request_method='GET', route_name='salary_deduction_id', permission='Issue')
@view_config(request_method='GET', route_name='salary_deduction', permission='Issue') @view_config(request_method='GET', route_name='salary_deduction', permission='Issue')
@view_config(request_method='GET', route_name='service_charge_id', permission='Service Charge')
@view_config(request_method='GET', route_name='service_charge', permission='Service Charge')
def journal_get(request): def journal_get(request):
package, resource = 'brewman:static/base.html'.split(':', 1) package, resource = 'brewman:static/base.html'.split(':', 1)
file = pkg_resources.resource_filename(package, resource) file = pkg_resources.resource_filename(package, resource)
@@ -46,7 +51,7 @@ def journal_get(request):
permission='Post Vouchers') permission='Post Vouchers')
@TryCatchFunction @TryCatchFunction
def voucher_post(request): def voucher_post(request):
user = User.by_id(uuid.UUID(authenticated_userid(request))) user = User.by_id(uuid.UUID(request.authenticated_userid))
voucher = Voucher.by_id(uuid.UUID(request.matchdict['id'])) voucher = Voucher.by_id(uuid.UUID(request.matchdict['id']))
start, finish = get_lock_info() start, finish = get_lock_info()
if start is not None and start > voucher.date: if start is not None and start > voucher.date:
@@ -60,7 +65,7 @@ def voucher_post(request):
def check_delete_permissions(request, voucher): def check_delete_permissions(request, voucher):
user = User.by_id(uuid.UUID(authenticated_userid(request))) user = User.by_id(uuid.UUID(request.authenticated_userid))
permissions = groupfinder(user.id, request) permissions = groupfinder(user.id, request)
if voucher.posted and not 'Edit Posted Vouchers' in permissions: if voucher.posted and not 'Edit Posted Vouchers' in permissions:
@@ -99,10 +104,10 @@ def delete(request):
if voucher.type == VoucherType.by_name('Issue').id: if voucher.type == VoucherType.by_name('Issue').id:
for item in voucher.journals: for item in voucher.journals:
if item.debit == 1: if item.debit == 1:
destination = item.cost_center_id destination = item.cost_centre_id
else: else:
source = item.cost_center_id source = item.cost_centre_id
batch_consumed = True if source == CostCenter.cost_center_purchase() else False if destination == CostCenter.cost_center_purchase() else None batch_consumed = True if source == CostCentre.cost_centre_purchase() else False if destination == CostCentre.cost_centre_purchase() else None
if batch_consumed is None: if batch_consumed is None:
pass pass
elif batch_consumed: elif batch_consumed:
@@ -151,6 +156,7 @@ def voucher_info(voucher, request):
'Journals': [], 'Journals': [],
'Inventories': [], 'Inventories': [],
'SalaryDeductions': [], 'SalaryDeductions': [],
'ServiceCharges': [],
'Files': [], 'Files': [],
'CreationDate': voucher.creation_date.strftime('%d-%b-%Y %H:%M'), 'CreationDate': voucher.creation_date.strftime('%d-%b-%Y %H:%M'),
'LastEditDate': voucher.last_edit_date.strftime('%d-%b-%Y %H:%M'), 'LastEditDate': voucher.last_edit_date.strftime('%d-%b-%Y %H:%M'),
@@ -161,7 +167,7 @@ def voucher_info(voucher, request):
for item in voucher.journals: for item in voucher.journals:
json_voucher['Journals'].append({'JournalID': item.id, 'Debit': item.debit, 'Amount': item.amount, json_voucher['Journals'].append({'JournalID': item.id, 'Debit': item.debit, 'Amount': item.amount,
'Ledger': {'LedgerID': item.ledger.id, 'Name': item.ledger.name}, 'Ledger': {'LedgerID': item.ledger.id, 'Name': item.ledger.name},
'CostCenter': {'CostCenterID': item.cost_center_id}}) 'CostCentre': {'CostCentreID': item.cost_centre_id}})
for item in voucher.salary_deductions: for item in voucher.salary_deductions:
json_voucher['SalaryDeductions'].append( json_voucher['SalaryDeductions'].append(
{'GrossSalary': item.gross_salary, {'GrossSalary': item.gross_salary,
@@ -173,8 +179,16 @@ def voucher_info(voucher, request):
'Journal': {'JournalID': item.journal.id, 'Journal': {'JournalID': item.journal.id,
'Ledger': {'LedgerID': item.journal.ledger.id, 'Name': item.journal.ledger.name, 'Ledger': {'LedgerID': item.journal.ledger.id, 'Name': item.journal.ledger.name,
'Designation': item.journal.ledger.designation, 'Designation': item.journal.ledger.designation,
'CostCenter': {'CostCenterID': item.journal.ledger.costcenter.id, 'CostCentre': {'CostCentreID': item.journal.ledger.cost_centre.id,
'Name': item.journal.ledger.costcenter.name}}}}) 'Name': item.journal.ledger.cost_centre.name}}}})
for item in voucher.service_charges:
json_voucher['ServiceCharges'].append(
{'EmployeeID': item.journal.ledger_id, 'Name': item.journal.ledger.name,
'Designation': Employee.by_id(item.journal.ledger_id).designation,
'Department': item.journal.ledger.cost_centre.name, 'DaysWorked': item.days_worked, 'Points': item.points})
if len(json_voucher['ServiceCharges']) > 0:
json_voucher['ServiceCharge'] = [x.amount for x in voucher.journals if
x.ledger_id == Ledger.service_charge_id()][0]
for item in voucher.inventories: for item in voucher.inventories:
text = "{0} ({1}) {2:.2f}@{3:.2f} from {4}".format(item.product.name, item.product.units, text = "{0} ({1}) {2:.2f}@{3:.2f} from {4}".format(item.product.name, item.product.units,
item.batch.quantity_remaining, item.batch.rate, item.batch.quantity_remaining, item.batch.rate,
@@ -233,36 +247,68 @@ def blank_voucher(info):
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()}, json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
'Amount': 0, 'Amount': 0,
'Debit': -1, 'Debit': -1,
'CostCenter': {'CostCenterID': info['Source']}}) 'CostCentre': {'CostCentreID': info['Source']}})
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()}, json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
'Amount': 0, 'Amount': 0,
'Debit': 1, 'Debit': 1,
'CostCenter': {'CostCenterID': info['Destination']}}) 'CostCentre': {'CostCentreID': info['Destination']}})
elif 'Journals' not in info: elif 'Journals' not in info:
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()}, json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
'Amount': 0, 'Amount': 0,
'Debit': -1, 'Debit': -1,
'CostCenter': {'CostCenterID': CostCenter.cost_center_purchase()}}) 'CostCentre': {'CostCentreID': CostCentre.cost_centre_purchase()}})
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()}, json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
'Amount': 0, 'Amount': 0,
'Debit': 1, 'Debit': 1,
'CostCenter': {'CostCenterID': CostCenter.cost_center_kitchen()}}) 'CostCentre': {'CostCentreID': CostCentre.cost_centre_kitchen()}})
else: else:
json_voucher['Date'] = info['Date'] json_voucher['Date'] = info['Date']
for item in info['Journals']: for item in info['Journals']:
json_voucher['Journals'].append({'Ledger': {'LedgerID': item['Ledger']['LedgerID']}, json_voucher['Journals'].append({'Ledger': {'LedgerID': item['Ledger']['LedgerID']},
'Amount': 0, 'Amount': 0,
'Debit': item['Debit'], 'Debit': item['Debit'],
'CostCenter': {'CostCenterID': item['CostCenter']['CostCenterID']}}) 'CostCentre': {'CostCentreID': item['CostCentre']['CostCentreID']}})
elif type == 'Salary Deduction': elif type == 'Salary Deduction':
json_voucher['SalaryDeductions'] = [] json_voucher['SalaryDeductions'] = []
elif type == 'Service Charge':
json_voucher['ServiceCharges'], json_voucher['ServiceCharge'] = service_charge_employees(info['Date'])
else: else:
raise ValidationError("Voucher of type \"{0}\" does not exist.".format(type)) raise ValidationError("Voucher of type \"{0}\" does not exist.".format(type))
json_voucher['Files'] = [] json_voucher['Files'] = []
return json_voucher return json_voucher
def service_charge_employees(date):
date = datetime.datetime.strptime(date, '%d-%b-%Y')
start_date = get_first_day(date)
finish_date = date + datetime.timedelta(1)
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()
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({'EmployeeID': employee.id, 'Name': employee.name, 'Designation': employee.designation,
'Department': employee.cost_centre.name, 'DaysWorked': att, 'Points': employee.service_points})
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.ledger_id == Ledger.service_charge_id()) \
.scalar()
amount = 0 if amount is None else amount * Decimal(.7) * Decimal(.9) * -1
return details, amount
def get_edit_url(request, voucher): def get_edit_url(request, voucher):
if voucher.type == 1: if voucher.type == 1:
return request.route_url('journal_id', id=voucher.id) return request.route_url('journal_id', id=voucher.id)
@@ -278,5 +324,7 @@ def get_edit_url(request, voucher):
return request.route_url('purchase_return_id', id=voucher.id) return request.route_url('purchase_return_id', id=voucher.id)
elif voucher.type == 12: elif voucher.type == 12:
return request.route_url('salary_deduction_id', id=voucher.id) return request.route_url('salary_deduction_id', id=voucher.id)
elif voucher.type == 13:
return request.route_url('service_charge_id', id=voucher.id)
else: else:
return '#' return '#'
@@ -1,10 +1,11 @@
import calendar import calendar
import datetime import datetime
import uuid import uuid
from pyramid.security import authenticated_userid
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import or_ from sqlalchemy import or_
import transaction import transaction
from ....models import DBSession from ....models import DBSession
from ....models.auth import User from ....models.auth import User
from ....models.master import Employee, AttendanceType, Ledger from ....models.master import Employee, AttendanceType, Ledger
@@ -12,13 +13,14 @@ from ....models.validation_exception import TryCatchFunction
from ....models.voucher import Voucher, VoucherType, Attendance, Journal from ....models.voucher import Voucher, VoucherType, Attendance, Journal
from ..session import get_first_day, get_last_day from ..session import get_first_day, get_last_day
__author__ = 'tanshu' __author__ = 'tanshu'
@view_config(request_method='POST', route_name='api_credit_salary', renderer='json', permission='Attendance') @view_config(request_method='POST', route_name='api_credit_salary', renderer='json', permission='Attendance')
@TryCatchFunction @TryCatchFunction
def credit_salary(request): def credit_salary(request):
user = User.by_id(uuid.UUID(authenticated_userid(request))) user = User.by_id(uuid.UUID(request.authenticated_userid))
month = datetime.datetime.strptime(request.json_body['Month'], '%d-%b-%Y') month = datetime.datetime.strptime(request.json_body['Month'], '%d-%b-%Y')
start_date = get_first_day(month) start_date = get_first_day(month)
@@ -41,7 +43,7 @@ def salary_journals(start_date, finish_date):
employees = DBSession().query(Employee) \ employees = DBSession().query(Employee) \
.filter(Employee.joining_date <= finish_date) \ .filter(Employee.joining_date <= finish_date) \
.filter(or_(Employee.is_active, Employee.leaving_date >= start_date)) \ .filter(or_(Employee.is_active, Employee.leaving_date >= start_date)) \
.order_by(Employee.costcenter_id).order_by(Employee.designation).order_by(Employee.name).all() .order_by(Employee.cost_centre_id).order_by(Employee.designation).order_by(Employee.name).all()
for employee in employees: for employee in employees:
att = DBSession.query(Attendance) \ att = DBSession.query(Attendance) \
.filter(Attendance.employee_id == employee.id) \ .filter(Attendance.employee_id == employee.id) \
@@ -53,9 +55,10 @@ def salary_journals(start_date, finish_date):
att = round(att * employee.salary / days) att = round(att * employee.salary / days)
if att != 0: if att != 0:
amount += att amount += att
journals.append(Journal(amount=att, debit=-1, ledger_id=employee.id, cost_center_id=employee.costcenter_id)) journals.append(
Journal(amount=att, debit=-1, ledger_id=employee.id, cost_centre_id=employee.cost_centre_id))
salary = Ledger.salary() salary = Ledger.salary()
salary = Ledger.by_id(uuid.UUID(salary['LedgerID'])) salary = Ledger.by_id(uuid.UUID(salary['LedgerID']))
journals.append(Journal(amount=amount, debit=1, ledger_id=salary.id, cost_center_id=salary.costcenter_id)) journals.append(Journal(amount=amount, debit=1, ledger_id=salary.id, cost_centre_id=salary.cost_centre_id))
return journals return journals
@@ -1,83 +0,0 @@
import datetime
import uuid
from decimal import Decimal
from pyramid.security import authenticated_userid
from pyramid.view import view_config
from sqlalchemy import or_, func
import transaction
from ....models import DBSession
from ....models.auth import User
from ....models.master import Employee, AttendanceType, Ledger
from ....models.validation_exception import TryCatchFunction
from ....models.voucher import Voucher, VoucherType, Attendance, Journal
from ..session import get_first_day, get_last_day
__author__ = 'tanshu'
@view_config(request_method='POST', route_name='api_credit_service_charge', renderer='json', permission='Attendance')
@TryCatchFunction
def credit_sc(request):
user = User.by_id(uuid.UUID(authenticated_userid(request)))
month = datetime.datetime.strptime(request.json_body['Month'], '%d-%b-%Y')
credit_date = datetime.datetime.strptime(request.json_body['CreditDate'], '%d-%b-%Y')
amount = balance(month)
start_date = get_first_day(month)
finish_date = get_last_day(month)
voucher = Voucher(date=credit_date, narration='Auto Generated Service Charge Entry', user_id=user.id,
type=VoucherType.by_name('Journal'), posted=True, poster_id=user.id)
DBSession.add(voucher)
for item in service_charge_journals(amount, start_date, finish_date):
voucher.journals.append(item)
DBSession.add(item)
transaction.commit()
return {'message': 'Salary Entry created'}
def service_charge_journals(amount, start_date, finish_date):
amount = amount * Decimal(.7) * Decimal(.9)
total_points = 0
details = []
finish_date = finish_date + datetime.timedelta(1)
journals = []
employees = DBSession().query(Employee) \
.filter(Employee.joining_date <= finish_date) \
.filter(or_(Employee.is_active, Employee.leaving_date >= start_date)) \
.order_by(Employee.costcenter_id).order_by(Employee.designation).order_by(Employee.name).all()
for employee in employees:
if employee.service_points != 0:
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))
points = Decimal(att) * employee.service_points
if points != 0:
total_points += points
details.append({'Employee': employee, 'Points': points})
if total_points == 0:
raise ValueError("There is no data to credit service charges")
point_value = round(amount / total_points, 2)
amount = 0
for item in details:
ee = item['Employee']
employee_amount = round(point_value * item['Points'])
journal = Journal(amount=employee_amount, debit=-1, ledger_id=ee.id, cost_center_id=ee.costcenter_id)
journals.append(journal)
amount += employee_amount
sc = Ledger.by_id(uuid.UUID(Ledger.service_charge()['LedgerID']))
journals.append(Journal(amount=amount, debit=1, ledger_id=sc.id, cost_center_id=sc.costcenter_id))
return journals
def balance(date):
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.ledger_id == uuid.UUID(Ledger.service_charge()['LedgerID'])) \
.scalar()
return 0 if amount is None else amount * -1
@@ -53,6 +53,15 @@ class blank_voucher_view(object):
else: else:
return self.get_blank() return self.get_blank()
@view_config(request_param='type=Service Charge', permission='Service Charge')
def service_charge(self):
voucher_type = self.request.GET.get('type', None)
date = self.request.GET.get('Date', None)
if date is not None :
return blank_voucher({'Type': voucher_type, 'Date': date})
else:
return self.get_blank()
def get_blank(self, additional_info=None): def get_blank(self, additional_info=None):
voucher_type = self.request.GET.get('type', None) voucher_type = self.request.GET.get('type', None)
if additional_info is None: if additional_info is None:
+15 -15
View File
@@ -2,7 +2,7 @@ import datetime
from decimal import Decimal from decimal import Decimal
import uuid import uuid
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import CostCenter, LedgerBase from brewman.models.master import CostCentre, LedgerBase
from brewman.models.operations import journals_valid, inventory_valid from brewman.models.operations import journals_valid, inventory_valid
from brewman.models.validation_exception import ValidationError from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journal from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journal
@@ -17,12 +17,12 @@ def issue_create_voucher(json, user):
for item in json['Journals']: for item in json['Journals']:
if int(item['Debit']) == 1: if int(item['Debit']) == 1:
destination = uuid.UUID(item['CostCenter']['CostCenterID']) destination = uuid.UUID(item['CostCentre']['CostCentreID'])
else: else:
source = uuid.UUID(item['CostCenter']['CostCenterID']) source = uuid.UUID(item['CostCentre']['CostCentreID'])
if source == destination: if source == destination:
raise ValidationError("Source cannot be the same as destination") raise ValidationError("Source cannot be the same as destination")
batch_consumed = True if source == CostCenter.cost_center_purchase() else False if destination == CostCenter.cost_center_purchase() else None batch_consumed = True if source == CostCentre.cost_centre_purchase() else False if destination == CostCentre.cost_centre_purchase() else None
for item in json['Inventories']: for item in json['Inventories']:
issue_create_inventory(voucher, item, batch_consumed) issue_create_inventory(voucher, item, batch_consumed)
for item in issue_create_journals(voucher.inventories, source, destination): for item in issue_create_journals(voucher.inventories, source, destination):
@@ -62,9 +62,9 @@ def issue_create_journals(inventories, source, destination):
for item in inventories: for item in inventories:
amount += item.amount amount += item.amount
return [Journal(debit=-1, ledger_id=LedgerBase.all_purchases(), amount=round(amount, 2), return [Journal(debit=-1, ledger_id=LedgerBase.all_purchases(), amount=round(amount, 2),
cost_center_id=source), cost_centre_id=source),
Journal(debit=1, ledger_id=LedgerBase.all_purchases(), amount=round(amount, 2), Journal(debit=1, ledger_id=LedgerBase.all_purchases(), amount=round(amount, 2),
cost_center_id=destination)] cost_centre_id=destination)]
def issue_update_voucher(voucher, json, user): def issue_update_voucher(voucher, json, user):
@@ -75,22 +75,22 @@ def issue_update_voucher(voucher, json, user):
for item in voucher.journals: for item in voucher.journals:
if item.debit == 1: if item.debit == 1:
destination = item.cost_center_id destination = item.cost_centre_id
else: else:
source = item.cost_center_id source = item.cost_centre_id
old_batch_consumed = True if source == CostCenter.cost_center_purchase() else False if destination == CostCenter.cost_center_purchase() else None old_batch_consumed = True if source == CostCentre.cost_centre_purchase() else False if destination == CostCentre.cost_centre_purchase() else None
for item in json['Journals']: for item in json['Journals']:
if int(item['Debit']) == 1: if int(item['Debit']) == 1:
destination = uuid.UUID(item['CostCenter']['CostCenterID']) destination = uuid.UUID(item['CostCentre']['CostCentreID'])
else: else:
source = uuid.UUID(item['CostCenter']['CostCenterID']) source = uuid.UUID(item['CostCentre']['CostCentreID'])
if source == destination: if source == destination:
raise ValidationError("Source cannot be the same as destination") raise ValidationError("Source cannot be the same as destination")
new_batch_consumed = True if source == CostCenter.cost_center_purchase() else False if destination == CostCenter.cost_center_purchase() else None new_batch_consumed = True if source == CostCentre.cost_centre_purchase() else False if destination == CostCentre.cost_centre_purchase() else None
if new_batch_consumed != old_batch_consumed: if new_batch_consumed != old_batch_consumed:
raise ValidationError("Purchase cost center cannot be changed") raise ValidationError("Purchase cost centre cannot be changed")
issue_update_inventory(voucher, json['Inventories'], old_batch_consumed) issue_update_inventory(voucher, json['Inventories'], old_batch_consumed)
issue_update_journals(voucher, source, destination) issue_update_journals(voucher, source, destination)
@@ -160,10 +160,10 @@ def issue_update_journals(voucher, source, destination):
for i in range(len(voucher.journals), 0, -1): for i in range(len(voucher.journals), 0, -1):
item = voucher.journals[i - 1] item = voucher.journals[i - 1]
if item.debit == -1: if item.debit == -1:
item.cost_center_id = source item.cost_centre_id = source
item.amount = round(amount, 2) item.amount = round(amount, 2)
else: else:
item.cost_center_id = destination item.cost_centre_id = destination
item.amount = round(amount, 2) item.amount = round(amount, 2)
+3 -3
View File
@@ -20,7 +20,7 @@ def journal_create_voucher(json, files, user):
journal_id = uuid.UUID(item['JournalID']) if 'JournalID' in item else None journal_id = uuid.UUID(item['JournalID']) if 'JournalID' in item else None
amount = round(Decimal(item['Amount']), 2) amount = round(Decimal(item['Amount']), 2)
journal = Journal(id=journal_id, amount=amount, debit=int(item['Debit']), ledger_id=ledger.id, journal = Journal(id=journal_id, amount=amount, debit=int(item['Debit']), ledger_id=ledger.id,
cost_center_id=ledger.costcenter_id) cost_centre_id=ledger.cost_centre_id)
voucher.journals.append(journal) voucher.journals.append(journal)
DBSession.add(journal) DBSession.add(journal)
journals_valid(voucher) journals_valid(voucher)
@@ -48,7 +48,7 @@ def journal_update_voucher(voucher, json, files, user):
item.debit = int(j['Debit']) item.debit = int(j['Debit'])
item.amount = round(Decimal(j['Amount']), 2) item.amount = round(Decimal(j['Amount']), 2)
item.ledger_id = ledger.id item.ledger_id = ledger.id
item.cost_center_id = ledger.costcenter_id item.cost_centre_id = ledger.cost_centre_id
newJournals.remove(j) newJournals.remove(j)
break break
if not found: if not found:
@@ -56,7 +56,7 @@ def journal_update_voucher(voucher, json, files, user):
for j in newJournals: for j in newJournals:
ledger = LedgerBase.by_id(uuid.UUID(j['Ledger']['LedgerID'])) ledger = LedgerBase.by_id(uuid.UUID(j['Ledger']['LedgerID']))
journal = Journal(id=None, amount=round(Decimal(j['Amount']), 2), debit=int(j['Debit']), ledger_id=ledger.id, journal = Journal(id=None, amount=round(Decimal(j['Amount']), 2), debit=int(j['Debit']), ledger_id=ledger.id,
cost_center_id=ledger.costcenter_id) cost_centre_id=ledger.cost_centre_id)
DBSession.add(journal) DBSession.add(journal)
voucher.journals.append(journal) voucher.journals.append(journal)
journals_valid(voucher) journals_valid(voucher)
+5 -5
View File
@@ -63,9 +63,9 @@ def purchase_create_journals(inventories, ledgerID):
if ledger.id in journals: if ledger.id in journals:
journals[ledger.id].amount += item_amount journals[ledger.id].amount += item_amount
else: else:
journals[ledger.id] = Journal(debit=1, cost_center_id=ledger.costcenter_id, ledger_id=ledger.id, journals[ledger.id] = Journal(debit=1, cost_centre_id=ledger.cost_centre_id, ledger_id=ledger.id,
amount=item_amount) amount=item_amount)
journals[otherLedger.id] = Journal(debit=-1, cost_center_id=otherLedger.costcenter_id, ledger_id=otherLedger.id, journals[otherLedger.id] = Journal(debit=-1, cost_centre_id=otherLedger.cost_centre_id, ledger_id=otherLedger.id,
amount=amount) amount=amount)
return list(journals.values()) return list(journals.values())
@@ -168,16 +168,16 @@ def purchase_update_journals(voucher, journals):
if ledger.id in journals: if ledger.id in journals:
journals[ledger.id].amount += item.amount journals[ledger.id].amount += item.amount
else: else:
journals[ledger.id] = Journal(debit=1, cost_center_id=ledger.costcenter_id, ledger_id=ledger.id, journals[ledger.id] = Journal(debit=1, cost_centre_id=ledger.cost_centre_id, ledger_id=ledger.id,
amount=item.amount) amount=item.amount)
journals[other_ledger.id] = Journal(debit=-1, cost_center_id=other_ledger.costcenter_id, ledger_id=other_ledger.id, journals[other_ledger.id] = Journal(debit=-1, cost_centre_id=other_ledger.cost_centre_id, ledger_id=other_ledger.id,
amount=amount) amount=amount)
for i in range(len(voucher.journals), 0, -1): for i in range(len(voucher.journals), 0, -1):
item = voucher.journals[i - 1] item = voucher.journals[i - 1]
if item.ledger_id in journals: if item.ledger_id in journals:
item.debit = journals[item.ledger_id].debit item.debit = journals[item.ledger_id].debit
item.amount = round(journals[item.ledger_id].amount, 2) item.amount = round(journals[item.ledger_id].amount, 2)
item.cost_center_id = journals[item.ledger_id].cost_center_id item.cost_centre_id = journals[item.ledger_id].cost_centre_id
del journals[item.ledger_id] del journals[item.ledger_id]
else: else:
DBSession.delete(item) DBSession.delete(item)
@@ -57,9 +57,9 @@ def purchase_return_create_journals(inventories, ledgerID):
if ledger.id in journals: if ledger.id in journals:
journals[ledger.id].amount += round(item.amount, 2) journals[ledger.id].amount += round(item.amount, 2)
else: else:
journals[ledger.id] = Journal(debit=-1, cost_center_id=ledger.costcenter_id, ledger_id=ledger.id, journals[ledger.id] = Journal(debit=-1, cost_centre_id=ledger.cost_centre_id, ledger_id=ledger.id,
amount=round(item.amount, 2)) amount=round(item.amount, 2))
journals[otherLedger.id] = Journal(debit=1, cost_center_id=otherLedger.costcenter_id, ledger_id=otherLedger.id, journals[otherLedger.id] = Journal(debit=1, cost_centre_id=otherLedger.cost_centre_id, ledger_id=otherLedger.id,
amount=amount) amount=amount)
return list(journals.values()) return list(journals.values())
@@ -126,16 +126,16 @@ def purchase_return_update_journals(voucher, journals):
if ledger.id in journals: if ledger.id in journals:
journals[ledger.id].amount += round(item.amount, 2) journals[ledger.id].amount += round(item.amount, 2)
else: else:
journals[ledger.id] = Journal(debit=-1, cost_center_id=ledger.costcenter_id, ledger_id=ledger.id, journals[ledger.id] = Journal(debit=-1, cost_centre_id=ledger.cost_centre_id, ledger_id=ledger.id,
amount=round(item.amount, 2)) amount=round(item.amount, 2))
journals[otherLedger.id] = Journal(debit=1, cost_center_id=otherLedger.costcenter_id, ledger_id=otherLedger.id, journals[otherLedger.id] = Journal(debit=1, cost_centre_id=otherLedger.cost_centre_id, ledger_id=otherLedger.id,
amount=amount) amount=amount)
for i in range(len(voucher.journals), 0, -1): for i in range(len(voucher.journals), 0, -1):
item = voucher.journals[i - 1] item = voucher.journals[i - 1]
if item.ledger_id in journals: if item.ledger_id in journals:
item.debit = journals[item.ledger_id].debit item.debit = journals[item.ledger_id].debit
item.amount = journals[item.ledger_id].amount item.amount = journals[item.ledger_id].amount
item.cost_center_id = journals[item.ledger_id].cost_center_id item.cost_centre_id = journals[item.ledger_id].cost_centre_id
del journals[item.ledger_id] del journals[item.ledger_id]
else: else:
DBSession.delete(item) DBSession.delete(item)
@@ -22,11 +22,11 @@ def salary_deduction_create_voucher(json, user):
exp += item_exp exp += item_exp
total += item_total total += item_total
ledger = LedgerBase.by_id(LedgerBase.esi_pf_expense()) ledger = LedgerBase.by_id(LedgerBase.esi_pf_expense())
journal = Journal(amount=exp, debit=1, ledger_id=ledger.id, cost_center_id=ledger.costcenter_id) journal = Journal(amount=exp, debit=1, ledger_id=ledger.id, cost_centre_id=ledger.cost_centre_id)
DBSession.add(journal) DBSession.add(journal)
voucher.journals.append(journal) voucher.journals.append(journal)
ledger = LedgerBase.by_id(LedgerBase.esi_pf_payable()) ledger = LedgerBase.by_id(LedgerBase.esi_pf_payable())
journal = Journal(amount=total, debit=-1, ledger_id=ledger.id, cost_center_id=ledger.costcenter_id) journal = Journal(amount=total, debit=-1, ledger_id=ledger.id, cost_centre_id=ledger.cost_centre_id)
DBSession.add(journal) DBSession.add(journal)
voucher.journals.append(journal) voucher.journals.append(journal)
@@ -81,7 +81,7 @@ def add_salary_deduction(item, days_in_month, voucher):
days_worked = int(item['DaysWorked']) days_worked = int(item['DaysWorked'])
esi_ee, esi_er, esi_both = esi_contribution(gross_salary, days_worked, days_in_month) esi_ee, esi_er, esi_both = esi_contribution(gross_salary, days_worked, days_in_month)
pf_ee, pf_er, pf_both = pf_contribution(gross_salary, days_worked, days_in_month) pf_ee, pf_er, pf_both = pf_contribution(gross_salary, days_worked, days_in_month)
journal = Journal(amount=esi_ee + pf_ee, debit=1, ledger_id=ledger.id, cost_center_id=ledger.costcenter_id) journal = Journal(amount=esi_ee + pf_ee, debit=1, ledger_id=ledger.id, cost_centre_id=ledger.cost_centre_id)
sd = SalaryDeduction(journal=journal, gross_salary=gross_salary, days_worked=days_worked, esi_ee=esi_ee, sd = SalaryDeduction(journal=journal, gross_salary=gross_salary, days_worked=days_worked, esi_ee=esi_ee,
pf_ee=pf_ee, esi_er=esi_er, pf_er=pf_er) pf_ee=pf_ee, esi_er=esi_er, pf_er=pf_er)
voucher.journals.append(journal) voucher.journals.append(journal)
@@ -2,7 +2,6 @@ import uuid
from json import loads from json import loads
import datetime import datetime
from pyramid.security import authenticated_userid
from pyramid.view import view_defaults, view_config from pyramid.view import view_defaults, view_config
import transaction import transaction
@@ -12,6 +11,7 @@ from brewman.models.voucher import Voucher
from brewman.views import get_lock_info from brewman.views import get_lock_info
from brewman.views.services.session import session_current_date_set from brewman.views.services.session import session_current_date_set
from . import voucher_info, journal_create_voucher, purchase_create_voucher, issue_create_voucher from . import voucher_info, journal_create_voucher, purchase_create_voucher, issue_create_voucher
from . import service_charge_create_voucher
from .purchase_return import purchase_return_create_voucher from .purchase_return import purchase_return_create_voucher
from .salary_deduction import salary_deduction_create_voucher from .salary_deduction import salary_deduction_create_voucher
@@ -38,7 +38,7 @@ class save_voucher(object):
return model, files return model, files
self.request = request self.request = request
self.user = User.by_id(uuid.UUID(authenticated_userid(request))) self.user = User.by_id(uuid.UUID(request.authenticated_userid))
self.json, self.files = parse_post(request) self.json, self.files = parse_post(request)
self.start, self.finish = get_lock_info() self.start, self.finish = get_lock_info()
self.voucher_date = datetime.datetime.strptime(self.json['Date'], '%d-%b-%Y') self.voucher_date = datetime.datetime.strptime(self.json['Date'], '%d-%b-%Y')
@@ -77,6 +77,10 @@ class save_voucher(object):
def salary_deduction(self): def salary_deduction(self):
return self.save() return self.save()
@view_config(request_param='type=Service Charge', permission='Service Charge')
def salary_deduction(self):
return self.save()
@TryCatchFunction @TryCatchFunction
def save(self): def save(self):
if self.start is not None and self.start > self.voucher_date: if self.start is not None and self.start > self.voucher_date:
@@ -94,6 +98,8 @@ class save_voucher(object):
voucher = issue_create_voucher(self.json, self.user) voucher = issue_create_voucher(self.json, self.user)
elif self.json['Type'] in ['Salary Deduction']: elif self.json['Type'] in ['Salary Deduction']:
voucher = salary_deduction_create_voucher(self.json, self.user) voucher = salary_deduction_create_voucher(self.json, self.user)
elif self.json['Type'] in ['Service Charge']:
voucher = service_charge_create_voucher(self.json, self.user)
transaction.commit() transaction.commit()
session_current_date_set(self.request, self.json['Date']) session_current_date_set(self.request, self.json['Date'])
return voucher_info(Voucher.by_id(voucher.id), self.request) return voucher_info(Voucher.by_id(voucher.id), self.request)
@@ -0,0 +1,132 @@
import datetime
from decimal import Decimal
import uuid
from sqlalchemy import or_, func
from brewman.models import DBSession
from brewman.models.master import Employee, AttendanceType, Ledger
from brewman.models.operations import journals_valid
from brewman.models.voucher import Journal, Voucher, VoucherType, Attendance, ServiceCharge
from brewman.views.services.session import get_first_day
__author__ = 'tanshu'
def service_charge_create_voucher(json, user):
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['ServiceCharges'])
amount = balance(date) * Decimal(.7) * Decimal(.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, ledger_id=employee.id, cost_centre_id=employee.cost_centre_id)
sc = ServiceCharge(journal=journal, days_worked=item['DaysWorked'], points=item['Points'])
voucher.journals.append(journal)
voucher.service_charges.append(sc)
DBSession.add(journal)
DBSession.add(sc)
total_amount += item_amount
sc = Ledger.by_id(Ledger.service_charge_id())
journal = Journal(amount=total_amount, debit=1, ledger_id=sc.id, cost_centre_id=sc.cost_centre_id)
voucher.journals.append(journal)
DBSession.add(journal)
journals_valid(voucher)
return voucher
def service_charge_update_voucher(voucher, json, user):
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['ServiceCharges'], voucher.journals)
amount = balance(date, voucher.id) * Decimal(.7) * Decimal(.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.service_charges:
employee = [e for e in employees if e['Employee'].id == item.journal.ledger_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.ledger_id == Ledger.service_charge_id()][0]
journal.amount = total_amount
journals_valid(voucher)
return voucher
def get_employees(start_date, finish_date, json, voucher_employees=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['EmployeeID']) == item['Employee'].id][0]
item['Points'] = round(Decimal(j['Points']), 2)
json.remove(j)
return details
def balance(date, voucher_id=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.ledger_id == Ledger.service_charge_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['EmployeeID']) for x in json])
db = set([x.id for x in db])
voucher = set([x.ledger_id for x in voucher]) if voucher is not None else None
if voucher is None:
if len(json) != len(db):
raise ValueError("Employee missing in json data")
if len(json ^ db) != 0:
raise ValueError("Employee missing in json data")
else:
if len(json) != len(db) != len(voucher):
raise ValueError("Employee missing in json data")
if len(json ^ db) != 0 or len(db ^ voucher) != 0:
raise ValueError("Employee missing in json data")
@@ -1,20 +1,23 @@
import datetime import datetime
from json import loads from json import loads
import uuid import uuid
from pyramid.response import Response from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.view import view_defaults, view_config from pyramid.view import view_defaults, view_config
import transaction import transaction
from brewman import groupfinder from brewman import groupfinder
from brewman.models.auth import User from brewman.models.auth import User
from brewman.models.validation_exception import ValidationError, TryCatchFunction from brewman.models.validation_exception import TryCatchFunction
from brewman.models.voucher import Voucher from brewman.models.voucher import Voucher
from brewman.views import get_lock_info from brewman.views import get_lock_info
from brewman.views.services.session import session_current_date_set from brewman.views.services.session import session_current_date_set
from . import voucher_info, issue_update_voucher, purchase_update_voucher, journal_update_voucher from . import voucher_info, issue_update_voucher, purchase_update_voucher, journal_update_voucher
from . import service_charge_update_voucher
from brewman.views.services.voucher.purchase_return import purchase_return_update_voucher from brewman.views.services.voucher.purchase_return import purchase_return_update_voucher
from brewman.views.services.voucher.salary_deduction import salary_deduction_update_voucher from brewman.views.services.voucher.salary_deduction import salary_deduction_update_voucher
__author__ = 'tanshu' __author__ = 'tanshu'
@@ -37,13 +40,12 @@ class update_voucher(object):
return model, files return model, files
self.request = request self.request = request
self.user = User.by_id(uuid.UUID(authenticated_userid(request))) self.user = User.by_id(uuid.UUID(request.authenticated_userid))
self.voucher = Voucher.by_id(uuid.UUID(request.matchdict.get('id', None))) self.voucher = Voucher.by_id(uuid.UUID(request.matchdict.get('id', None)))
self.json, self.files = parse_post(request) self.json, self.files = parse_post(request)
self.start, self.finish = get_lock_info() self.start, self.finish = get_lock_info()
self.voucher_date = datetime.datetime.strptime(self.json['Date'], '%d-%b-%Y') self.voucher_date = datetime.datetime.strptime(self.json['Date'], '%d-%b-%Y')
permissions = groupfinder(self.user.id, self.request) permissions = groupfinder(self.user.id, self.request)
if self.voucher.posted and not 'Edit Posted Vouchers' in permissions: if self.voucher.posted and not 'Edit Posted Vouchers' in permissions:
response = Response("You are not allowed to edit posted vouchers") response = Response("You are not allowed to edit posted vouchers")
@@ -98,6 +100,10 @@ class update_voucher(object):
def salary_deduction(self): def salary_deduction(self):
return self.update() return self.update()
@view_config(request_param='type=Service Charge', permission='Service Charge')
def service_charge(self):
return self.update()
@TryCatchFunction @TryCatchFunction
def update(self): def update(self):
if self.error is not None: if self.error is not None:
@@ -112,6 +118,8 @@ class update_voucher(object):
voucher = issue_update_voucher(self.voucher, self.json, self.user) voucher = issue_update_voucher(self.voucher, self.json, self.user)
elif self.json['Type'] in ['Salary Deduction']: elif self.json['Type'] in ['Salary Deduction']:
voucher = salary_deduction_update_voucher(self.voucher, self.json, self.user) voucher = salary_deduction_update_voucher(self.voucher, self.json, self.user)
elif self.json['Type'] in ['Service Charge']:
voucher = service_charge_update_voucher(self.voucher, self.json, self.user)
transaction.commit() transaction.commit()
session_current_date_set(self.request, self.json['Date']) session_current_date_set(self.request, self.json['Date'])
return voucher_info(Voucher.by_id(voucher.id), self.request) return voucher_info(Voucher.by_id(voucher.id), self.request)