diff --git a/brewman/models/__init__.py b/brewman/models/__init__.py index d526f7ae..5bff5d17 100644 --- a/brewman/models/__init__.py +++ b/brewman/models/__init__.py @@ -9,9 +9,9 @@ from .voucher import Attendance, Batch, Fingerprint, Inventory, Journal, Product from .master import (Product, AttendanceType, CostCentre, Employee, - Ledger, - LedgerBase, - LedgerType, + Account, + AccountBase, + AccountType, ProductGroup, Recipe, RecipeItem diff --git a/brewman/models/master.py b/brewman/models/master.py index 346ad01a..8ad8fb34 100644 --- a/brewman/models/master.py +++ b/brewman/models/master.py @@ -33,7 +33,7 @@ class Product(Base): product_yield = Column('ProductYield', Numeric, nullable=False) product_group_id = Column('ProductGroupID', GUID(), ForeignKey('product_groups.ProductGroupID'), nullable=False) - ledger_id = Column('LedgerID', GUID(), ForeignKey('ledgers.LedgerID'), nullable=False) + account_id = Column('account_id', GUID(), ForeignKey('accounts.id'), nullable=False) price = Column('cost_price', Numeric, nullable=False) sale_price = Column('sale_price', Numeric, nullable=False) is_active = Column('IsActive', Boolean, nullable=False) @@ -44,10 +44,10 @@ class Product(Base): batches = relationship('Batch', backref='product') inventories = relationship('Inventory', backref='product') recipes = relationship('Recipe', backref='product') - ledger = relationship('Ledger', primaryjoin="Ledger.id==Product.ledger_id", backref='products') + account = relationship('Account', primaryjoin="Account.id==Product.account_id", backref='products') def __init__(self, code=None, name=None, units=None, fraction=None, fraction_units=None, product_yield=None, - product_group_id=None, ledger_id=None, price=None, sale_price=None, is_active=None, is_purchased=None, + product_group_id=None, account_id=None, price=None, sale_price=None, is_active=None, is_purchased=None, is_sold=None, id=None, is_fixture=False): self.code = code self.name = name @@ -56,7 +56,7 @@ class Product(Base): self.fraction_units = fraction_units self.product_yield = product_yield self.product_group_id = product_group_id - self.ledger_id = ledger_id + self.account_id = account_id self.price = price self.sale_price = sale_price self.is_active = is_active @@ -175,7 +175,7 @@ class CostCentre(Base): name = Column('Name', Unicode(255), unique=True) is_fixture = Column('IsFixture', Boolean, nullable=False) - ledgers = relationship('LedgerBase', backref='cost_centre') + accounts = relationship('AccountBase', backref='cost_centre') journals = relationship('Journal', backref='cost_centre') @property @@ -204,22 +204,23 @@ class CostCentre(Base): return {'id': uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), 'name': 'Overall'} -class LedgerBase(Base): - __tablename__ = 'ledgers' +class AccountBase(Base): + __tablename__ = 'accounts' - id = Column('LedgerID', GUID(), primary_key=True, default=uuid.uuid4) - code = Column('Code', Integer) - name = Column('Name', Unicode(255), unique=True) - type = Column('Type', Integer, nullable=False) - ledger_type = Column('ledger_type', Unicode(50), nullable=False) - is_active = Column('IsActive', Boolean) - is_reconcilable = Column('IsReconcilable', Boolean) - cost_centre_id = Column('CostCentreID', GUID(), ForeignKey('cost_centres.CostCentreID')) - is_fixture = Column('IsFixture', Boolean, nullable=False) + id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) + code = Column('code', Integer, nullable=False) + name = Column('name', Unicode(255), unique=True, nullable=False) + type = Column('type', Integer, nullable=False) + account_type = Column('account_type', Unicode(50), nullable=False) + is_starred = Column('is_starred', Boolean, nullable=False) + is_active = Column('is_active', Boolean, nullable=False) + is_reconcilable = Column('is_reconcilable', Boolean, nullable=False) + cost_centre_id = Column('cost_centre_id', GUID(), ForeignKey('cost_centres.CostCentreID'), nullable=False) + is_fixture = Column('is_fixture', Boolean, nullable=False) - __mapper_args__ = {'polymorphic_on': ledger_type} + __mapper_args__ = {'polymorphic_on': account_type} - journals = relationship('Journal', backref='ledger') + journals = relationship('Journal', backref='account') @property def __name__(self): @@ -227,13 +228,14 @@ class LedgerBase(Base): @property def type_object(self): - return LedgerType.by_id(self.type) + return AccountType.by_id(self.type) - def __init__(self, code=None, name=None, type=None, is_active=None, is_reconcilable=False, cost_centre_id=None, - id=None, is_fixture=False): + def __init__(self, code=None, name=None, type=None, is_starred=None, is_active=None, is_reconcilable=False, + cost_centre_id=None, id=None, is_fixture=False): self.code = code self.name = name self.type = type + self.is_starred = is_starred self.is_active = is_active self.is_reconcilable = is_reconcilable self.cost_centre_id = cost_centre_id @@ -257,7 +259,7 @@ class LedgerBase(Base): return query.order_by(cls.name) def create(self, dbsession): - code = dbsession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == self.type).one()[0] + code = dbsession.query(func.max(AccountBase.code)).filter(AccountBase.type == self.type).one()[0] if code is None: self.code = 1 else: @@ -276,7 +278,7 @@ class LedgerBase(Base): @classmethod def get_code(cls, type, dbsession): - code = dbsession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == type).one()[0] + code = dbsession.query(func.max(AccountBase.code)).filter(AccountBase.type == type).one()[0] return 1 if code is None else code + 1 @classmethod @@ -316,11 +318,11 @@ class LedgerBase(Base): return uuid.UUID('3854e317-6f3b-5142-ab26-9c44d4cddd08') -class Employee(LedgerBase): +class Employee(AccountBase): __tablename__ = 'employees' __mapper_args__ = {'polymorphic_identity': 'employees'} - id = Column('LedgerID', GUID(), ForeignKey(LedgerBase.id), primary_key=True) + id = Column('id', GUID(), ForeignKey(AccountBase.id), primary_key=True) designation = Column('Designation', Unicode(255)) salary = Column('Salary', Integer) service_points = Column('ServicePoints', Numeric(precision=5, scale=2)) @@ -341,7 +343,7 @@ class Employee(LedgerBase): cost_centre_id=cost_centre_id) def create(self, dbsession): - code = dbsession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == self.type).one()[0] + code = dbsession.query(func.max(AccountBase.code)).filter(AccountBase.type == self.type).one()[0] if code is None: self.code = 1 else: @@ -354,13 +356,13 @@ class Employee(LedgerBase): return super(Employee, self).can_delete(advanced_delete) -class Ledger(LedgerBase): +class Account(AccountBase): __mapper_args__ = {'polymorphic_identity': ''} def can_delete(self, advanced_delete): if len(self.products) > 0: return False, 'Account has products' - return super(Ledger, self).can_delete(advanced_delete) + return super(Account, self).can_delete(advanced_delete) class AttendanceType: @@ -393,7 +395,7 @@ class AttendanceType: return item -class LedgerType: +class AccountType: def __init__(self, id, name, balance_sheet=None, debit=None, cash_flow_classification=None, order=None, show_in_list=None): self.id = id @@ -411,21 +413,21 @@ class LedgerType: @classmethod def list(cls): - list = [LedgerType(1, 'Cash', True, True, 'Cash', 10, True), - LedgerType(2, 'Purchase', False, True, 'Operating', 20, True), - LedgerType(3, 'Sale', False, False, 'Operating', 10, True), - LedgerType(4, 'Assets', True, True, 'Investing', 20, True), - LedgerType(5, 'Capital', True, False, 'Financing', 70, True), - LedgerType(6, 'Debtors', True, True, 'Operating', 30, True), - LedgerType(7, 'Expenses', False, True, 'Operating', 40, True), - LedgerType(9, 'Creditors', True, False, 'Operating', 60, True), - LedgerType(10, 'Salary', True, True, 'Operating', 40, False), - LedgerType(11, 'Liabilities', True, False, 'Operating', 50, True), - LedgerType(12, 'Revenue', False, False, 'Operating', 30, True), - LedgerType(13, 'Tax', True, False, 'Operating', 80, True)] - # list.append(LedgerType(8, 'Discount', False, False, True, 30, True)) - # list.append(LedgerType(14, 'Total', False, False, False, 900, False)) - # list.append(LedgerType(15, 'Net', False, False, False, 1000, False)) + list = [AccountType(1, 'Cash', True, True, 'Cash', 10, True), + AccountType(2, 'Purchase', False, True, 'Operating', 20, True), + AccountType(3, 'Sale', False, False, 'Operating', 10, True), + AccountType(4, 'Assets', True, True, 'Investing', 20, True), + AccountType(5, 'Capital', True, False, 'Financing', 70, True), + AccountType(6, 'Debtors', True, True, 'Operating', 30, True), + AccountType(7, 'Expenses', False, True, 'Operating', 40, True), + AccountType(9, 'Creditors', True, False, 'Operating', 60, True), + AccountType(10, 'Salary', True, True, 'Operating', 40, False), + AccountType(11, 'Liabilities', True, False, 'Operating', 50, True), + AccountType(12, 'Revenue', False, False, 'Operating', 30, True), + AccountType(13, 'Tax', True, False, 'Operating', 80, True)] + # list.append(AccountType(8, 'Discount', False, False, True, 30, True)) + # list.append(AccountType(14, 'Total', False, False, False, 900, False)) + # list.append(AccountType(15, 'Net', False, False, False, 1000, False)) return list @classmethod diff --git a/brewman/models/operations.py b/brewman/models/operations.py index 213936a7..e9af80b0 100644 --- a/brewman/models/operations.py +++ b/brewman/models/operations.py @@ -151,7 +151,7 @@ def journals_valid(voucher): def is_distinct_journal(journals): found = set() for item in journals: - item_hash = hash(item.ledger_id) ^ hash(item.cost_centre_id) + item_hash = hash(item.account_id) ^ hash(item.cost_centre_id) if item_hash in found: raise ValidationError("Duplicate journals") else: diff --git a/brewman/models/voucher.py b/brewman/models/voucher.py index 20bec998..e903971c 100644 --- a/brewman/models/voucher.py +++ b/brewman/models/voucher.py @@ -1,14 +1,14 @@ -from datetime import datetime import uuid +from datetime import datetime +from sqlalchemy import Column, Integer, Boolean, Unicode, DateTime, Numeric, ForeignKey, UniqueConstraint from sqlalchemy.dialects.postgresql import BYTEA from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy import Column, Integer, Boolean, Unicode, DateTime, Numeric, ForeignKey, UniqueConstraint from sqlalchemy.orm import relationship, synonym, backref from brewman.models.guidtype import GUID -from .meta import Base from brewman.models.master import Product +from .meta import Base class VoucherType: @@ -20,7 +20,7 @@ class VoucherType: def list(cls): list = [VoucherType(1, 'Journal'), VoucherType(2, 'Purchase'), VoucherType(3, 'Issue'), VoucherType(4, 'Payment'), VoucherType(5, 'Receipt'), VoucherType(6, 'Purchase Return'), - VoucherType(7, 'Opening Ledgers'), VoucherType(8, 'Opening Batches'), VoucherType(9, 'Verification'), + VoucherType(7, 'Opening Accounts'), VoucherType(8, 'Opening Batches'), VoucherType(9, 'Verification'), VoucherType(10, 'Opening Balance'), VoucherType(11, 'Closing Balance'), VoucherType(12, 'Salary Deduction'), VoucherType(13, 'Service Charge')] return list @@ -44,16 +44,17 @@ class Voucher(Base): __tablename__ = 'vouchers' id = Column('VoucherID', GUID(), primary_key=True, default=uuid.uuid4) - date = Column('Date', DateTime, nullable=False, index=True) - reconcile_date = Column('ReconcileDate', DateTime, nullable=False) - is_reconciled = Column('IsReconciled', Boolean, nullable=False) - narration = Column('Narration', Unicode(1000), nullable=False) - posted = Column('Posted', Boolean, nullable=False) - creation_date = Column('CreationDate', DateTime(timezone=True), nullable=False) - last_edit_date = Column('LastEditDate', DateTime(timezone=True), nullable=False) - _type = Column('VoucherType', Integer, nullable=False) - user_id = Column('UserID', GUID(), ForeignKey('auth_users.UserID'), nullable=False) - poster_id = Column('PosterID', GUID(), ForeignKey('auth_users.UserID')) + date = Column('date', DateTime, nullable=False, index=True) + narration = Column('narration', Unicode(1000), nullable=False) + is_reconciled = Column('is_reconciled', Boolean, nullable=False) + reconcile_date = Column('reconcile_date', DateTime, nullable=False) + is_starred = Column('is_starred', Boolean, nullable=False) + creation_date = Column('creation_date', DateTime(timezone=True), nullable=False) + last_edit_date = Column('last_edit_date', DateTime(timezone=True), nullable=False) + _type = Column('voucher_type', Integer, nullable=False) + user_id = Column('user_id', GUID(), ForeignKey('auth_users.UserID'), nullable=False) + posted = Column('is_posted', Boolean, nullable=False) + poster_id = Column('poster_id', GUID(), ForeignKey('auth_users.UserID')) user = relationship('User', primaryjoin="User.id==Voucher.user_id", cascade=None) poster = relationship('User', primaryjoin="User.id==Voucher.poster_id", cascade=None) @@ -84,10 +85,12 @@ class Voucher(Base): def __name__(self): return self.name - def __init__(self, date=None, reconcile_date=None, narration='', posted=False, creation_date=None, - last_edit_date=None, type=None, user_id=None, poster_id=None, is_reconciled=False): + def __init__(self, date=None, is_reconciled=False, reconcile_date=None, is_starred=None, narration='', posted=False, + creation_date=None, last_edit_date=None, type=None, user_id=None, poster_id=None): self.date = date + self.is_reconciled = is_reconciled self.reconcile_date = reconcile_date if reconcile_date and is_reconciled else date + self.is_starred = is_starred if is_starred is not None else False self.narration = narration self.posted = posted self.creation_date = datetime.utcnow() if creation_date is None else creation_date @@ -95,7 +98,6 @@ class Voucher(Base): self.type = type self.user_id = user_id self.poster_id = poster_id - self.is_reconciled = is_reconciled class Journal(Base): @@ -105,7 +107,7 @@ class Journal(Base): debit = Column('Debit', Integer) amount = Column('Amount', Numeric) voucher_id = Column('VoucherID', GUID(), ForeignKey('vouchers.VoucherID'), nullable=False, index=True) - ledger_id = Column('LedgerID', GUID(), ForeignKey('ledgers.LedgerID'), nullable=False) + account_id = Column('account_id', GUID(), ForeignKey('accounts.id'), nullable=False) cost_centre_id = Column('CostCentreID', GUID(), ForeignKey('cost_centres.CostCentreID'), nullable=False) @hybrid_property @@ -116,12 +118,12 @@ class Journal(Base): def __name__(self): return self.name - def __init__(self, id=None, debit=None, amount=None, voucher_id=None, ledger_id=None, cost_centre_id=None): + def __init__(self, id=None, debit=None, amount=None, voucher_id=None, account_id=None, cost_centre_id=None): self.id = id self.debit = debit self.amount = amount self.voucher_id = voucher_id - self.ledger_id = ledger_id + self.account_id = account_id self.cost_centre_id = cost_centre_id @@ -251,7 +253,7 @@ class Attendance(Base): __tablename__ = 'attendances' id = Column('AttendanceID', GUID(), primary_key=True, default=uuid.uuid4) - employee_id = Column('EmployeeID', GUID(), ForeignKey('employees.LedgerID')) + employee_id = Column('EmployeeID', GUID(), ForeignKey('employees.id')) date = Column('Date', DateTime) attendance_type = Column('AttendanceType', Integer) amount = Column('Amount', Numeric) @@ -286,7 +288,7 @@ class Fingerprint(Base): __tablename__ = 'fingerprints' id = Column('FingerprintID', GUID(), primary_key=True, default=uuid.uuid4) - employee_id = Column('EmployeeID', GUID(), ForeignKey('employees.LedgerID')) + employee_id = Column('EmployeeID', GUID(), ForeignKey('employees.id')) date = Column('Date', DateTime) def __init__(self, id=None, employee_id=None, date=None): diff --git a/brewman/scripts/initializedb.py b/brewman/scripts/initializedb.py index da699797..177d0fb2 100644 --- a/brewman/scripts/initializedb.py +++ b/brewman/scripts/initializedb.py @@ -29,8 +29,8 @@ from brewman.models.master import ( Product, CostCentre, Employee, - Ledger, - LedgerBase, + Account, + AccountBase, ProductGroup, Recipe, RecipeItem, @@ -139,25 +139,25 @@ def main(argv=sys.argv): for cost_centre in cost_centres: dbsession.add(cost_centre) - ledgers = [Ledger(1, 'All Purchases', 2, True, False, uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3'), - uuid.UUID('240dd899-c413-854c-a7eb-67a29d154490'), True), - Ledger(1, 'Local Purchase', 9, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), - uuid.UUID('d2b75912-505f-2548-9093-466dfff6a0f9'), True), - Ledger(1, 'ESI/PF - Payable', 11, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), - uuid.UUID('42277912-cc18-854b-b134-9f4b00dba419'), True), - Ledger(2, 'ESI/PF - Expense', 7, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), - uuid.UUID('d2a1a286-e900-764b-a1a5-9f4b00dbb940'), True), - Ledger(1, 'Cash in Hand', 1, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), - uuid.UUID('ed2341bb-80b8-9649-90db-f9aaca183bb3'), True), - Ledger(1, 'Staff Salary', 7, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), - uuid.UUID('5c2b54d0-c174-004d-a0d5-92cdaadcefa7'), True), - Ledger(2, 'Service Charges', 11, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), - uuid.UUID('b7eff754-e8ba-e047-ab06-9132c15c7640'), True), - Ledger(1, 'Suspense', 4, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), - uuid.UUID('3854e317-6f3b-5142-ab26-9c44d4cddd08'), True)] + accounts = [Account(1, 'All Purchases', 2, True, False, uuid.UUID('7b845f95-dfef-fa4a-897c-f0baf15284a3'), + uuid.UUID('240dd899-c413-854c-a7eb-67a29d154490'), True), + Account(1, 'Local Purchase', 9, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), + uuid.UUID('d2b75912-505f-2548-9093-466dfff6a0f9'), True), + Account(1, 'ESI/PF - Payable', 11, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), + uuid.UUID('42277912-cc18-854b-b134-9f4b00dba419'), True), + Account(2, 'ESI/PF - Expense', 7, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), + uuid.UUID('d2a1a286-e900-764b-a1a5-9f4b00dbb940'), True), + Account(1, 'Cash in Hand', 1, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), + uuid.UUID('ed2341bb-80b8-9649-90db-f9aaca183bb3'), True), + Account(1, 'Staff Salary', 7, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), + uuid.UUID('5c2b54d0-c174-004d-a0d5-92cdaadcefa7'), True), + Account(2, 'Service Charges', 11, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), + uuid.UUID('b7eff754-e8ba-e047-ab06-9132c15c7640'), True), + Account(1, 'Suspense', 4, True, False, uuid.UUID('36f59436-522a-0746-ae94-e0f746bf6c0d'), + uuid.UUID('3854e317-6f3b-5142-ab26-9c44d4cddd08'), True)] - for ledger in ledgers: - dbsession.add(ledger) + for account in accounts: + dbsession.add(account) product_group = ProductGroup('Suspense', uuid.UUID('ae59a20c-87bb-444a-8abb-915ad5e58b83'), True) dbsession.add(product_group) diff --git a/brewman/views/Management/rebase.py b/brewman/views/Management/rebase.py index ee704af0..91c3e874 100644 --- a/brewman/views/Management/rebase.py +++ b/brewman/views/Management/rebase.py @@ -1,13 +1,13 @@ import datetime -from decimal import Decimal import uuid +from decimal import Decimal +import transaction from pyramid.view import view_config from sqlalchemy import func, and_, distinct -from sqlalchemy.orm import aliased -import transaction +from sqlalchemy.orm import aliased, joinedload_all -from brewman.models.master import LedgerBase, CostCentre, Ledger, Employee +from brewman.models.master import AccountBase, CostCentre, Account, Employee from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory, SalaryDeduction, Fingerprint, \ Attendance, DbImage, ServiceCharge @@ -18,9 +18,11 @@ def rebase(request): date = request.matchdict.get('date', None) date = datetime.datetime.strptime(date, '%d-%b-%Y') user_id = uuid.UUID(request.authenticated_userid) - voucher_l, accounts = opening_ledgers(date, user_id, request.dbsession) + voucher_l, accounts = opening_accounts(date, user_id, request.dbsession) voucher_b, batches = opening_batches(date, user_id, request.dbsession) - delete_data(date, request.dbsession) + starred_vouchers = save_starred(date, request.dbsession) + request.dbsession.flush() + delete_data(date, starred_vouchers, request.dbsession) request.dbsession.add(voucher_l) for j in voucher_l.journals: request.dbsession.add(j) @@ -35,29 +37,84 @@ def rebase(request): return {} -def opening_ledgers(date, user_id, dbsession): +def save_starred(date, dbsession): + accounts = [i.id for i in dbsession.query(AccountBase.id).filter(AccountBase.is_starred == True).all()] + vouchers = [] + query = dbsession.query( + Voucher + ).options( + joinedload_all(Voucher.journals, Journal.account, innerjoin=True) + ).filter( + Voucher.date < date + ).filter( + Voucher.journals.any(Journal.account_id.in_(accounts)) + ).all() + + for voucher in query: + vouchers.append(voucher.id) + others = [journal for journal in voucher.journals if journal.account_id not in accounts] + if len(others) == 0: + continue + amount = round(Decimal(sum(o.signed_amount for o in others)), 2) + if amount != 0: + journal = Journal( + amount=abs(amount), + debit=-1 if amount < 0 else 1, + account_id=AccountBase.suspense(), + cost_centre_id=CostCentre.cost_centre_overall() + ) + voucher.journals.append(journal) + dbsession.add(journal) + + for other in others: + if voucher.type != VoucherType.by_name('Opening Accounts').id: + voucher.narration += '\nSuspense \u20B9{0:,.2f} is {1}'.format(other.amount, other.account.name) + dbsession.delete(other) + voucher.type = VoucherType.by_name('Journal') + if len(voucher.narration) >= 1000: + voucher.narration = voucher.narration[:1000] + return vouchers + + +def opening_accounts(date, user_id, dbsession): running_total = 0 accounts = [] sum_func = func.sum(Journal.signed_amount) - query = dbsession.query(LedgerBase, sum_func) \ - .join(Journal, Voucher.journals).join(LedgerBase, Journal.ledger) \ - .filter(Voucher.date < date).filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .having(sum_func != 0) \ - .group_by(LedgerBase).all() + query = dbsession.query( + AccountBase, sum_func + ).join( + Journal, Voucher.journals + ).join( + AccountBase, Journal.account + ).filter( + AccountBase.is_starred == False + ).filter( + AccountBase.id != AccountBase.suspense() + ).filter( + Voucher.date < date + ).filter( + Voucher.type != VoucherType.by_name('Issue').id + ).having( + sum_func != 0 + ).group_by(AccountBase).all() dt = date - datetime.timedelta(days=1) - voucher = Voucher(date=dt, narration='Opening Ledgers', user_id=user_id, posted=True, - type=VoucherType.by_name('Opening Ledgers')) - for ledger, amount in query: + voucher = Voucher( + date=dt, + narration='Opening Accounts', + user_id=user_id, posted=True, + type=VoucherType.by_name('Opening Accounts') + ) + for account, amount in query: amount = round(Decimal(amount), 2) - if ledger.type_object.balance_sheet and ledger.id != LedgerBase.suspense() and amount != 0: + if account.type_object.balance_sheet and amount != 0: running_total += amount - journal = Journal(amount=abs(amount), debit=-1 if amount < 0 else 1, ledger_id=ledger.id, - cost_centre_id=ledger.cost_centre_id) + journal = Journal(amount=abs(amount), debit=-1 if amount < 0 else 1, account_id=account.id, + cost_centre_id=account.cost_centre_id) voucher.journals.append(journal) - accounts.append(ledger.id) + accounts.append(account.id) 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, account_id=AccountBase.suspense(), cost_centre_id=CostCentre.cost_centre_overall()) voucher.journals.append(journal) return voucher, accounts @@ -67,16 +124,31 @@ def opening_batches(date, user_id, dbsession): total = 0 batches = [] sum_func = func.sum(Journal.debit * Inventory.quantity) - query = dbsession.query(Batch, sum_func) \ - .join(Journal, Voucher.journals).join(Inventory, Voucher.inventories).join(Batch, Inventory.batch) \ - .filter(Voucher.date < date) \ - .filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase()) \ - .having(sum_func != 0) \ - .group_by(Batch).all() + query = dbsession.query( + Batch, sum_func + ).join( + Journal, Voucher.journals + ).join( + Inventory, Voucher.inventories + ).join( + Batch, Inventory.batch + ).filter( + Voucher.date < date + ).filter( + Journal.cost_centre_id == CostCentre.cost_centre_purchase() + ).having( + sum_func != 0 + ).group_by(Batch).all() dt = date - datetime.timedelta(days=1) - voucher = Voucher(date=dt, narration='Opening Batches', user_id=user_id, posted=True, - type=VoucherType.by_name('Opening Batches')) + voucher = Voucher( + date=dt, + narration='Opening Batches', + user_id=user_id, + posted=True, + type=VoucherType.by_name('Opening Batches') + ) + for batch, quantity in query: quantity = round(Decimal(quantity), 2) if quantity != 0: @@ -85,16 +157,28 @@ def opening_batches(date, user_id, dbsession): tax=batch.tax, discount=batch.discount) voucher.inventories.append(inventory) batches.append(batch.id) - voucher.journals.append(Journal(amount=abs(total), debit=-1, ledger_id=LedgerBase.all_purchases(), - cost_centre_id=CostCentre.cost_centre_overall())) - voucher.journals.append(Journal(amount=abs(total), debit=1, ledger_id=LedgerBase.all_purchases(), - cost_centre_id=CostCentre.cost_centre_purchase())) + voucher.journals.append(Journal( + amount=abs(total), + debit=-1, + account_id=AccountBase.all_purchases(), + cost_centre_id=CostCentre.cost_centre_overall() + )) + voucher.journals.append(Journal( + amount=abs(total), + debit=1, + account_id=AccountBase.all_purchases(), + cost_centre_id=CostCentre.cost_centre_purchase() + )) return voucher, batches -def delete_data(date, dbsession): +def delete_data(date, vouchers, dbsession): sub_voucher = aliased(Voucher) - sub_query = dbsession.query(sub_voucher.id).filter(sub_voucher.date < date).subquery() + sub_query = dbsession.query( + sub_voucher.id + ).filter( + sub_voucher.date < date + ).subquery() dbsession.execute( Inventory.__table__.delete(Inventory.voucher_id.in_(sub_query)) @@ -106,13 +190,28 @@ def delete_data(date, dbsession): ServiceCharge.__table__.delete(ServiceCharge.voucher_id.in_(sub_query)) ) dbsession.execute( - Journal.__table__.delete(Journal.voucher_id.in_(sub_query)) + Journal.__table__.delete( + and_( + Journal.voucher_id.in_(sub_query), + ~Journal.voucher_id.in_(vouchers) + ) + ) ) dbsession.execute( - DbImage.__table__.delete(and_(DbImage.resource_type == 'voucher', DbImage.resource_id.in_(sub_query))) + DbImage.__table__.delete( + and_( + DbImage.resource_type == 'voucher', DbImage.resource_id.in_(sub_query), + ~DbImage.resource_id.in_(vouchers) + ) + ) ) dbsession.execute( - Voucher.__table__.delete(Voucher.date < date) + Voucher.__table__.delete( + and_( + Voucher.date < date, + ~Voucher.id.in_(vouchers) + ) + ) ) @@ -135,33 +234,38 @@ def cleanup_lint(date, accounts, batches, dbsession): dbsession.execute( Employee.__table__.delete( and_( - ~Employee.id.in_(dbsession.query(distinct(Journal.ledger_id)).subquery()), + ~Employee.id.in_(dbsession.query(distinct(Journal.account_id)).subquery()), ~Employee.id.in_(accounts), Employee.id.in_( - dbsession.query(LedgerBase.id).filter( - LedgerBase.is_fixture == False + dbsession.query( + AccountBase.id ).filter( - LedgerBase.is_active == False + AccountBase.is_fixture == False + ).filter( + AccountBase.is_active == False + ).filter( + AccountBase.is_starred == False ).subquery()), Employee.leaving_date < date ) ) ) dbsession.execute( - LedgerBase.__table__.delete( + AccountBase.__table__.delete( and_( - ~LedgerBase.id.in_(dbsession.query(Employee.id).subquery()), - LedgerBase.ledger_type == Employee.__mapper_args__['polymorphic_identity'] + ~AccountBase.id.in_(dbsession.query(Employee.id).subquery()), + AccountBase.account_type == Employee.__mapper_args__['polymorphic_identity'] ) ) ) dbsession.execute( - Ledger.__table__.delete( + Account.__table__.delete( and_( - ~Ledger.id.in_(dbsession.query(distinct(Journal.ledger_id)).subquery()), - ~Ledger.id.in_(accounts), - Ledger.is_fixture == False, - Ledger.ledger_type == Ledger.__mapper_args__['polymorphic_identity'] + ~Account.id.in_(dbsession.query(distinct(Journal.account_id)).subquery()), + ~Account.id.in_(accounts), + Account.is_fixture == False, + Account.is_starred == False, + Account.account_type == Account.__mapper_args__['polymorphic_identity'] ) ) ) diff --git a/brewman/views/Management/stock.py b/brewman/views/Management/stock.py index f3cd632e..e77d66bc 100644 --- a/brewman/views/Management/stock.py +++ b/brewman/views/Management/stock.py @@ -6,7 +6,7 @@ from pyramid.view import view_config from sqlalchemy import func import transaction -from brewman.models.master import LedgerBase, CostCentre, Product +from brewman.models.master import AccountBase, CostCentre, Product from brewman.models.validation_exception import ValidationError from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory @@ -83,9 +83,9 @@ def create_voucher(batch, quantity, date, user_id, dbsession): dbsession.add(inventory) amount = round(inventory.amount, 2) - source = Journal(debit=-1, ledger_id=LedgerBase.all_purchases(), amount=amount, cost_centre_id=source) + source = Journal(debit=-1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=source) voucher.journals.append(source) dbsession.add(source) - destination = Journal(debit=1, ledger_id=LedgerBase.all_purchases(), amount=amount, cost_centre_id=destination) + destination = Journal(debit=1, account_id=AccountBase.all_purchases(), amount=amount, cost_centre_id=destination) voucher.journals.append(destination) dbsession.add(destination) diff --git a/brewman/views/account.py b/brewman/views/account.py index 1f79aa30..da3564bc 100644 --- a/brewman/views/account.py +++ b/brewman/views/account.py @@ -8,7 +8,7 @@ from pyramid.view import view_config from sqlalchemy import func from sqlalchemy.orm import joinedload_all -from brewman.models.master import CostCentre, Ledger, LedgerType, LedgerBase +from brewman.models.master import CostCentre, Account, AccountType, AccountBase from brewman.models.validation_exception import ValidationError from brewman.models.voucher import Voucher, Journal, VoucherType @@ -24,25 +24,33 @@ def html(request): @view_config(request_method='POST', route_name='api_account', renderer='json', permission='Accounts', trans=True) def save(request): - 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'], - cost_centre_id=uuid.UUID(request.json_body['costCentre']['id'])).create(request.dbsession) + json = request.json_body + item = Account( + code=0, + name=json['name'], + type=int(json['type']), + is_starred=json['isStarred'], + is_active=json['isActive'], + is_reconcilable=json['isReconcilable'], + cost_centre_id=uuid.UUID(json['costCentre']['id']) + ).create(request.dbsession) transaction.commit() return account_info(item.id, request.dbsession) @view_config(request_method='PUT', route_name='api_account_id', renderer='json', permission='Accounts', trans=True) def update(request): - item = request.dbsession.query(Ledger).filter(Ledger.id == uuid.UUID(request.matchdict['id'])).first() + item = request.dbsession.query(Account).filter(Account.id == uuid.UUID(request.matchdict['id'])).first() if item.is_fixture: raise ValidationError("{0} is a fixture and cannot be edited or deleted.".format(item.name)) new_type = int(request.json_body['type']) if not item.type == new_type: - item.code = Ledger.get_code(new_type, request.dbsession) + item.code = Account.get_code(new_type, request.dbsession) item.type = new_type item.name = request.json_body['name'] item.is_active = request.json_body['isActive'] item.is_reconcilable = request.json_body['isReconcilable'] + item.is_starred = request.json_body['isStarred'] item.cost_centre_id = uuid.UUID(request.json_body['costCentre']['id']) transaction.commit() return account_info(item.id, request.dbsession) @@ -50,7 +58,7 @@ def update(request): @view_config(request_method='DELETE', route_name='api_account_id', renderer='json', permission='Accounts') def delete(request): - account = request.dbsession.query(Ledger).filter(Ledger.id == uuid.UUID(request.matchdict['id'])).first() + account = request.dbsession.query(Account).filter(Account.id == uuid.UUID(request.matchdict['id'])).first() can_delete, reason = account.can_delete(request.has_permission('Advanced Delete')) if can_delete: delete_with_data(account, request.dbsession) @@ -73,7 +81,7 @@ def show_balance(request): def balance(id_, date, dbsession): - account = dbsession.query(LedgerBase).filter(LedgerBase.id == id_).first() + account = dbsession.query(AccountBase).filter(AccountBase.id == id_).first() if not account.type_object.balance_sheet: return 0 @@ -82,7 +90,7 @@ def balance(id_, date, dbsession): bal = bal.filter(Voucher.date <= date) bal = bal.filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .filter(Journal.ledger_id == id_) \ + .filter(Journal.account_id == id_) \ .scalar() return 0 if bal is None else bal @@ -100,13 +108,17 @@ def show_blank(request): @view_config(request_method='GET', route_name='api_account', renderer='json', request_param='l', permission='Authenticated') def show_list(request): - list = request.dbsession.query(Ledger).order_by(Ledger.type).order_by(Ledger.name).order_by(Ledger.code).all() - ledgers = [] + list = request.dbsession.query(Account).order_by(Account.type).order_by(Account.name).order_by(Account.code).all() + accounts = [] for item in list: - ledgers.append({'id': item.id, 'name': item.name, 'type': item.type_object.name, 'isActive': item.is_active, - 'isReconcilable': item.is_reconcilable, 'costCentre': item.cost_centre.name, - 'isFixture': item.is_fixture}) - return ledgers + accounts.append( + { + 'id': item.id, 'name': item.name, 'type': item.type_object.name, 'isActive': item.is_active, + 'isReconcilable': item.is_reconcilable, 'isStarred': item.is_starred, + 'costCentre': item.cost_centre.name, 'isFixture': item.is_fixture + } + ) + return accounts @view_config(request_method='GET', route_name='api_account', renderer='json', request_param='q', @@ -124,7 +136,7 @@ def show_term(request): count = None if count is None or count == '' else int(count) list = [] - for index, item in enumerate(LedgerBase.list(type, filter, reconcilable, active, request.dbsession)): + for index, item in enumerate(AccountBase.list(type, filter, reconcilable, active, request.dbsession)): list.append({'id': item.id, 'name': item.name}) if count is not None and index == count - 1: break @@ -134,36 +146,40 @@ def show_term(request): @view_config(request_method='GET', route_name='api_account_type_list', renderer='json', permission='Authenticated') def account_type_list(request): account_types = [] - for item in LedgerType.list(): + for item in AccountType.list(): account_types.append({'id': item.id, 'name': item.name}) return account_types def account_info(id, dbsession): if id is None: - account = {'code': '(Auto)', 'type': LedgerType.by_name('Creditors').id, 'isActive': True, - 'isReconcilable': False, 'costCentre': CostCentre.overall()} + account = { + 'code': '(Auto)', 'type': AccountType.by_name('Creditors').id, 'isActive': True, + 'isReconcilable': False, 'isStarred': False, 'costCentre': CostCentre.overall() + } else: - account = dbsession.query(Ledger).filter(Ledger.id == id).first() - account = {'id': account.id, 'code': account.code, 'name': account.name, 'type': account.type, - 'isActive': account.is_active, 'isReconcilable': account.is_reconcilable, - 'isFixture': account.is_fixture, - 'costCentre': {'id': account.cost_centre_id, 'name': account.cost_centre.name}} + account = dbsession.query(Account).filter(Account.id == id).first() + account = { + 'id': account.id, 'code': account.code, 'name': account.name, 'type': account.type, + 'isActive': account.is_active, 'isReconcilable': account.is_reconcilable, 'isStarred': account.is_starred, + 'isFixture': account.is_fixture, + 'costCentre': {'id': account.cost_centre_id, 'name': account.cost_centre.name} + } return account def delete_with_data(account, dbsession): - suspense_ledger = dbsession.query(Ledger).filter(Ledger.id == Ledger.suspense()).first() - query = dbsession.query(Voucher).options(joinedload_all(Voucher.journals, Journal.ledger, innerjoin=True)) \ - .filter(Voucher.journals.any(Journal.ledger_id == account.id)) \ + suspense_account = dbsession.query(Account).filter(Account.id == Account.suspense()).first() + query = dbsession.query(Voucher).options(joinedload_all(Voucher.journals, Journal.account, innerjoin=True)) \ + .filter(Voucher.journals.any(Journal.account_id == account.id)) \ .all() for voucher in query: others, sus_jnl, acc_jnl = False, None, None for journal in voucher.journals: - if journal.ledger_id == account.id: + if journal.account_id == account.id: acc_jnl = journal - elif journal.ledger_id == Ledger.suspense(): + elif journal.account_id == Account.suspense(): sus_jnl = journal else: others = True @@ -171,7 +187,7 @@ def delete_with_data(account, dbsession): dbsession.delete(voucher) else: if sus_jnl is None: - acc_jnl.ledger = suspense_ledger + acc_jnl.account = suspense_account voucher.narration += '\nSuspense \u20B9{0:,.2f} is {1}'.format(acc_jnl.amount, account.name) else: amount = (sus_jnl.debit * sus_jnl.amount) + (acc_jnl.debit * acc_jnl.amount) diff --git a/brewman/views/employee.py b/brewman/views/employee.py index 56fda25f..10c018b8 100644 --- a/brewman/views/employee.py +++ b/brewman/views/employee.py @@ -9,7 +9,7 @@ from pyramid.view import view_config from sqlalchemy import desc from sqlalchemy.orm import joinedload_all -from brewman.models.master import CostCentre, Employee, LedgerBase, Ledger +from brewman.models.master import CostCentre, Employee, AccountBase, Account from brewman.models.validation_exception import ValidationError from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.views import to_uuid @@ -149,16 +149,16 @@ def show_blank(request): permission='Authenticated') def show_list(request): list = request.dbsession.query(Employee).order_by(desc(Employee.is_active)).order_by( - Ledger.cost_centre_id).order_by(Employee.designation).order_by(Employee.name).all() - ledgers = [] + Account.cost_centre_id).order_by(Employee.designation).order_by(Employee.name).all() + accounts = [] for item in list: - ledgers.append({ + accounts.append({ 'id': item.id, 'code': item.code, 'name': item.name, 'designation': item.designation, 'salary': item.salary, 'points': item.service_points, 'isActive': item.is_active, 'costCentre': item.cost_centre.name, 'url': request.route_url('employee_id', id=item.id), 'joiningDate': item.joining_date.strftime('%d-%b-%Y'), 'leavingDate': '' if item.is_active else item.leaving_date.strftime('%d-%b-%Y') }) - return ledgers + return accounts @view_config(request_method='GET', route_name='api_employee', renderer='json', request_param='q', @@ -170,7 +170,7 @@ def show_term(request): count = None if count is None or count == '' else int(count) list = [] - for index, item in enumerate(LedgerBase.list(10, filter, dbsession=request.dbsession)): + for index, item in enumerate(AccountBase.list(10, filter, dbsession=request.dbsession)): list.append({'id': item.id, 'name': item.name, 'designation': item.designation, 'costCentre': {'id': item.cost_centre.id, 'name': item.cost_centre.name}}) if count is not None and index == count - 1: @@ -194,17 +194,17 @@ def employee_info(id, dbsession): def delete_with_data(employee, dbsession): - suspense_ledger = dbsession.query(Ledger).filter(Ledger.id == Ledger.suspense()).first() - query = dbsession.query(Voucher).options(joinedload_all(Voucher.journals, Journal.ledger, innerjoin=True)) \ - .filter(Voucher.journals.any(Journal.ledger_id == employee.id)) \ + suspense_account = dbsession.query(Account).filter(Account.id == Account.suspense()).first() + query = dbsession.query(Voucher).options(joinedload_all(Voucher.journals, Journal.account, innerjoin=True)) \ + .filter(Voucher.journals.any(Journal.account_id == employee.id)) \ .all() for voucher in query: others, sus_jnl, acc_jnl = False, None, None for journal in voucher.journals: - if journal.ledger_id == employee.id: + if journal.account_id == employee.id: acc_jnl = journal - elif journal.ledger_id == Ledger.suspense(): + elif journal.account_id == Account.suspense(): sus_jnl = journal else: others = True @@ -212,7 +212,7 @@ def delete_with_data(employee, dbsession): dbsession.delete(voucher) else: if sus_jnl is None: - acc_jnl.ledger = suspense_ledger + acc_jnl.account = suspense_account voucher.narration += '\nSuspense \u20B9 {0:,.2f} is {1}'.format(acc_jnl.amount, employee.name) else: amount = (sus_jnl.debit * sus_jnl.amount) + (acc_jnl.debit * acc_jnl.amount) diff --git a/brewman/views/product.py b/brewman/views/product.py index 8615561f..a37f6955 100644 --- a/brewman/views/product.py +++ b/brewman/views/product.py @@ -8,7 +8,7 @@ from pyramid.view import view_config from sqlalchemy import desc from sqlalchemy.orm import joinedload_all -from brewman.models.master import Product, Ledger +from brewman.models.master import Product, Account from brewman.models.validation_exception import ValidationError from brewman.models.voucher import Voucher, Batch, Inventory, VoucherType @@ -67,7 +67,7 @@ def save(request): is_active = json.get('isActive', True) is_purchased = json.get('isPurchased', True) is_sold = json.get('isSold', True) - item = Product(0, name, units, fraction, fraction_units, product_yield, product_group_id, Ledger.all_purchases(), + item = Product(0, name, units, fraction, fraction_units, product_yield, product_group_id, Account.all_purchases(), price, sale_price, is_active, is_purchased, is_sold).create(request.dbsession) transaction.commit() return product_info(item.id, request.dbsession) @@ -96,7 +96,7 @@ def update(request): raise ValidationError("Yield must be a decimal > 0 <= 1") item.product_group_id = uuid.UUID(request.json_body['productGroup']['id']) - item.ledger_id = Ledger.all_purchases() + item.account_id = Account.all_purchases() try: item.price = Decimal(request.json_body['price']) if item.price < 0: @@ -213,7 +213,7 @@ def product_info(id, dbsession): 'isActive': product.is_active, 'isFixture': product.is_fixture, 'isPurchased': product.is_purchased, 'isSold': product.is_sold, 'productGroup': {'id': product.product_group_id}, - 'account': {'id': product.ledger_id}} + 'account': {'id': product.account_id}} return product diff --git a/brewman/views/reports/balance_sheet.py b/brewman/views/reports/balance_sheet.py index f821f407..a7d7e1f1 100644 --- a/brewman/views/reports/balance_sheet.py +++ b/brewman/views/reports/balance_sheet.py @@ -5,7 +5,7 @@ from sqlalchemy.sql.expression import func, desc from pyramid.view import view_config -from brewman.models.master import LedgerType, LedgerBase +from brewman.models.master import AccountType, AccountBase from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.views.reports.closing_stock import get_closing_stock @@ -36,7 +36,7 @@ def report_data(request): def build_balance_sheet(finish_date, dbsession): if not isinstance(finish_date, datetime.datetime): finish_date = datetime.datetime.strptime(finish_date, '%d-%b-%Y') - type_list = [i.id for i in LedgerType.list() if i.balance_sheet == True] + type_list = [i.id for i in AccountType.list() if i.balance_sheet == True] report = [] groups = dict() # Add Net Profit / Loss @@ -45,38 +45,38 @@ def build_balance_sheet(finish_date, dbsession): total_amount = net_profit report.append({'name': 'Net Loss' if net_profit >= 0 else 'Net Profit', 'subAmount': net_profit, 'order': 79}) - capital_group = LedgerType.by_id(5) + capital_group = AccountType.by_id(5) groups[capital_group.id] = {'group': capital_group.name, 'amount': total_amount, 'order': capital_group.order} total_amount += closing_stock report.append({'name': 'Closing Stock', 'subAmount': closing_stock, 'order': 20.001}) - asset_group = LedgerType.by_id(4) + asset_group = AccountType.by_id(4) groups[asset_group.id] = {'group': asset_group.name, 'amount': closing_stock, 'order': asset_group.order} amount_sum = func.sum(Journal.amount * Journal.debit) - query = dbsession.query(LedgerBase, amount_sum) \ - .join(Journal.voucher).join(Journal.ledger) \ + query = dbsession.query(AccountBase, amount_sum) \ + .join(Journal.voucher).join(Journal.account) \ .filter(Voucher.date <= finish_date) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .filter(LedgerBase.type.in_(type_list)) \ - .group_by(LedgerBase).order_by(LedgerBase.type).order_by(desc(func.abs(amount_sum))).all() + .filter(AccountBase.type.in_(type_list)) \ + .group_by(AccountBase).order_by(AccountBase.type).order_by(desc(func.abs(amount_sum))).all() counter = 0 sss = 0 - for ledger, amount in query: + for account, amount in query: # Add Items - ledger_type = LedgerType.by_id(ledger.type) + account_type = AccountType.by_id(account.type) sss += amount total_amount += amount if amount != 0: counter += .001 report.append( - {'name': ledger.name, 'subAmount': amount, 'order': ledger_type.order + counter}) - if ledger_type.id in groups: - groups[ledger_type.id]['amount'] += amount + {'name': account.name, 'subAmount': amount, 'order': account_type.order + counter}) + if account_type.id in groups: + groups[account_type.id]['amount'] += amount else: - groups[ledger_type.id] = {'group': ledger_type.name, 'amount': amount, 'order': ledger_type.order} + groups[account_type.id] = {'group': account_type.name, 'amount': amount, 'order': account_type.order} # Add Subtotals for item in groups.values(): diff --git a/brewman/views/reports/cash_flow.py b/brewman/views/reports/cash_flow.py index d19a37ac..8f5db123 100644 --- a/brewman/views/reports/cash_flow.py +++ b/brewman/views/reports/cash_flow.py @@ -6,7 +6,7 @@ from sqlalchemy.orm.util import aliased from sqlalchemy.sql.expression import func, desc from pyramid.view import view_config -from brewman.models.master import LedgerBase, LedgerType +from brewman.models.master import AccountBase, AccountType from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.views.services.session import session_period_start, session_period_finish @@ -42,35 +42,35 @@ def build_report(request, start_date, finish_date): report = {'startDate': start_date, 'finishDate': finish_date} sub_voucher = aliased(Voucher) sub_journal = aliased(Journal) - sub_ledger = aliased(LedgerBase) + sub_account = aliased(AccountBase) sub_query = request.dbsession.query(sub_voucher.id) \ .join(sub_journal, sub_voucher.journals) \ - .join(sub_ledger, sub_journal.ledger) \ - .filter(sub_ledger.type == LedgerType.by_name('Cash').id) \ + .join(sub_account, sub_journal.account) \ + .filter(sub_account.type == AccountType.by_name('Cash').id) \ .filter(sub_voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(sub_voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')).subquery() query = request.dbsession.query( - LedgerBase.type, func.sum(Journal.signed_amount) + AccountBase.type, func.sum(Journal.signed_amount) ).join( Journal, Voucher.journals ).join( - LedgerBase, Journal.ledger + AccountBase, Journal.account ).filter( Voucher.id.in_(sub_query) ).filter( - LedgerBase.type != LedgerType.by_name('Cash').id + AccountBase.type != AccountType.by_name('Cash').id ).group_by( - LedgerBase.type + AccountBase.type ).order_by( func.sum(Journal.signed_amount) ).all() total_amount = 0 cf = {'operating': [], 'investing': [], 'financing': []} - for ledgerType, amount in query: - lt = LedgerType.by_id(ledgerType) + for account_type, amount in query: + lt = AccountType.by_id(account_type) total_amount += (amount * -1) cf[lt.cash_flow_classification.lower()].append( { @@ -88,21 +88,21 @@ def build_report(request, start_date, finish_date): opening = request.dbsession.query( func.sum(Journal.amount * Journal.debit) ).join(Journal.voucher).join( - Journal.ledger + Journal.account ).filter(Voucher.date < start_date).filter( Voucher.type != VoucherType.by_name('Issue').id ).filter( - LedgerBase.type == LedgerType.by_name('Cash').id + AccountBase.type == AccountType.by_name('Cash').id ).scalar() closing = request.dbsession.query( func.sum(Journal.amount * Journal.debit) ).join(Journal.voucher).join( - Journal.ledger + Journal.account ).filter(Voucher.date <= finish_date).filter( Voucher.type != VoucherType.by_name('Issue').id ).filter( - LedgerBase.type == LedgerType.by_name('Cash').id + AccountBase.type == AccountType.by_name('Cash').id ).scalar() report['Footer'] = [{'name': 'Net increase in cash and cash equivalents', 'amount': total_amount}, @@ -111,42 +111,42 @@ def build_report(request, start_date, finish_date): return report -def build_report_id(request, ledger_type, start_date, finish_date): +def build_report_id(request, account_type, start_date, finish_date): report = {'startDate': start_date, 'finishDate': finish_date, 'body': {'details': []}} sub_voucher = aliased(Voucher) sub_journal = aliased(Journal) - sub_ledger = aliased(LedgerBase) + sub_account = aliased(AccountBase) sub_query = request.dbsession.query( sub_voucher.id ).join( sub_journal, sub_voucher.journals ).join( - sub_ledger, sub_journal.ledger + sub_account, sub_journal.account ).filter( - sub_ledger.type == LedgerType.by_name('Cash').id + sub_account.type == AccountType.by_name('Cash').id ).filter( sub_voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y') ).filter( sub_voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y') ).subquery() - query = request.dbsession.query(LedgerBase, func.sum(Journal.signed_amount)) \ + query = request.dbsession.query(AccountBase, func.sum(Journal.signed_amount)) \ .join(Journal, Voucher.journals) \ - .join(LedgerBase, Journal.ledger) \ + .join(AccountBase, Journal.account) \ .filter(Voucher.id.in_(sub_query)) \ - .filter(LedgerBase.type == ledger_type) \ - .group_by(LedgerBase) \ + .filter(AccountBase.type == account_type) \ + .group_by(AccountBase) \ .order_by(desc(func.sum(Journal.amount))).all() total_amount = 0 - for ledger, amount in query: + for account, amount in query: total_amount += (amount * -1) report['body']['details'].append( { - 'name': ledger.name, + 'name': account.name, 'url': request.route_url( - 'ledger_id', id=ledger.id, + 'ledger_id', id=account.id, _query={'startDate': start_date, 'finishDate': finish_date} ), 'amount': amount * -1 diff --git a/brewman/views/reports/closing_stock.py b/brewman/views/reports/closing_stock.py index 7d894f0f..8c772adf 100644 --- a/brewman/views/reports/closing_stock.py +++ b/brewman/views/reports/closing_stock.py @@ -54,7 +54,7 @@ def get_opening_stock(start_date, dbsession): ).join( Journal.voucher ).join( - Journal.ledger + Journal.account ).join( Voucher.inventories ).filter( @@ -71,7 +71,7 @@ def get_closing_stock(finish_date, dbsession): ).join( Journal.voucher ).join( - Journal.ledger + Journal.account ).join( Voucher.inventories ).filter( diff --git a/brewman/views/reports/daybook.py b/brewman/views/reports/daybook.py index da56007b..8397e1ad 100644 --- a/brewman/views/reports/daybook.py +++ b/brewman/views/reports/daybook.py @@ -31,7 +31,7 @@ def daybook_report(request): def build_report(request, start_date, finish_date): report = {'startDate': start_date, 'finishDate': finish_date, 'body': []} - query = request.dbsession.query(Voucher).options(joinedload_all(Voucher.journals, Journal.ledger, innerjoin=True)) \ + query = request.dbsession.query(Voucher).options(joinedload_all(Voucher.journals, Journal.account, innerjoin=True)) \ .filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \ @@ -45,10 +45,10 @@ def build_report(request, start_date, finish_date): for journal in voucher.journals: if journal.debit == 1: debit += journal.amount - name_debit += "{0} / ".format(journal.ledger.name) + name_debit += "{0} / ".format(journal.account.name) else: credit += journal.amount - name_credit += "{0} / ".format(journal.ledger.name) + name_credit += "{0} / ".format(journal.account.name) name_debit = name_debit[:-3] name_credit = name_credit[:-3] diff --git a/brewman/views/reports/ledger.py b/brewman/views/reports/ledger.py index e8417565..e3951f1d 100644 --- a/brewman/views/reports/ledger.py +++ b/brewman/views/reports/ledger.py @@ -7,7 +7,7 @@ from sqlalchemy.orm import joinedload_all from sqlalchemy.sql.expression import func from pyramid.view import view_config -from brewman.models.master import LedgerBase +from brewman.models.master import AccountBase from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.views.services.session import session_period_start, session_period_finish from brewman.views.services.voucher import get_edit_url @@ -29,11 +29,11 @@ def show_blank(request): @view_config(request_method='GET', route_name='api_ledger_id', renderer='json', permission='Ledger', trans=True) def show_data(request): - ledger = request.dbsession.query(LedgerBase).filter(LedgerBase.id == uuid.UUID(request.matchdict['id'])).first() + account = request.dbsession.query(AccountBase).filter(AccountBase.id == uuid.UUID(request.matchdict['id'])).first() start_date = request.GET.get('s', session_period_start(request)) finish_date = request.GET.get('f', session_period_finish(request)) info = {'startDate': start_date, 'finishDate': finish_date, - 'account': {'id': ledger.id, 'name': ledger.name}, + 'account': {'id': account.id, 'name': account.name}, 'body': []} build_report(request, info) return info @@ -46,8 +46,8 @@ def build_report(request, info): opening = opening_balance(account_id, start_date, request.dbsession) info['body'].append(opening) - query = request.dbsession.query(Voucher).options(joinedload_all(Voucher.journals, Journal.ledger, innerjoin=True)) \ - .filter(Voucher.journals.any(Journal.ledger_id == account_id)) \ + query = request.dbsession.query(Voucher).options(joinedload_all(Voucher.journals, Journal.account, innerjoin=True)) \ + .filter(Voucher.journals.any(Journal.account_id == account_id)) \ .filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \ @@ -59,7 +59,7 @@ def build_report(request, info): journal_debit = 0 name = "" for journal in voucher.journals: - if journal.ledger_id == account_id: + if journal.account_id == account_id: journal_debit = journal.debit if journal.debit == 1: debit = journal.amount @@ -69,7 +69,7 @@ def build_report(request, info): debit = 0 for journal in voucher.journals: if journal.debit != journal_debit: - name += "{0} / ".format(journal.ledger.name) + name += "{0} / ".format(journal.account.name) name = name[:-3] info['body'].append( {'id': voucher.id, 'date': voucher.date.strftime('%d-%b-%Y'), 'name': name, @@ -82,7 +82,7 @@ def opening_balance(account_id, start_date, dbsession): .join(Journal.voucher) \ .filter(Voucher.date < datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .filter(Journal.ledger_id == account_id) \ + .filter(Journal.account_id == account_id) \ .scalar() opening = 0 if opening is None else opening if opening < 0: diff --git a/brewman/views/reports/net_transactions.py b/brewman/views/reports/net_transactions.py index f4e972f9..a8c42924 100644 --- a/brewman/views/reports/net_transactions.py +++ b/brewman/views/reports/net_transactions.py @@ -5,7 +5,7 @@ from sqlalchemy.sql.expression import func, desc from pyramid.view import view_config -from brewman.models.master import LedgerBase +from brewman.models.master import AccountBase from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.views.services.session import session_period_finish, session_period_start @@ -37,16 +37,16 @@ def build_report(start_date, finish_date, dbsession): finish_date = datetime.datetime.strptime(finish_date, '%d-%b-%Y') amount_sum = func.sum(Journal.amount * Journal.debit).label('amount') - query = dbsession.query(LedgerBase, amount_sum) \ - .join(Journal.voucher).join(Journal.ledger) \ + query = dbsession.query(AccountBase, amount_sum) \ + .join(Journal.voucher).join(Journal.account) \ .filter(Voucher.date >= start_date) \ .filter(Voucher.date <= finish_date) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .group_by(LedgerBase).order_by(LedgerBase.type).order_by(desc(func.abs(amount_sum))).all() + .group_by(AccountBase).order_by(AccountBase.type).order_by(desc(func.abs(amount_sum))).all() body = [] - for ledger, amount in query: + for account, amount in query: if amount != 0: tag = 'debit' if amount > 0 else 'credit' - body.append({'type': ledger.type_object.name, 'name': ledger.name, tag: amount}) + body.append({'type': account.type_object.name, 'name': account.name, tag: amount}) return body diff --git a/brewman/views/reports/product_ledger.py b/brewman/views/reports/product_ledger.py index 7571c578..09b43c08 100644 --- a/brewman/views/reports/product_ledger.py +++ b/brewman/views/reports/product_ledger.py @@ -58,7 +58,7 @@ def build_report(request, info, dbsession): info['body'].append(opening) query = request.dbsession.query(Voucher, Inventory, Journal).options( - joinedload(Journal.ledger, innerjoin=True), + joinedload(Journal.account, innerjoin=True), joinedload(Journal.cost_centre, innerjoin=True)) \ .filter(Voucher.id == Inventory.voucher_id) \ .filter(Voucher.id == Journal.voucher_id) \ @@ -71,7 +71,7 @@ def build_report(request, info, dbsession): for row in query: journal_debit = row.Journal.debit * -1 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.account.name debit_q = row.Inventory.quantity if journal_debit == 1 else 0 debit_a = row.Inventory.amount if journal_debit == 1 else 0 credit_q = row.Inventory.quantity if journal_debit != 1 else 0 diff --git a/brewman/views/reports/profit_loss.py b/brewman/views/reports/profit_loss.py index 0c16b6d4..c5a5f80b 100644 --- a/brewman/views/reports/profit_loss.py +++ b/brewman/views/reports/profit_loss.py @@ -5,7 +5,7 @@ from pyramid.response import FileResponse from pyramid.view import view_config from sqlalchemy.sql.expression import func, desc -from brewman.models.master import LedgerType, LedgerBase +from brewman.models.master import AccountType, AccountBase from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.views.reports.closing_stock import get_opening_stock, get_closing_stock from brewman.views.services.session import session_period_start, session_period_finish @@ -34,18 +34,18 @@ def get_profit_loss(request): def build_profit_loss(start_date, finish_date, dbsession): - profit_type_list = [i.id for i in LedgerType.list() if i.balance_sheet == False] + profit_type_list = [i.id for i in AccountType.list() if i.balance_sheet == False] report = [] groups = dict() amount_sum = func.sum(Journal.amount * Journal.debit) - query = dbsession.query(LedgerBase, amount_sum) \ - .join(Journal.voucher).join(Journal.ledger) \ + query = dbsession.query(AccountBase, amount_sum) \ + .join(Journal.voucher).join(Journal.account) \ .filter(Voucher.date >= start_date) \ .filter(Voucher.date <= finish_date) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .filter(LedgerBase.type.in_(profit_type_list)) \ - .group_by(LedgerBase).order_by(LedgerBase.type).order_by(desc(func.abs(amount_sum))).all() + .filter(AccountBase.type.in_(profit_type_list)) \ + .group_by(AccountBase).order_by(AccountBase.type).order_by(desc(func.abs(amount_sum))).all() # Get opening / closing stock opening_stock = get_opening_stock(start_date, dbsession) @@ -54,23 +54,23 @@ def build_profit_loss(start_date, finish_date, dbsession): report.append({'name': 'Opening Stock', 'amount': opening_stock * -1, 'order': 20.0001}) report.append({'name': 'Closing Stock', 'amount': closing_stock, 'order': 29}) - purchase_group = LedgerType.by_id(2) + purchase_group = AccountType.by_id(2) groups[purchase_group.id] = {'group': purchase_group.name, 'total': total_amount, 'order': purchase_group.order} counter = 0 - for ledger, amount in query: + for account, amount in query: # Add Items amount *= -1 - ledger_type = LedgerType.by_id(ledger.type) + account_type = AccountType.by_id(account.type) total_amount += amount if amount != 0: counter += .001 - report.append({'name': ledger.name, 'amount': amount, 'order': ledger_type.order + counter}) - if ledger_type.id in groups: - groups[ledger_type.id]['total'] += amount + report.append({'name': account.name, 'amount': amount, 'order': account_type.order + counter}) + if account_type.id in groups: + groups[account_type.id]['total'] += amount else: - groups[ledger_type.id] = {'group': ledger_type.name, 'total': amount, 'order': ledger_type.order} + groups[account_type.id] = {'group': account_type.name, 'total': amount, 'order': account_type.order} # Add Subtotals for item in groups.values(): @@ -83,12 +83,12 @@ def build_profit_loss(start_date, finish_date, dbsession): def get_accumulated_profit(finish_date, dbsession): - type_list = [i.id for i in LedgerType.list() if i.balance_sheet is False] + type_list = [i.id for i in AccountType.list() if i.balance_sheet is False] accumulated_profit = dbsession.query(func.sum(Journal.amount * Journal.debit)) \ - .join(Journal.voucher).join(Journal.ledger) \ + .join(Journal.voucher).join(Journal.account) \ .filter(Voucher.date <= finish_date) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .filter(LedgerBase.type.in_(type_list)) \ + .filter(AccountBase.type.in_(type_list)) \ .scalar() return 0 if accumulated_profit is None else accumulated_profit diff --git a/brewman/views/reports/purchase_entries.py b/brewman/views/reports/purchase_entries.py index f979d14e..5f7a98e1 100644 --- a/brewman/views/reports/purchase_entries.py +++ b/brewman/views/reports/purchase_entries.py @@ -47,7 +47,7 @@ def build_report(request, start_date, finish_date): for item in voucher.inventories: row = { 'date': voucher.date.strftime('%d-%b-%Y'), - 'supplier': journal.ledger.name, + 'supplier': journal.account.name, 'url': get_edit_url(request, voucher), 'products': [], 'product': item.product.full_name, diff --git a/brewman/views/reports/raw_material_cost.py b/brewman/views/reports/raw_material_cost.py index 6475d577..040afd05 100644 --- a/brewman/views/reports/raw_material_cost.py +++ b/brewman/views/reports/raw_material_cost.py @@ -6,7 +6,7 @@ from pyramid.response import FileResponse from pyramid.view import view_config from sqlalchemy.sql.expression import func, case -from brewman.models.master import LedgerBase, CostCentre, Product, ProductGroup +from brewman.models.master import AccountBase, CostCentre, Product, ProductGroup from brewman.models.voucher import Voucher, Journal, Inventory from brewman.views.services.session import session_period_start, session_period_finish @@ -45,15 +45,15 @@ def report_id(request): def build_report(request, start_date, finish_date): report = {'startDate': start_date, 'finishDate': finish_date, 'body': [], 'footer': {}} - 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 * -1)], else_=0)).label('sale') + sum_issue = func.sum(case([(AccountBase.type == 2, Journal.signed_amount)], else_=0)).label('issue') + sum_sale = func.sum(case([(AccountBase.type == 3, Journal.signed_amount * -1)], else_=0)).label('sale') query = request.dbsession.query(CostCentre, sum_issue, sum_sale) \ - .join(CostCentre.journals).join(Journal.voucher).join(Journal.ledger) \ + .join(CostCentre.journals).join(Journal.voucher).join(Journal.account) \ .filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \ .filter(Journal.cost_centre_id != CostCentre.cost_centre_purchase()) \ - .filter(LedgerBase.type.in_([2, 3])) \ + .filter(AccountBase.type.in_([2, 3])) \ .group_by(CostCentre) \ .order_by(sum_sale.desc()).all() diff --git a/brewman/views/reports/reconcile.py b/brewman/views/reports/reconcile.py index 9ba03c1f..8e134b64 100644 --- a/brewman/views/reports/reconcile.py +++ b/brewman/views/reports/reconcile.py @@ -1,15 +1,14 @@ import datetime -import pkg_resources -from pyramid.response import FileResponse -from sqlalchemy.orm import joinedload_all -from sqlalchemy.sql.expression import func, or_, and_ import uuid -from pyramid.view import view_config +import pkg_resources import transaction +from pyramid.response import FileResponse +from pyramid.view import view_config +from sqlalchemy.orm import joinedload_all +from sqlalchemy.sql.expression import func, or_, and_ -from brewman.models.master import LedgerBase - +from brewman.models.master import AccountBase from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.views.services.session import session_period_start, session_period_finish from brewman.views.services.voucher import get_edit_url @@ -25,32 +24,32 @@ def html(request): @view_config(request_method='GET', route_name='api_reconcile', renderer='json', permission='Reconcile') def show_blank(request): - return {'StartDate': session_period_start(request), - 'FinishDate': session_period_finish(request), 'Ledger': None, 'Body': []} + return {'startDate': session_period_start(request), + 'finishDate': session_period_finish(request), 'account': None, 'body': []} @view_config(request_method='GET', route_name='api_reconcile_id', renderer='json', permission='Reconcile', trans=True) def show_data(request): - account = request.dbsession.query(LedgerBase).filter(LedgerBase.id == uuid.UUID(request.matchdict['id'])).first() - start_date = request.GET.get('StartDate', session_period_start(request)) - finish_date = request.GET.get('FinishDate', session_period_finish(request)) - info = {'StartDate': start_date, 'FinishDate': finish_date, - 'Account': {'LedgerID': account.id, 'Name': account.name}, 'Body': []} + account = request.dbsession.query(AccountBase).filter(AccountBase.id == uuid.UUID(request.matchdict['id'])).first() + start_date = request.GET.get('s', session_period_start(request)) + finish_date = request.GET.get('f', session_period_finish(request)) + info = {'startDate': start_date, 'finishDate': finish_date, + 'account': {'id': account.id, 'name': account.name}, 'body': []} build_report(request, info, request.dbsession) return info def build_report(request, info, dbsession): - ledger_id = info['Account']['LedgerID'] - start_date = info['StartDate'] - finish_date = info['FinishDate'] - opening = opening_balance(ledger_id, start_date, dbsession) - info['Body'].append(opening) + account_id = info['a`ccount']['id'] + start_date = info['startDate'] + finish_date = info['finishDate'] + opening = opening_balance(account_id, start_date, dbsession) + info['body'].append(opening) query = request.dbsession.query(Voucher).options( - joinedload_all(Voucher.journals, Journal.ledger, innerjoin=True) + joinedload_all(Voucher.journals, Journal.account, innerjoin=True) ).filter( - Voucher.journals.any(Journal.ledger_id == ledger_id) + Voucher.journals.any(Journal.account_id == account_id) ).filter( or_( Voucher.is_reconciled == False, @@ -69,7 +68,7 @@ def build_report(request, info, dbsession): journal_debit = 0 name = "" for journal in voucher.journals: - if journal.ledger_id == ledger_id: + if journal.account_id == account_id: journal_debit = journal.debit if journal.debit == 1: debit = journal.amount @@ -79,22 +78,22 @@ def build_report(request, info, dbsession): debit = 0 for journal in voucher.journals: if journal.debit != journal_debit: - name += "{0} / ".format(journal.ledger.name) + name += "{0} / ".format(journal.account.name) name = name[:-3] - info['Body'].append( - {'VoucherID': voucher.id, 'Date': voucher.date.strftime('%d-%b-%Y'), 'Name': name, - 'Url': get_edit_url(request, voucher), 'Type': VoucherType.by_id(voucher.type).name, - 'Narration': voucher.narration, 'Debit': debit, 'Credit': credit, 'IsReconciled': voucher.is_reconciled, - 'ReconcileDate': voucher.reconcile_date.strftime('%d-%b-%Y')}) + info['body'].append( + {'id': voucher.id, 'date': voucher.date.strftime('%d-%b-%Y'), 'name': name, + 'url': get_edit_url(request, voucher), 'type': VoucherType.by_id(voucher.type).name, + 'narration': voucher.narration, 'debit': debit, 'credit': credit, 'isReconciled': voucher.is_reconciled, + 'reconcileDate': voucher.reconcile_date.strftime('%d-%b-%Y')}) -def opening_balance(ledger_id, start_date, dbsession): +def opening_balance(account_id, start_date, dbsession): opening = dbsession.query(func.sum(Journal.amount * Journal.debit)) \ .join(Journal.voucher) \ .filter(Voucher.reconcile_date < datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(Voucher.is_reconciled == True) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .filter(Journal.ledger_id == ledger_id) \ + .filter(Journal.account_id == account_id) \ .scalar() opening = 0 if opening is None else opening if opening < 0: @@ -103,28 +102,30 @@ def opening_balance(ledger_id, start_date, dbsession): else: debit = opening credit = 0 - return {'Date': start_date, 'ID': 'OB', 'Name': 'Opening Balance', 'Type': 'Opening Balance', 'Narration': '', - 'Debit': debit, 'Credit': credit, 'Running': opening, 'IsReconciled': True, 'ReconcileDate': start_date} + return { + 'date': start_date, 'id': None, 'name': 'Opening Balance', 'type': 'Opening Balance', 'narration': '', + 'debit': debit, 'credit': credit, 'running': opening, 'isReconciled': True, 'reconcileDate': start_date + } @view_config(request_method='POST', route_name='api_reconcile_id', renderer='json', permission='Reconcile') def save(request): - account = request.dbsession.query(LedgerBase).filter(LedgerBase.id == uuid.UUID(request.matchdict['id'])).first() - start_date = request.GET.get('StartDate', session_period_start(request)) - finish_date = request.GET.get('FinishDate', session_period_finish(request)) - for item in request.json_body['Body']: - if 'VoucherID' not in item: + account = request.dbsession.query(AccountBase).filter(AccountBase.id == uuid.UUID(request.matchdict['id'])).first() + start_date = request.GET.get('s', session_period_start(request)) + finish_date = request.GET.get('f', session_period_finish(request)) + for item in request.json_body['body']: + if 'id' not in item or item['id'] is None: continue - voucher = request.dbsession.query(Voucher).filter(Voucher.id == uuid.UUID(item['VoucherID'])).first() - is_reconciled = item['IsReconciled'] - reconcile_date = datetime.datetime.strptime(item['ReconcileDate'], '%d-%b-%Y') + voucher = request.dbsession.query(Voucher).filter(Voucher.id == uuid.UUID(item['id'])).first() + is_reconciled = item['isReconciled'] + reconcile_date = datetime.datetime.strptime(item['reconcileDate'], '%d-%b-%Y') voucher.is_reconciled = is_reconciled voucher.reconcile_date = reconcile_date transaction.commit() - info = {'StartDate': start_date, 'FinishDate': finish_date, - 'Account': {'LedgerID': account.id, 'Name': account.name}, - 'Body': [], 'Footer': {}} + info = {'startDate': start_date, 'finishDate': finish_date, + 'account': {'id': account.id, 'name': account.name}, + 'body': [], 'footer': {}} build_report(request, info, request.dbsession) return info diff --git a/brewman/views/reports/trial_balance.py b/brewman/views/reports/trial_balance.py index 49b8837c..d1494503 100644 --- a/brewman/views/reports/trial_balance.py +++ b/brewman/views/reports/trial_balance.py @@ -5,7 +5,7 @@ from pyramid.response import FileResponse from pyramid.view import view_config from sqlalchemy.sql.expression import func -from brewman.models.master import LedgerBase +from brewman.models.master import AccountBase from brewman.models.voucher import Voucher, Journal, VoucherType from brewman.views.services.session import session_period_finish @@ -32,14 +32,14 @@ def report_data(request): def build_report(date, dbsession): date = datetime.datetime.strptime(date, '%d-%b-%Y') amount_sum = func.sum(Journal.amount * Journal.debit).label('amount') - query = dbsession.query(LedgerBase, amount_sum) \ - .join(Journal.voucher).join(Journal.ledger) \ - .filter(Voucher.date <= date).filter(Voucher.type != VoucherType.by_name('Issue').id).group_by(LedgerBase) \ - .order_by(LedgerBase.type).order_by(func.abs(amount_sum).desc()).all() + query = dbsession.query(AccountBase, amount_sum) \ + .join(Journal.voucher).join(Journal.account) \ + .filter(Voucher.date <= date).filter(Voucher.type != VoucherType.by_name('Issue').id).group_by(AccountBase) \ + .order_by(AccountBase.type).order_by(func.abs(amount_sum).desc()).all() body = [] - for ledger, amount in query: + for account, amount in query: if amount != 0: tag = 'debit' if amount > 0 else 'credit' - body.append({'type': ledger.type_object.name, 'name': ledger.name, tag: amount}) + body.append({'type': account.type_object.name, 'name': account.name, tag: amount}) return body diff --git a/brewman/views/reports/unposted.py b/brewman/views/reports/unposted.py index 0f814600..b2cda25a 100644 --- a/brewman/views/reports/unposted.py +++ b/brewman/views/reports/unposted.py @@ -22,10 +22,15 @@ def report_data(request): def build_report(request): body = [] - query = request.dbsession.query(Voucher).options(joinedload_all(Voucher.journals, Journal.ledger, innerjoin=True)) \ - .filter(Voucher.posted == False) \ - .filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .order_by(Voucher.date).order_by(Voucher.last_edit_date).all() + query = request.dbsession.query( + Voucher + ).options( + joinedload_all(Voucher.journals, Journal.account, innerjoin=True) + ).filter( + Voucher.posted == False + ).filter( + Voucher.type != VoucherType.by_name('Issue').id + ).order_by(Voucher.date).order_by(Voucher.last_edit_date).all() for voucher in query: debit = 0 @@ -35,10 +40,10 @@ def build_report(request): for journal in voucher.journals: if journal.debit == 1: debit += journal.amount - name_debit += "{0} / ".format(journal.ledger.name) + name_debit += "{0} / ".format(journal.account.name) else: credit += journal.amount - name_credit += "{0} / ".format(journal.ledger.name) + name_credit += "{0} / ".format(journal.account.name) name_debit = name_debit[:-3] name_credit = name_credit[:-3] diff --git a/brewman/views/services/voucher/__init__.py b/brewman/views/services/voucher/__init__.py index 7e6ffafb..13764f31 100644 --- a/brewman/views/services/voucher/__init__.py +++ b/brewman/views/services/voucher/__init__.py @@ -9,7 +9,7 @@ from pyramid.view import view_config from sqlalchemy import func, or_ from brewman.models.auth import User -from brewman.models.master import LedgerBase, CostCentre, Employee, AttendanceType, Ledger +from brewman.models.master import AccountBase, CostCentre, Employee, AttendanceType, Account from brewman.models.validation_exception import ValidationError from brewman.models.voucher import Voucher, VoucherType, Inventory, DbImage, Attendance, Journal from brewman.views import get_lock_info @@ -149,6 +149,7 @@ def get_old(request): def voucher_info(voucher, request): json_voucher = {'id': voucher.id, 'date': voucher.date.strftime('%d-%b-%Y'), + 'isStarred': voucher.is_starred, 'type': VoucherType.by_id(voucher.type).name, 'posted': voucher.posted, 'narration': voucher.narration, @@ -165,7 +166,7 @@ def voucher_info(voucher, request): json_voucher['reconcileDate'] = voucher.reconcile_date.strftime('%d-%b-%Y %H:%M') for item in voucher.journals: json_voucher['journals'].append({'id': item.id, 'debit': item.debit, 'amount': item.amount, - 'account': {'id': item.ledger.id, 'name': item.ledger.name}, + 'account': {'id': item.account.id, 'name': item.account.name}, 'costCentre': {'id': item.cost_centre_id}}) for item in voucher.salary_deductions: json_voucher['employeeBenefits'].append( @@ -176,19 +177,22 @@ def voucher_info(voucher, request): 'esiEmployer': item.esi_er, 'pfEmployer': item.pf_er, 'journal': {'id': item.journal.id, - 'account': {'id': item.journal.ledger.id, 'name': item.journal.ledger.name, - 'designation': item.journal.ledger.designation, - 'costCentre': {'id': item.journal.ledger.cost_centre.id, - 'name': item.journal.ledger.cost_centre.name}}}}) + 'account': {'id': item.journal.account.id, 'name': item.journal.account.name, + 'designation': item.journal.account.designation, + 'costCentre': {'id': item.journal.account.cost_centre.id, + 'name': item.journal.account.cost_centre.name}}}}) for item in voucher.service_charges: - employee = request.dbsession.query(Employee).filter(Employee.id == item.journal.ledger_id).first() + employee = request.dbsession.query(Employee).filter(Employee.id == item.journal.account_id).first() json_voucher['incentives'].append( - {'id': item.journal.ledger_id, 'name': item.journal.ledger.name, - 'designation': employee.designation, - 'department': item.journal.ledger.cost_centre.name, 'daysWorked': item.days_worked, 'points': item.points}) + { + 'id': item.journal.account_id, 'name': item.journal.account.name, 'designation': employee.designation, + 'department': item.journal.account.cost_centre.name, 'daysWorked': item.days_worked, + 'points': item.points + } + ) if len(json_voucher['incentives']) > 0: json_voucher['incentive'] = [x.amount for x in voucher.journals if - x.ledger_id == Ledger.service_charge_id()][0] + x.account_id == Account.service_charge_id()][0] for item in voucher.inventories: text = "{0} ({1}) {2:.2f}@{3:.2f} from {4}".format(item.product.name, item.product.units, item.batch.quantity_remaining, item.batch.rate, @@ -232,48 +236,51 @@ def blank_voucher(info, dbsession): type = info['type'] if 'date' not in info: raise ValidationError('Date cannot be null') - json_voucher = {'type': type, 'date': info['date'], 'posted': False, 'narration': "", 'journals': [], - 'inventories': []} + json_voucher = { + 'type': type, 'date': info['date'], + 'isStarred': False, 'posted': False, + 'narration': "", 'journals': [], 'inventories': [] + } if type == 'Journal': pass elif type == 'Payment': - ledger = None + account = None if info is not None and 'account' in info and info['account'] is not None: - ledger = dbsession.query(LedgerBase).filter(LedgerBase.id == uuid.UUID(info['account'])).first() - if ledger is not None: - ledger = {'id': ledger.id, 'name': ledger.name} + account = dbsession.query(AccountBase).filter(AccountBase.id == uuid.UUID(info['account'])).first() + if account is not None: + account = {'id': account.id, 'name': account.name} else: - ledger = LedgerBase.cash_in_hand() - json_voucher['journals'].append({'account': ledger, 'amount': 0, 'debit': -1}) + account = AccountBase.cash_in_hand() + json_voucher['journals'].append({'account': account, 'amount': 0, 'debit': -1}) elif type == 'Receipt': - ledger = None + account = None if info is not None and 'account' in info and info['account'] is not None: - ledger = dbsession.query(LedgerBase).filter(LedgerBase.id == uuid.UUID(info['account'])).first() - if ledger is not None: - ledger = {'id': ledger.id, 'name': ledger.name} + account = dbsession.query(AccountBase).filter(AccountBase.id == uuid.UUID(info['account'])).first() + if account is not None: + account = {'id': account.id, 'name': account.name} else: - ledger = LedgerBase.cash_in_hand() - json_voucher['journals'].append({'account': ledger, 'amount': 0, 'debit': 1}) + account = AccountBase.cash_in_hand() + json_voucher['journals'].append({'account': account, 'amount': 0, 'debit': 1}) elif type == 'Purchase': - json_voucher['journals'].append({'account': LedgerBase.local_purchase(), 'amount': 0, 'debit': -1}) + json_voucher['journals'].append({'account': AccountBase.local_purchase(), 'amount': 0, 'debit': -1}) elif type == 'Purchase Return': - json_voucher['journals'].append({'account': LedgerBase.local_purchase(), 'amount': 0, 'debit': 1}) + json_voucher['journals'].append({'account': AccountBase.local_purchase(), 'amount': 0, 'debit': 1}) elif type == 'Issue': if 'dource' in info and 'destination' in info: - json_voucher['journals'].append({'account': {'id': LedgerBase.all_purchases()}, + json_voucher['journals'].append({'account': {'id': AccountBase.all_purchases()}, 'amount': 0, 'debit': -1, 'costCentre': {'id': info['source']}}) - json_voucher['journals'].append({'account': {'id': LedgerBase.all_purchases()}, + json_voucher['journals'].append({'account': {'id': AccountBase.all_purchases()}, 'amount': 0, 'debit': 1, 'costCentre': {'id': info['destination']}}) elif 'journals' not in info: - json_voucher['journals'].append({'account': {'id': LedgerBase.all_purchases()}, + json_voucher['journals'].append({'account': {'id': AccountBase.all_purchases()}, 'amount': 0, 'debit': -1, 'costCentre': {'id': CostCentre.cost_centre_purchase()}}) - json_voucher['journals'].append({'account': {'id': LedgerBase.all_purchases()}, + json_voucher['journals'].append({'account': {'id': AccountBase.all_purchases()}, 'amount': 0, 'debit': 1, 'costCentre': {'id': CostCentre.cost_centre_kitchen()}}) @@ -321,7 +328,7 @@ def service_charge_employees(date, dbsession): .join(Journal.voucher) \ .filter(Voucher.date < finish_date) \ .filter(Voucher.type != VoucherType.by_name('Issue').id) \ - .filter(Journal.ledger_id == Ledger.service_charge_id()) \ + .filter(Journal.account_id == Account.service_charge_id()) \ .scalar() amount = 0 if amount is None else amount * Decimal(.7) * Decimal(.9) * -1 return details, amount diff --git a/brewman/views/services/voucher/credit_salary.py b/brewman/views/services/voucher/credit_salary.py index 3dc41d63..5aee6c02 100644 --- a/brewman/views/services/voucher/credit_salary.py +++ b/brewman/views/services/voucher/credit_salary.py @@ -7,7 +7,7 @@ from sqlalchemy import or_ import transaction from ....models.auth import User -from ....models.master import Employee, AttendanceType, Ledger +from ....models.master import Employee, AttendanceType, Account from ....models.voucher import Voucher, VoucherType, Attendance, Journal from ..session import get_first_day, get_last_day @@ -51,7 +51,7 @@ def salary_journals(start_date, finish_date, dbsession): if att != 0: amount += att journals.append( - Journal(amount=att, debit=-1, ledger_id=employee.id, cost_centre_id=employee.cost_centre_id)) - salary = dbsession.query(Ledger).filter(Ledger.id == uuid.UUID(Ledger.salary()['id'])).first() - journals.append(Journal(amount=amount, debit=1, ledger_id=salary.id, cost_centre_id=salary.cost_centre_id)) + Journal(amount=att, debit=-1, account_id=employee.id, cost_centre_id=employee.cost_centre_id)) + salary = dbsession.query(Account).filter(Account.id == uuid.UUID(Account.salary()['id'])).first() + journals.append(Journal(amount=amount, debit=1, account_id=salary.id, cost_centre_id=salary.cost_centre_id)) return journals diff --git a/brewman/views/services/voucher/issue.py b/brewman/views/services/voucher/issue.py index 08e2a5e2..18c08a41 100644 --- a/brewman/views/services/voucher/issue.py +++ b/brewman/views/services/voucher/issue.py @@ -1,7 +1,7 @@ import datetime from decimal import Decimal import uuid -from brewman.models.master import CostCentre, LedgerBase +from brewman.models.master import CostCentre, AccountBase from brewman.models.operations import journals_valid, inventory_valid from brewman.models.validation_exception import ValidationError from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journal @@ -63,9 +63,9 @@ def issue_create_journals(inventories, source, destination): amount = 0 for item in inventories: amount += item.amount - return [Journal(debit=-1, ledger_id=LedgerBase.all_purchases(), amount=round(amount, 2), + return [Journal(debit=-1, account_id=AccountBase.all_purchases(), amount=round(amount, 2), cost_centre_id=source), - Journal(debit=1, ledger_id=LedgerBase.all_purchases(), amount=round(amount, 2), + Journal(debit=1, account_id=AccountBase.all_purchases(), amount=round(amount, 2), cost_centre_id=destination)] diff --git a/brewman/views/services/voucher/journal.py b/brewman/views/services/voucher/journal.py index 79f9631b..8e19d61d 100644 --- a/brewman/views/services/voucher/journal.py +++ b/brewman/views/services/voucher/journal.py @@ -1,22 +1,26 @@ import datetime -from decimal import Decimal import uuid +from decimal import Decimal -from brewman.models.master import LedgerBase +from brewman.models.master import AccountBase from brewman.models.operations import journals_valid from brewman.models.voucher import Journal, Voucher, VoucherType, DbImage def journal_create_voucher(json, files, user, dbsession): dt = datetime.datetime.strptime(json['date'], '%d-%b-%Y') - voucher = Voucher(date=dt, narration=json['narration'], user_id=user.id, type=VoucherType.by_name(json['type'])) + voucher = Voucher( + date=dt, narration=json['narration'], + is_starred=json['isStarred'], + user_id=user.id, type=VoucherType.by_name(json['type']) + ) dbsession.add(voucher) for item in json['journals']: - ledger = dbsession.query(LedgerBase).filter(LedgerBase.id == uuid.UUID(item['account']['id'])).first() + account = dbsession.query(AccountBase).filter(AccountBase.id == uuid.UUID(item['account']['id'])).first() journal_id = uuid.UUID(item['id']) if 'id' in item and item['id'] is not None else None amount = round(Decimal(item['amount']), 2) - journal = Journal(id=journal_id, amount=amount, debit=int(item['debit']), ledger_id=ledger.id, - cost_centre_id=ledger.cost_centre_id) + journal = Journal(id=journal_id, amount=amount, debit=int(item['debit']), account_id=account.id, + cost_centre_id=account.cost_centre_id) voucher.journals.append(journal) dbsession.add(journal) journals_valid(voucher) @@ -27,6 +31,7 @@ def journal_create_voucher(json, files, user, dbsession): def journal_update_voucher(voucher, json, files, user, dbsession): voucher.date = datetime.datetime.strptime(json['date'], '%d-%b-%Y') + voucher.is_starred = json['isStarred'] voucher.narration = json['narration'] voucher.user_id = user.id voucher.posted = False @@ -39,27 +44,28 @@ def journal_update_voucher(voucher, json, files, user, dbsession): for j in range(len(new_journals), 0, -1): new_item = new_journals[j - 1] if 'id' in new_item and new_item['id'] is not None and item.id == uuid.UUID(new_item['id']): - ledger = dbsession.query(LedgerBase).filter( - LedgerBase.id == uuid.UUID(new_item['account']['id'])).first() + account = dbsession.query(AccountBase).filter( + AccountBase.id == uuid.UUID(new_item['account']['id']) + ).first() found = True item.debit = int(new_item['debit']) item.amount = round(Decimal(new_item['amount']), 2) - item.ledger_id = ledger.id - item.cost_centre_id = ledger.cost_centre_id + item.account_id = account.id + item.cost_centre_id = account.cost_centre_id new_journals.remove(new_item) break if not found: voucher.journals.remove(item) for new_item in new_journals: - ledger = dbsession.query(LedgerBase).filter(LedgerBase.id == uuid.UUID(new_item['account']['id'])).first() + account = dbsession.query(AccountBase).filter(AccountBase.id == uuid.UUID(new_item['account']['id'])).first() journal = Journal(id=None, amount=round(Decimal(new_item['amount']), 2), debit=int(new_item['debit']), - ledger_id=ledger.id, - cost_centre_id=ledger.cost_centre_id) + account_id=account.id, + cost_centre_id=account.cost_centre_id) dbsession.add(journal) voucher.journals.append(journal) journals_valid(voucher) - old_files = [uuid.UUID(f['id']) for f in json['files'] if 'id' in f and f['id'] is not None ] + old_files = [uuid.UUID(f['id']) for f in json['files'] if 'id' in f and f['id'] is not None] images = dbsession.query(DbImage).filter(DbImage.resource_id == voucher.id).all() for image in [i for i in images if i.id not in old_files]: dbsession.delete(image) diff --git a/brewman/views/services/voucher/purchase.py b/brewman/views/services/voucher/purchase.py index e0f5f9c7..23fb22c9 100644 --- a/brewman/views/services/voucher/purchase.py +++ b/brewman/views/services/voucher/purchase.py @@ -1,10 +1,10 @@ import datetime -from decimal import Decimal import uuid +from decimal import Decimal from sqlalchemy import func -from brewman.models.master import Product, LedgerBase +from brewman.models.master import Product, AccountBase from brewman.models.operations import journals_valid, inventory_valid from brewman.models.validation_exception import ValidationError from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journal, DbImage @@ -12,7 +12,11 @@ from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journ def purchase_create_voucher(json, files, user, dbsession): dt = datetime.datetime.strptime(json['date'], '%d-%b-%Y') - voucher = Voucher(date=dt, narration=json['narration'], user_id=user.id, type=VoucherType.by_name(json['type'])) + voucher = Voucher( + date=dt, narration=json['narration'], + is_starred=json['isStarred'], + user_id=user.id, type=VoucherType.by_name(json['type']) + ) dbsession.add(voucher) for item in json['inventories']: @@ -48,27 +52,30 @@ def purchase_create_inventory(voucher, item, date, dbsession): dbsession.add(inventory) -def purchase_create_journals(inventories, ledger_id, dbsession): - other_ledger = dbsession.query(LedgerBase).filter(LedgerBase.id == uuid.UUID(ledger_id)).first() +def purchase_create_journals(inventories, account_id, dbsession): + other_account = dbsession.query(AccountBase).filter(AccountBase.id == uuid.UUID(account_id)).first() journals = dict() amount = 0 for item in inventories: product = dbsession.query(Product).filter(Product.id == item.product_id).first() - ledger = product.ledger + account = product.account item_amount = round(item.amount, 2) amount += item_amount - if ledger.id in journals: - journals[ledger.id].amount += item_amount + if account.id in journals: + journals[account.id].amount += item_amount else: - journals[ledger.id] = Journal(debit=1, cost_centre_id=ledger.cost_centre_id, ledger_id=ledger.id, - amount=item_amount) - journals[other_ledger.id] = Journal(debit=-1, cost_centre_id=other_ledger.cost_centre_id, ledger_id=other_ledger.id, - amount=amount) + journals[account.id] = Journal( + debit=1, cost_centre_id=account.cost_centre_id, account_id=account.id, amount=item_amount + ) + journals[other_account.id] = Journal( + debit=-1, cost_centre_id=other_account.cost_centre_id, account_id=other_account.id, amount=amount + ) return list(journals.values()) def purchase_update_voucher(voucher, json, files, user, dbsession): voucher.date = datetime.datetime.strptime(json['date'], '%d-%b-%Y') + voucher.is_starred = json['isStarred'] voucher.narration = json['narration'] voucher.user_id = user.id voucher.posted = False @@ -156,29 +163,32 @@ def purchase_update_inventory(voucher, new_inventories, dbsession): def purchase_update_journals(voucher, journals, dbsession): - other_ledger = [ff for ff in journals if ff['debit'] == -1] - other_ledger = dbsession.query(LedgerBase).filter( - LedgerBase.id == uuid.UUID(other_ledger[0]['account']['id'])).first() + other_account = [ff for ff in journals if ff['debit'] == -1] + other_account = dbsession.query(AccountBase).filter( + AccountBase.id == uuid.UUID(other_account[0]['account']['id']) + ).first() journals = dict() amount = 0 for item in voucher.inventories: product = dbsession.query(Product).filter(Product.id == item.product_id).first() - ledger = product.ledger + account = product.account amount += item.amount - if ledger.id in journals: - journals[ledger.id].amount += item.amount + if account.id in journals: + journals[account.id].amount += item.amount else: - journals[ledger.id] = Journal(debit=1, cost_centre_id=ledger.cost_centre_id, ledger_id=ledger.id, - amount=item.amount) - journals[other_ledger.id] = Journal(debit=-1, cost_centre_id=other_ledger.cost_centre_id, ledger_id=other_ledger.id, - amount=amount) + journals[account.id] = Journal( + debit=1, cost_centre_id=account.cost_centre_id, account_id=account.id, amount=item.amount + ) + journals[other_account.id] = Journal( + debit=-1, cost_centre_id=other_account.cost_centre_id, account_id=other_account.id, amount=amount + ) for i in range(len(voucher.journals), 0, -1): item = voucher.journals[i - 1] - if item.ledger_id in journals: - item.debit = journals[item.ledger_id].debit - item.amount = round(journals[item.ledger_id].amount, 2) - item.cost_centre_id = journals[item.ledger_id].cost_centre_id - del journals[item.ledger_id] + if item.account_id in journals: + item.debit = journals[item.account_id].debit + item.amount = round(journals[item.account_id].amount, 2) + item.cost_centre_id = journals[item.account_id].cost_centre_id + del journals[item.account_id] else: dbsession.delete(item) voucher.journals.remove(item) diff --git a/brewman/views/services/voucher/purchase_return.py b/brewman/views/services/voucher/purchase_return.py index a9db545c..4c4dafc0 100644 --- a/brewman/views/services/voucher/purchase_return.py +++ b/brewman/views/services/voucher/purchase_return.py @@ -1,7 +1,8 @@ import datetime -from decimal import Decimal import uuid -from brewman.models.master import Product, LedgerBase +from decimal import Decimal + +from brewman.models.master import Product, AccountBase from brewman.models.operations import inventory_valid, journals_valid from brewman.models.validation_exception import ValidationError from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journal, DbImage @@ -9,7 +10,11 @@ from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journ def purchase_return_create_voucher(json, files, user, dbsession): dt = datetime.datetime.strptime(json['date'], '%d-%b-%Y') - voucher = Voucher(date=dt, narration=json['narration'], user_id=user.id, type=VoucherType.by_name(json['type'])) + voucher = Voucher( + date=dt, narration=json['narration'], + is_starred=json['isStarred'], + user_id=user.id, type=VoucherType.by_name(json['type']) + ) dbsession.add(voucher) for item in json['inventories']: @@ -45,26 +50,29 @@ def purchase_return_create_inventory(voucher, item, dbsession): dbsession.add(item) -def purchase_return_create_journals(inventories, ledger_id, dbsession): - other_ledger = dbsession.query(LedgerBase).filter(LedgerBase.id == uuid.UUID(ledger_id)).first() +def purchase_return_create_journals(inventories, account_id, dbsession): + other_account = dbsession.query(AccountBase).filter(AccountBase.id == uuid.UUID(account_id)).first() journals = dict() amount = 0 for item in inventories: product = dbsession.query(Product).filter(Product.id == item.product_id).first() - ledger = product.ledger + account = product.account amount += round(item.amount, 2) - if ledger.id in journals: - journals[ledger.id].amount += round(item.amount, 2) + if account.id in journals: + journals[account.id].amount += round(item.amount, 2) else: - journals[ledger.id] = Journal(debit=-1, cost_centre_id=ledger.cost_centre_id, ledger_id=ledger.id, - amount=round(item.amount, 2)) - journals[other_ledger.id] = Journal(debit=1, cost_centre_id=other_ledger.cost_centre_id, ledger_id=other_ledger.id, - amount=amount) + journals[account.id] = Journal( + debit=-1, cost_centre_id=account.cost_centre_id, account_id=account.id, amount=round(item.amount, 2) + ) + journals[other_account.id] = Journal( + debit=1, cost_centre_id=other_account.cost_centre_id, account_id=other_account.id, amount=amount + ) return list(journals.values()) def purchase_return_update_voucher(voucher, json, files, user, dbsession): voucher.date = datetime.datetime.strptime(json['date'], '%d-%b-%Y') + voucher.is_starred = json['isStarred'] voucher.narration = json['narration'] voucher.user_id = user.id voucher.posted = False @@ -119,29 +127,31 @@ def purchase_return_update_inventory(voucher, new_inventories, date, dbsession): def purchase_return_update_journals(voucher, journals, dbsession): - other_ledger = [ff for ff in journals if ff['debit'] == 1] - other_ledger = dbsession.query(LedgerBase).filter( - LedgerBase.id == uuid.UUID(other_ledger[0]['account']['id'])).first() + other_account = [ff for ff in journals if ff['debit'] == 1] + other_account = dbsession.query(AccountBase).filter( + AccountBase.id == uuid.UUID(other_account[0]['account']['id'])).first() journals = dict() amount = 0 for item in voucher.inventories: product = dbsession.query(Product).filter(Product.id == item.product_id).first() - ledger = product.ledger + account = product.account amount += round(item.amount, 2) - if ledger.id in journals: - journals[ledger.id].amount += round(item.amount, 2) + if account.id in journals: + journals[account.id].amount += round(item.amount, 2) else: - journals[ledger.id] = Journal(debit=-1, cost_centre_id=ledger.cost_centre_id, ledger_id=ledger.id, - amount=round(item.amount, 2)) - journals[other_ledger.id] = Journal(debit=1, cost_centre_id=other_ledger.cost_centre_id, ledger_id=other_ledger.id, - amount=amount) + journals[account.id] = Journal( + debit=-1, cost_centre_id=account.cost_centre_id, account_id=account.id, amount=round(item.amount, 2) + ) + journals[other_account.id] = Journal( + debit=1, cost_centre_id=other_account.cost_centre_id, account_id=other_account.id, amount=amount + ) for i in range(len(voucher.journals), 0, -1): item = voucher.journals[i - 1] - if item.ledger_id in journals: - item.debit = journals[item.ledger_id].debit - item.amount = journals[item.ledger_id].amount - item.cost_centre_id = journals[item.ledger_id].cost_centre_id - del journals[item.ledger_id] + if item.account_id in journals: + item.debit = journals[item.account_id].debit + item.amount = journals[item.account_id].amount + item.cost_centre_id = journals[item.account_id].cost_centre_id + del journals[item.account_id] else: dbsession.delete(item) voucher.journals.remove(item) diff --git a/brewman/views/services/voucher/salary_deduction.py b/brewman/views/services/voucher/salary_deduction.py index 0a7bf863..1f83150c 100644 --- a/brewman/views/services/voucher/salary_deduction.py +++ b/brewman/views/services/voucher/salary_deduction.py @@ -1,7 +1,7 @@ import datetime from math import ceil import uuid -from brewman.models.master import LedgerBase, Employee +from brewman.models.master import AccountBase, Employee from brewman.models.operations import journals_valid from brewman.models.validation_exception import ValidationError from brewman.models.voucher import Journal, Voucher, VoucherType, SalaryDeduction @@ -18,12 +18,12 @@ def salary_deduction_create_voucher(json, user, dbsession): item_exp, item_total = add_salary_deduction(item, days_in_month, voucher, dbsession) exp += item_exp total += item_total - ledger = dbsession.query(LedgerBase).filter(LedgerBase.id == LedgerBase.esi_pf_expense()).first() - journal = Journal(amount=exp, debit=1, ledger_id=ledger.id, cost_centre_id=ledger.cost_centre_id) + account = dbsession.query(AccountBase).filter(AccountBase.id == AccountBase.esi_pf_expense()).first() + journal = Journal(amount=exp, debit=1, account_id=account.id, cost_centre_id=account.cost_centre_id) dbsession.add(journal) voucher.journals.append(journal) - ledger = dbsession.query(LedgerBase).filter(LedgerBase.id == LedgerBase.esi_pf_payable()).first() - journal = Journal(amount=total, debit=-1, ledger_id=ledger.id, cost_centre_id=ledger.cost_centre_id) + account = dbsession.query(AccountBase).filter(AccountBase.id == AccountBase.esi_pf_payable()).first() + journal = Journal(amount=total, debit=-1, account_id=account.id, cost_centre_id=account.cost_centre_id) dbsession.add(journal) voucher.journals.append(journal) @@ -61,10 +61,10 @@ def salary_deduction_update_voucher(voucher, json, user, dbsession): exp += item_exp total += item_total - journal = [i for i in voucher.journals if i.ledger_id == LedgerBase.esi_pf_expense()] + journal = [i for i in voucher.journals if i.account_id == AccountBase.esi_pf_expense()] journal = journal[0] journal.amount = exp - journal = [i for i in voucher.journals if i.ledger_id == LedgerBase.esi_pf_payable()] + journal = [i for i in voucher.journals if i.account_id == AccountBase.esi_pf_payable()] journal = journal[0] journal.amount = total @@ -73,14 +73,16 @@ def salary_deduction_update_voucher(voucher, json, user, dbsession): def add_salary_deduction(item, days_in_month, voucher, dbsession): - ledger = dbsession.query(Employee).filter(Employee.id == uuid.UUID(item['journal']['account']['id'])).first() + account = dbsession.query(Employee).filter(Employee.id == uuid.UUID(item['journal']['account']['id'])).first() gross_salary = int(item['grossSalary']) days_worked = int(item['daysWorked']) 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) - 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, - pf_ee=pf_ee, esi_er=esi_er, pf_er=pf_er) + journal = Journal(amount=esi_ee + pf_ee, debit=1, account_id=account.id, cost_centre_id=account.cost_centre_id) + 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 + ) voucher.journals.append(journal) voucher.salary_deductions.append(sd) dbsession.add(journal) diff --git a/brewman/views/services/voucher/service_charge.py b/brewman/views/services/voucher/service_charge.py index 4da50bae..84d90659 100644 --- a/brewman/views/services/voucher/service_charge.py +++ b/brewman/views/services/voucher/service_charge.py @@ -4,7 +4,7 @@ from decimal import Decimal from sqlalchemy import or_, func -from brewman.models.master import Employee, AttendanceType, Ledger +from brewman.models.master import Employee, AttendanceType, Account 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 @@ -29,7 +29,7 @@ def service_charge_create_voucher(json, user, dbsession): 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) + journal = Journal(amount=item_amount, debit=-1, account_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) @@ -37,8 +37,8 @@ def service_charge_create_voucher(json, user, dbsession): dbsession.add(sc) total_amount += item_amount - sc = dbsession.query(Ledger).filter(Ledger.id == Ledger.service_charge_id()).first() - journal = Journal(amount=total_amount, debit=1, ledger_id=sc.id, cost_centre_id=sc.cost_centre_id) + sc = dbsession.query(Account).filter(Account.id == Account.service_charge_id()).first() + journal = Journal(amount=total_amount, debit=1, account_id=sc.id, cost_centre_id=sc.cost_centre_id) voucher.journals.append(journal) dbsession.add(journal) journals_valid(voucher) @@ -68,14 +68,14 @@ def service_charge_update_voucher(voucher, json, user, dbsession): total_amount = 0 for item in voucher.service_charges: - employee = [e for e in employees if e['employee'].id == item.journal.ledger_id][0] + employee = [e for e in employees if e['employee'].id == item.journal.account_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 = [j for j in voucher.journals if j.account_id == Account.service_charge_id()][0] journal.amount = total_amount journals_valid(voucher) @@ -115,7 +115,7 @@ def balance(date, voucher_id=None, dbsession=None): .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()) + .filter(Journal.account_id == Account.service_charge_id()) if voucher_id is not None: amount = amount.filter(Voucher.id != voucher_id) amount = amount.scalar() @@ -125,7 +125,7 @@ def balance(date, voucher_id=None, dbsession=None): def check_if_employees_changed(json, db, voucher): json = set([uuid.UUID(x['id']) for x in json]) db = set([x.id for x in db]) - voucher = set([x.ledger_id for x in voucher if x.ledger_id != Ledger.service_charge_id()]) if voucher is not None else None + voucher = set([x.account_id for x in voucher if x.account_id != Account.service_charge_id()]) if voucher is not None else None if voucher is None: if len(json ^ db) != 0: raise ValueError("Employee missing in json data") diff --git a/overlord/src/app/account/account-detail/account-detail.component.css b/overlord/src/app/account/account-detail/account-detail.component.css index e69de29b..1c0ef634 100644 --- a/overlord/src/app/account/account-detail/account-detail.component.css +++ b/overlord/src/app/account/account-detail/account-detail.component.css @@ -0,0 +1,7 @@ +.gold { + color: gold; +} + +.pointer { + cursor: pointer; +} diff --git a/overlord/src/app/account/account-detail/account-detail.component.html b/overlord/src/app/account/account-detail/account-detail.component.html index d6649996..fdb9e654 100644 --- a/overlord/src/app/account/account-detail/account-detail.component.html +++ b/overlord/src/app/account/account-detail/account-detail.component.html @@ -2,6 +2,9 @@ Account + + {{ item.isStarred ? 'star' : 'star_border' }} +
diff --git a/overlord/src/app/account/account-list/account-list.component.css b/overlord/src/app/account/account-list/account-list.component.css index e69de29b..3417e4c1 100644 --- a/overlord/src/app/account/account-list/account-list.component.css +++ b/overlord/src/app/account/account-list/account-list.component.css @@ -0,0 +1,3 @@ +.gold { + color: gold; +} diff --git a/overlord/src/app/account/account-list/account-list.component.html b/overlord/src/app/account/account-list/account-list.component.html index 3adc688e..dcee4408 100644 --- a/overlord/src/app/account/account-list/account-list.component.html +++ b/overlord/src/app/account/account-list/account-list.component.html @@ -20,7 +20,13 @@ Name - {{row.name}} + + + star + + {{row.name}} + + diff --git a/overlord/src/app/account/account.ts b/overlord/src/app/account/account.ts index 5352b569..e078ee28 100644 --- a/overlord/src/app/account/account.ts +++ b/overlord/src/app/account/account.ts @@ -9,6 +9,7 @@ export class Account { type: AccountType; isActive: boolean; isReconcilable: boolean; + isStarred: boolean; isFixture: boolean; costCentre: CostCentre; diff --git a/overlord/src/app/employee/employee-detail/employee-detail.component.ts b/overlord/src/app/employee/employee-detail/employee-detail.component.ts index ee3209a8..a83aaa6b 100644 --- a/overlord/src/app/employee/employee-detail/employee-detail.component.ts +++ b/overlord/src/app/employee/employee-detail/employee-detail.component.ts @@ -125,8 +125,8 @@ export class EmployeeDetailComponent implements OnInit, AfterViewInit { const formModel = this.form.value; this.item.name = formModel.name; this.item.designation = formModel.designation; - this.item.salary = formModel.salary; - this.item.points = formModel.points; + this.item.salary = +formModel.salary; + this.item.points = +formModel.points; this.item.isActive = formModel.isActive; this.item.costCentre.id = formModel.costCentre; this.item.joiningDate = moment(formModel.joiningDate).format('DD-MMM-YYYY'); diff --git a/overlord/src/app/journal/journal.component.css b/overlord/src/app/journal/journal.component.css index e28a55b0..73445292 100644 --- a/overlord/src/app/journal/journal.component.css +++ b/overlord/src/app/journal/journal.component.css @@ -34,3 +34,11 @@ mat-form-field.mat-form-field { font-size: 1.25em; } + +.gold { + color: gold; +} + +.pointer { + cursor: pointer; +} diff --git a/overlord/src/app/journal/journal.component.html b/overlord/src/app/journal/journal.component.html index 0c1df699..1065b4d2 100644 --- a/overlord/src/app/journal/journal.component.html +++ b/overlord/src/app/journal/journal.component.html @@ -1,6 +1,10 @@ Journal + + {{ voucher.isStarred ? 'star' : 'star_border' }} + diff --git a/overlord/src/app/journal/voucher.ts b/overlord/src/app/journal/voucher.ts index 87af682e..91d6212b 100644 --- a/overlord/src/app/journal/voucher.ts +++ b/overlord/src/app/journal/voucher.ts @@ -18,6 +18,7 @@ export class Voucher { creationDate: string; lastEditDate: string; user: User; + isStarred: boolean; poster: string; reconcileDate: string; } diff --git a/overlord/src/app/payment/payment.component.css b/overlord/src/app/payment/payment.component.css index e28a55b0..73445292 100644 --- a/overlord/src/app/payment/payment.component.css +++ b/overlord/src/app/payment/payment.component.css @@ -34,3 +34,11 @@ mat-form-field.mat-form-field { font-size: 1.25em; } + +.gold { + color: gold; +} + +.pointer { + cursor: pointer; +} diff --git a/overlord/src/app/payment/payment.component.html b/overlord/src/app/payment/payment.component.html index bc71d2ea..9b07e058 100644 --- a/overlord/src/app/payment/payment.component.html +++ b/overlord/src/app/payment/payment.component.html @@ -1,6 +1,10 @@ Payment + + {{ voucher.isStarred ? 'star' : 'star_border' }} + diff --git a/overlord/src/app/purchase-return/purchase-return.component.css b/overlord/src/app/purchase-return/purchase-return.component.css index e28a55b0..73445292 100644 --- a/overlord/src/app/purchase-return/purchase-return.component.css +++ b/overlord/src/app/purchase-return/purchase-return.component.css @@ -34,3 +34,11 @@ mat-form-field.mat-form-field { font-size: 1.25em; } + +.gold { + color: gold; +} + +.pointer { + cursor: pointer; +} diff --git a/overlord/src/app/purchase-return/purchase-return.component.html b/overlord/src/app/purchase-return/purchase-return.component.html index a030c2d6..c51ef7cf 100644 --- a/overlord/src/app/purchase-return/purchase-return.component.html +++ b/overlord/src/app/purchase-return/purchase-return.component.html @@ -1,6 +1,10 @@ Purchase Return + + {{ voucher.isStarred ? 'star' : 'star_border' }} + diff --git a/overlord/src/app/purchase/purchase.component.css b/overlord/src/app/purchase/purchase.component.css index e28a55b0..73445292 100644 --- a/overlord/src/app/purchase/purchase.component.css +++ b/overlord/src/app/purchase/purchase.component.css @@ -34,3 +34,11 @@ mat-form-field.mat-form-field { font-size: 1.25em; } + +.gold { + color: gold; +} + +.pointer { + cursor: pointer; +} diff --git a/overlord/src/app/purchase/purchase.component.html b/overlord/src/app/purchase/purchase.component.html index c74992b7..2871029f 100644 --- a/overlord/src/app/purchase/purchase.component.html +++ b/overlord/src/app/purchase/purchase.component.html @@ -1,6 +1,10 @@ Purchase + + {{ voucher.isStarred ? 'star' : 'star_border' }} + diff --git a/overlord/src/app/receipt/receipt.component.css b/overlord/src/app/receipt/receipt.component.css index e28a55b0..73445292 100644 --- a/overlord/src/app/receipt/receipt.component.css +++ b/overlord/src/app/receipt/receipt.component.css @@ -34,3 +34,11 @@ mat-form-field.mat-form-field { font-size: 1.25em; } + +.gold { + color: gold; +} + +.pointer { + cursor: pointer; +} diff --git a/overlord/src/app/receipt/receipt.component.html b/overlord/src/app/receipt/receipt.component.html index 4db70b86..6a65a1eb 100644 --- a/overlord/src/app/receipt/receipt.component.html +++ b/overlord/src/app/receipt/receipt.component.html @@ -1,6 +1,10 @@ Receipt + + {{ voucher.isStarred ? 'star' : 'star_border' }} + diff --git a/sql/2018.07.06 - starring.sql b/sql/2018.07.06 - starring.sql new file mode 100644 index 00000000..dcf06b4d --- /dev/null +++ b/sql/2018.07.06 - starring.sql @@ -0,0 +1,90 @@ +-- rename ledgers to accounts and add the is_starred column +CREATE TABLE accounts +( + id uuid NOT NULL, + code integer NOT NULL, + name character varying(255) NOT NULL, + type integer NOT NULL, + account_type character varying(50) NOT NULL, + is_starred boolean NOT NULL, + is_active boolean NOT NULL, + is_reconcilable boolean NOT NULL, + cost_centre_id uuid NOT NULL, + is_fixture boolean NOT NULL, + CONSTRAINT accounts_pkey PRIMARY KEY (id), + CONSTRAINT accounts_cost_centre_id_fkey FOREIGN KEY (cost_centre_id) + REFERENCES cost_centres ("CostCentreID"), + CONSTRAINT "accounts_name_key" UNIQUE (name) +); + +INSERT INTO accounts( + id, code, name, type, account_type, is_starred, is_active, + is_reconcilable, cost_centre_id, is_fixture) + SELECT "LedgerID", "Code", "Name", "Type", ledger_type, FALSE, "IsActive", + "IsReconcilable", "CostCentreID", "IsFixture" + FROM ledgers; + +ALTER TABLE employees RENAME COLUMN "LedgerID" TO id; +ALTER TABLE employees DROP CONSTRAINT "entities_employees_LedgerID_fkey"; +ALTER TABLE employees ADD CONSTRAINT "employees_id_fkey" FOREIGN KEY (id) + REFERENCES accounts (id); + + +ALTER TABLE journals RENAME COLUMN "LedgerID" TO account_id; +ALTER TABLE journals DROP CONSTRAINT "entities_journals_LedgerID_fkey"; +ALTER TABLE journals ADD CONSTRAINT "journals_account_id_fkey" FOREIGN KEY (account_id) + REFERENCES accounts (id); + +ALTER TABLE products RENAME COLUMN "LedgerID" TO account_id; +ALTER TABLE products DROP CONSTRAINT "products_LedgerID_fkey"; +ALTER TABLE products ADD CONSTRAINT "products_account_id_fkey" FOREIGN KEY (account_id) + REFERENCES accounts (id); + +DROP TABLE ledgers; + + +ALTER TABLE vouchers RENAME TO vouchers_old; + +CREATE TABLE vouchers +( + "VoucherID" uuid NOT NULL, + date timestamp without time zone NOT NULL, + narration character varying(1000) NOT NULL, + creation_date timestamp with time zone NOT NULL, + last_edit_date timestamp with time zone NOT NULL, + voucher_type integer NOT NULL, + is_posted boolean NOT NULL, + poster_id uuid, + user_id uuid NOT NULL, + is_reconciled boolean NOT NULL, + reconcile_date timestamp without time zone NOT NULL, + is_starred boolean NOT NULL, + CONSTRAINT vouchers_pkey PRIMARY KEY ("VoucherID"), + CONSTRAINT vouchers_poster_id_fkey FOREIGN KEY (poster_id) REFERENCES public.auth_users ("UserID"), + CONSTRAINT vouchers_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.auth_users ("UserID") +); + +INSERT INTO vouchers( + "VoucherID", date, reconcile_date, narration, creation_date, last_edit_date, + voucher_type, is_posted, poster_id, user_id, is_reconciled, is_starred) + SELECT "VoucherID", "Date", "ReconcileDate", "Narration", "CreationDate", "LastEditDate", + "VoucherType", "Posted", "PosterID", "UserID", "IsReconciled", FALSE + FROM vouchers_old; + +ALTER TABLE inventories DROP CONSTRAINT "entities_inventories_VoucherID_fkey"; +ALTER TABLE inventories ADD CONSTRAINT "inventories_VoucherID_fkey" FOREIGN KEY ("VoucherID") + REFERENCES vouchers ("VoucherID"); + +ALTER TABLE journals DROP CONSTRAINT "entities_journals_VoucherID_fkey"; +ALTER TABLE journals ADD CONSTRAINT "journals_VoucherID_fkey" FOREIGN KEY ("VoucherID") + REFERENCES vouchers ("VoucherID"); + +ALTER TABLE salary_deductions DROP CONSTRAINT "entities_salarydeductions_VoucherID_fkey"; +ALTER TABLE salary_deductions ADD CONSTRAINT "salary_deductions_VoucherID_fkey" FOREIGN KEY ("VoucherID") + REFERENCES vouchers ("VoucherID"); + +ALTER TABLE service_charges DROP CONSTRAINT service_charges_voucher_id_fkey; +ALTER TABLE service_charges ADD CONSTRAINT service_charges_voucher_id_fkey FOREIGN KEY (voucher_id) + REFERENCES vouchers ("VoucherID"); + +DROP TABLE vouchers_old; \ No newline at end of file