Added the Clents table to restrict the webapp on allowed clients via 10 yr long cookies and otp for intitial activation.
Added the reconcilable column to ledgers table for future implementation of reconcile account feature. Purchase return should work now at. Changed the class of add button in voucher forms to btn-info Edit in Payment and Receipt should be working now. JS Code Cleanup including missing ';', etc. Added 'use strict'; to all js files Added came_from in login in AngularJS. Fixed error in purchase where it would look for purchase_ledger instead of ledger of product. Added 'Clients' permission which is allowed remote logins and to authorize/deauthroize clients Added JDBC Sqlite provider for use in PyCharm
This commit is contained in:
1 parent
bccad85099
commit
16bbf37601
57 files changed
+899
-420
No files matched your search
@@ -78,8 +78,8 @@ def main(global_config, **settings):
|
|||||||
config.add_route('journal', '/Journal')
|
config.add_route('journal', '/Journal')
|
||||||
config.add_route('purchase_id', '/Purchase/{id}')
|
config.add_route('purchase_id', '/Purchase/{id}')
|
||||||
config.add_route('purchase', '/Purchase')
|
config.add_route('purchase', '/Purchase')
|
||||||
config.add_route('purchase_return_id', '/PurchaseReturn/{id}')
|
config.add_route('purchase_return_id', '/Return/{id}')
|
||||||
config.add_route('purchase_return', '/PurchaseReturn')
|
config.add_route('purchase_return', '/Return')
|
||||||
config.add_route('payment_id', '/Payment/{id}')
|
config.add_route('payment_id', '/Payment/{id}')
|
||||||
config.add_route('payment', '/Payment')
|
config.add_route('payment', '/Payment')
|
||||||
config.add_route('receipt_id', '/Receipt/{id}')
|
config.add_route('receipt_id', '/Receipt/{id}')
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import random
|
||||||
|
import string
|
||||||
import uuid
|
import uuid
|
||||||
from sqlalchemy.schema import ForeignKey, Table
|
from sqlalchemy.schema import ForeignKey, Table
|
||||||
from brewman.models.guidtype import GUID
|
from brewman.models.guidtype import GUID
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
|
|
||||||
from sqlalchemy import Column, Boolean, Unicode
|
from sqlalchemy import Column, Boolean, Unicode, Integer
|
||||||
|
|
||||||
from sqlalchemy.orm import synonym, relationship
|
from sqlalchemy.orm import synonym, relationship
|
||||||
|
|
||||||
@@ -14,12 +16,50 @@ def encrypt(val):
|
|||||||
return md5(val.encode('utf-8') + "Salt".encode('utf-8')).hexdigest()
|
return md5(val.encode('utf-8') + "Salt".encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
#class UserGroup(Base):
|
class Client(Base):
|
||||||
# __tablename__ = 'auth_usergroups'
|
__tablename__ = 'auth_clients'
|
||||||
#
|
|
||||||
# id = Column('UserGroupID', GUID(), primary_key=True)
|
id = Column('ClientID', GUID(), primary_key=True, default=uuid.uuid4)
|
||||||
# user_id = Column('UserID', GUID(), ForeignKey('auth_users.UserID'))
|
code = Column('Code', Integer, unique=True, nullable=False)
|
||||||
# group_id = Column('GroupID', GUID(), ForeignKey('auth_groups.GroupID'))
|
name = Column('Name', Unicode(255), unique=True, nullable=False)
|
||||||
|
enabled = Column('Enabled', Boolean, nullable=False)
|
||||||
|
otp = Column('OTP', Integer)
|
||||||
|
|
||||||
|
def __init__(self, code=None, name=None, enabled=False, otp=None):
|
||||||
|
self.code = code
|
||||||
|
self.name = name
|
||||||
|
self.enabled = enabled
|
||||||
|
self.otp = otp
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def by_id(cls, id):
|
||||||
|
if not isinstance(id, uuid.UUID):
|
||||||
|
id = uuid.UUID(id)
|
||||||
|
return DBSession.query(cls).filter(cls.id == id).first()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def by_code(cls, code):
|
||||||
|
if not isinstance(code, int):
|
||||||
|
code = int(code)
|
||||||
|
return DBSession.query(cls).filter(cls.code == code).first()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def list(cls):
|
||||||
|
return DBSession.query(cls).order_by(cls.name).all()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enabled_list(cls):
|
||||||
|
return DBSession.query(cls).filter(cls.enabled == True).order_by(cls.name).all()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls):
|
||||||
|
client_code = random.randint(1000, 9999)
|
||||||
|
otp = random.randint(1000, 9999)
|
||||||
|
name = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(6))
|
||||||
|
# name = str(client_code)
|
||||||
|
client = Client(client_code, name, False, otp)
|
||||||
|
DBSession.add(client)
|
||||||
|
return client
|
||||||
|
|
||||||
|
|
||||||
user_group = Table(
|
user_group = Table(
|
||||||
@@ -27,7 +67,7 @@ user_group = Table(
|
|||||||
Column('UserGroupID', GUID(), primary_key=True, default=uuid.uuid4),
|
Column('UserGroupID', GUID(), primary_key=True, default=uuid.uuid4),
|
||||||
Column('UserID', GUID(), ForeignKey('auth_users.UserID')),
|
Column('UserID', GUID(), ForeignKey('auth_users.UserID')),
|
||||||
Column('GroupID', GUID(), ForeignKey('auth_groups.GroupID'))
|
Column('GroupID', GUID(), ForeignKey('auth_groups.GroupID'))
|
||||||
)
|
)
|
||||||
|
|
||||||
#class RoleGroup(Base):
|
#class RoleGroup(Base):
|
||||||
# __tablename__ = 'auth_rolegroups'
|
# __tablename__ = 'auth_rolegroups'
|
||||||
@@ -37,12 +77,12 @@ user_group = Table(
|
|||||||
# group_id = Column('GroupID', GUID(), ForeignKey('auth_groups.GroupID'))
|
# group_id = Column('GroupID', GUID(), ForeignKey('auth_groups.GroupID'))
|
||||||
|
|
||||||
|
|
||||||
role_group = Table (
|
role_group = Table(
|
||||||
'auth_rolegroups', Base.metadata,
|
'auth_rolegroups', Base.metadata,
|
||||||
Column('RoleGroupID', GUID(), primary_key=True, default=uuid.uuid4),
|
Column('RoleGroupID', GUID(), primary_key=True, default=uuid.uuid4),
|
||||||
Column('RoleID', GUID(), ForeignKey('auth_roles.RoleID')),
|
Column('RoleID', GUID(), ForeignKey('auth_roles.RoleID')),
|
||||||
Column('GroupID', GUID(), ForeignKey('auth_groups.GroupID'))
|
Column('GroupID', GUID(), ForeignKey('auth_groups.GroupID'))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class User(Base):
|
class User(Base):
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ class LedgerBase(Base):
|
|||||||
type = Column('Type', Integer, nullable=False)
|
type = Column('Type', Integer, nullable=False)
|
||||||
ledger_type = Column('ledger_type', Unicode(50), nullable=False)
|
ledger_type = Column('ledger_type', Unicode(50), nullable=False)
|
||||||
is_active = Column('IsActive', Boolean)
|
is_active = Column('IsActive', Boolean)
|
||||||
|
is_reconcilable = Column('IsReconcilable', Boolean)
|
||||||
costcenter_id = Column('CostCenterID', GUID(), ForeignKey('entities_costcenters.CostCenterID'))
|
costcenter_id = Column('CostCenterID', GUID(), ForeignKey('entities_costcenters.CostCenterID'))
|
||||||
|
|
||||||
__mapper_args__ = {'polymorphic_on': ledger_type}
|
__mapper_args__ = {'polymorphic_on': ledger_type}
|
||||||
@@ -174,11 +175,12 @@ class LedgerBase(Base):
|
|||||||
def type_object(self):
|
def type_object(self):
|
||||||
return LedgerType.by_id(self.type)
|
return LedgerType.by_id(self.type)
|
||||||
|
|
||||||
def __init__(self, code=None, name=None, type=None, is_active=None, costcenter_id=None):
|
def __init__(self, code=None, name=None, type=None, is_active=None, is_reconcilable=False, costcenter_id=None):
|
||||||
self.code = code
|
self.code = code
|
||||||
self.name = name
|
self.name = name
|
||||||
self.type = type
|
self.type = type
|
||||||
self.is_active = is_active
|
self.is_active = is_active
|
||||||
|
self.is_reconcilable = is_reconcilable
|
||||||
self.costcenter_id = costcenter_id
|
self.costcenter_id = costcenter_id
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -253,7 +255,8 @@ class Employee(LedgerBase):
|
|||||||
self.service_points = service_points
|
self.service_points = service_points
|
||||||
self.joining_date = joining_date
|
self.joining_date = joining_date
|
||||||
self.leaving_date = leaving_date
|
self.leaving_date = leaving_date
|
||||||
super().__init__(code, name, 10, is_active, costcenter_id)
|
super().__init__(code=code, name=name, type=10, is_active=is_active, is_reconcilable=False,
|
||||||
|
costcenter_id=costcenter_id)
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
code = DBSession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == self.type).one()[0]
|
code = DBSession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == self.type).one()[0]
|
||||||
@@ -341,14 +344,14 @@ class LedgerType:
|
|||||||
list.append(LedgerType(5, 'Capital', True, False, False, 70, True))
|
list.append(LedgerType(5, 'Capital', True, False, False, 70, True))
|
||||||
list.append(LedgerType(6, 'Debtors', True, True, True, 30, True))
|
list.append(LedgerType(6, 'Debtors', True, True, True, 30, True))
|
||||||
list.append(LedgerType(7, 'Expenses', False, True, True, 40, True))
|
list.append(LedgerType(7, 'Expenses', False, True, True, 40, True))
|
||||||
# list.append(LedgerType(8, 'Discount', False, False, True, 30, True))
|
# list.append(LedgerType(8, 'Discount', False, False, True, 30, True))
|
||||||
list.append(LedgerType(9, 'Creditors', True, False, True, 60, True))
|
list.append(LedgerType(9, 'Creditors', True, False, True, 60, True))
|
||||||
list.append(LedgerType(10, 'Salary', True, True, True, 40, False))
|
list.append(LedgerType(10, 'Salary', True, True, True, 40, False))
|
||||||
list.append(LedgerType(11, 'Liabilities', True, False, True, 50, True))
|
list.append(LedgerType(11, 'Liabilities', True, False, True, 50, True))
|
||||||
list.append(LedgerType(12, 'Revenue', False, False, True, 30, True))
|
list.append(LedgerType(12, 'Revenue', False, False, True, 30, True))
|
||||||
# list.append(LedgerType(13, 'Tax', True, False, True, 80, True))
|
# list.append(LedgerType(13, 'Tax', True, False, True, 80, True))
|
||||||
# list.append(LedgerType(14, 'Total', False, False, False, 900, False))
|
# list.append(LedgerType(14, 'Total', False, False, False, 900, False))
|
||||||
# list.append(LedgerType(15, 'Net', False, False, False, 1000, False))
|
# list.append(LedgerType(15, 'Net', False, False, False, 1000, False))
|
||||||
return list
|
return list
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" ng-model="account.IsActive"> Is Active
|
<input type="checkbox" ng-model="account.IsActive"> Is Active
|
||||||
</label>
|
</label>
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" ng-model="account.IsReconcilable"> Is Reconcilable
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<th>Is Active?</th>
|
<th>Is Active?</th>
|
||||||
|
<th>Is Reconcilable?</th>
|
||||||
<th>Cost Center</th>
|
<th>Cost Center</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -13,6 +14,7 @@
|
|||||||
<td><a href="{{item.Url}}">{{item.Name}}</a></td>
|
<td><a href="{{item.Url}}">{{item.Name}}</a></td>
|
||||||
<td>{{item.Type}}</td>
|
<td>{{item.Type}}</td>
|
||||||
<td>{{item.IsActive}}</td>
|
<td>{{item.IsActive}}</td>
|
||||||
|
<td>{{item.IsReconcilable}}</td>
|
||||||
<td>{{item.CostCenter}}</td>
|
<td>{{item.CostCenter}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -67,14 +67,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=" control-group" id="add">
|
<div class=" control-group" id="add">
|
||||||
<label for="txtBatch" class="control-label">Add</label>
|
<label for="txtBatch" class="control-label">Product</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<autobatch id="txtBatch" url="/Services/Batches" selname="name"
|
<autobatch id="txtBatch" url="/Services/Batches" selname="name"
|
||||||
batch="batch" ng-model="name"></autobatch>
|
batch="batch" ng-model="name"></autobatch>
|
||||||
<input type="text" id="txtQuantity" class="span2" autocomplete="off"
|
<input type="text" id="txtQuantity" class="span2" autocomplete="off"
|
||||||
placeholder="Quantity" ng-model="quantity"/>
|
placeholder="Quantity" ng-model="quantity"/>
|
||||||
<button class="btn btn-success" ng-click="addInventory()">Add <i class="icon-plus-sign icon-white"></i>
|
<button class="btn btn-info" ng-click="addInventory()">Add <i class="icon-plus-sign icon-white"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=" control-group" id="add">
|
<div class=" control-group" id="add">
|
||||||
<label for="ddlDebitCredit" class="control-label">Add</label>
|
<label for="ddlDebitCredit" class="control-label">Account</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<select id="ddlDebitCredit" ng-model="debit">
|
<select id="ddlDebitCredit" ng-model="debit">
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<span class="add-on">₹</span><input type="text" id="txtAmount" class="span2" autocomplete="off"
|
<span class="add-on">₹</span><input type="text" id="txtAmount" class="span2" autocomplete="off"
|
||||||
placeholder="Amount" ng-model="amount"/>
|
placeholder="Amount" ng-model="amount"/>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn" ng-click="addJournal()">Add</button>
|
<button class="btn btn-info" ng-click="addJournal()">Add <i class="icon-plus-sign icon-white"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=" control-group">
|
<div class=" control-group">
|
||||||
@@ -38,18 +38,18 @@
|
|||||||
<table id="gvGrid" class="table clean-table">
|
<table id="gvGrid" class="table clean-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="Debit">Debit</th>
|
<th>Debit</th>
|
||||||
<th class="Name">Name</th>
|
<th>Name</th>
|
||||||
<th class="Amount">Amount</th>
|
<th>Amount</th>
|
||||||
<th class="Delete">Delete</th>
|
<th>Delete</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="tbodyMain">
|
<tbody id="tbodyMain">
|
||||||
<tr ng-repeat="journal in voucher.Journals">
|
<tr ng-repeat="journal in voucher.Journals">
|
||||||
<td class="Debit">{{journal.Debit | debit}}</td>
|
<td>{{journal.Debit | debit}}</td>
|
||||||
<td class="Name">{{journal.Ledger.Name}}</td>
|
<td>{{journal.Ledger.Name}}</td>
|
||||||
<td data-column="Amount" class="Amount Editable">{{journal.Amount}}</td>
|
<td>{{journal.Amount}}</td>
|
||||||
<td class="Delete">
|
<td>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<a class="btn btn-danger" ng-click="removeJournal(journal)"><i
|
<a class="btn btn-danger" ng-click="removeJournal(journal)"><i
|
||||||
class="icon-trash icon-white"></i> Delete</a>
|
class="icon-trash icon-white"></i> Delete</a>
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<form method="post" autocomplete="off">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 id="myModalLabel">Edit Payment</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class=" control-group">
|
||||||
|
<label for="editAccount">Account</label>
|
||||||
|
<autocomplete id="editAccount" url="/Services/Accounts" selname="edit.Ledger.Name"
|
||||||
|
selid="edit.Ledger.LedgerID"></autocomplete>
|
||||||
|
<label for="editAmount">Amount</label>
|
||||||
|
|
||||||
|
<div class="input-prepend input-append">
|
||||||
|
<span class="add-on">₹</span><input type="text" id="editAmount" class="span2" autocomplete="off"
|
||||||
|
placeholder="Amount" ng-model="edit.Amount"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button id="cancel" class="btn">Cancel</button>
|
||||||
|
<button id="action" class="btn btn-primary">Update</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -27,18 +27,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=" control-group" id="add">
|
<div class=" control-group" id="add">
|
||||||
<label for="txtLedger" class="control-label">Add</label>
|
<label for="txtLedger" class="control-label">Account</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<autocomplete id="txtLedger" url="/Services/Accounts" selname="name"
|
<autocomplete id="txtLedger" url="/Services/Accounts" selname="ledger.Name"
|
||||||
selid="id" ng-model="name"></autocomplete>
|
selid="ledger.LedgerID" ng-model="name"></autocomplete>
|
||||||
<div class=" input-prepend">
|
<div class=" input-prepend">
|
||||||
<span class="add-on">₹</span>
|
<span class="add-on">₹</span>
|
||||||
<input type="text" id="txtAmount" class="span2" autocomplete="off"
|
<input type="text" id="txtAmount" class="span2" autocomplete="off"
|
||||||
placeholder="Amount" ng-model="amount"/>
|
placeholder="Amount" ng-model="amount"/>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-success" ng-click="addJournal()">Add <i class="icon-plus-sign icon-white"></i>
|
<button class="btn btn-info" ng-click="addJournal()">Add <i class="icon-plus-sign icon-white"></i></button>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -59,7 +58,17 @@
|
|||||||
<td>{{journal.Ledger.Name}}</td>
|
<td>{{journal.Ledger.Name}}</td>
|
||||||
<td>{{journal.Amount}}</td>
|
<td>{{journal.Amount}}</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn" ng-click="removeJournal(journal)">Delete</button>
|
<div class="btn-group">
|
||||||
|
<a class="btn btn-danger" ng-click="removeJournal(journal)"><i
|
||||||
|
class="icon-trash icon-white"></i> Delete</a>
|
||||||
|
<a class="btn btn-danger dropdown-toggle" data-toggle="dropdown" href="#"><span
|
||||||
|
class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a ng-confirm url="/partial/payment-modal.html" before="toggleEdit(journal)"
|
||||||
|
on-action="toggleEdit(journal, true)" on-cancel="toggleEdit(journal, false)"><i
|
||||||
|
class="icon-pencil"></i> Edit</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
<form method="post" autocomplete="off" class="form-horizontal">
|
||||||
|
<legend>Purchase Return Edit / New</legend>
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="txtCode" class="control-label">Code</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="txtCode" class="non-search-box" disabled="disabled" ng-model="voucher.Code"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="txtDate" class="control-label">Date</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<datepicker id="txtDate" model="voucher" prop="Date" ng-model="voucher.Date"></datepicker>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group" ng-repeat="journal in voucher.Journals | journalDebit:1">
|
||||||
|
|
||||||
|
<label for="txtLedger" class="control-label">Ledger</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<autocomplete id="txtLedger" url="/Services/Accounts"
|
||||||
|
selname="journal.Ledger.Name" selid="journal.Ledger.LedgerID"></autocomplete>
|
||||||
|
|
||||||
|
<div class="input-prepend">
|
||||||
|
<span class="add-on">₹</span><input type="text" id="txtLedgerAmount" class="span2"
|
||||||
|
autocomplete="off" readonly="readonly"
|
||||||
|
placeholder="Amount" ng-model="journal.Amount"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class=" control-group" id="add">
|
||||||
|
<label for="txtBatch" class="control-label">Product</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<autobatch id="txtBatch" url="/Services/Batches" selname="name"
|
||||||
|
batch="batch" ng-model="name"></autobatch>
|
||||||
|
<input type="text" id="txtQuantity" class="span2" autocomplete="off"
|
||||||
|
placeholder="Quantity" ng-model="quantity"/>
|
||||||
|
<button class="btn btn-info" ng-click="addInventory()">Add <i class="icon-plus-sign icon-white"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="gvGrid" class="control-label"></label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<table id="gvGrid" class="table clean-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Product</th>
|
||||||
|
<th>Quantity</th>
|
||||||
|
<th>Rate</th>
|
||||||
|
<th>Tax</th>
|
||||||
|
<th>Discount</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
<th>Delete</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="tbodyMain">
|
||||||
|
<tr ng-repeat="inventory in voucher.Inventories">
|
||||||
|
<td>{{inventory.Product.Name}}</td>
|
||||||
|
<td>{{inventory.Quantity}}</td>
|
||||||
|
<td>{{inventory.Rate}}</td>
|
||||||
|
<td>{{inventory.Tax}}</td>
|
||||||
|
<td>{{inventory.Discount}}</td>
|
||||||
|
<td>{{inventory.Amount}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn" ng-click="removeInventory(inventory)">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot id="tfootMain">
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="txtNarration" class="control-label">Narration</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<textarea rows="2" cols="20" id="txtNarration"
|
||||||
|
class="non-search-box" ng-model="voucher.Narration"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-actions">
|
||||||
|
<button class="btn btn-primary" ng-click="save()"
|
||||||
|
ng-disabled="preventAlteration(voucher)">{{voucher.Code | save_button}}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-inverse" ng-click="post()" ng-hide="voucher.Code == '(Auto)'"
|
||||||
|
ng-disabled="voucher.Posted || !perms['Post Vouchers']">{{voucher.Posted | posted}}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger" ng-hide="voucher.Code == '(Auto)'" ng-disabled="preventAlteration(voucher)"
|
||||||
|
ng-confirm title="Delete Voucher" action-text="Are you sure? This cannot be undone."
|
||||||
|
action-button-text="Delete" action-function="delete()"> Delete
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="row-fluid">
|
||||||
|
Created on {{voucher.CreationDate}} and Last Edited on {{voucher.LastEditDate}} by {{voucher.User.Name}}.
|
||||||
|
Posted
|
||||||
|
by {{voucher.Poster}}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
placeholder="Tax" ng-model="tax"/>
|
placeholder="Tax" ng-model="tax"/>
|
||||||
<input type="text" id="txtDiscount" autocomplete="off" class="non-search-box inline"
|
<input type="text" id="txtDiscount" autocomplete="off" class="non-search-box inline"
|
||||||
placeholder="Discount" ng-model="discount"/>
|
placeholder="Discount" ng-model="discount"/>
|
||||||
<button class="btn btn-success" ng-click="addInventory()">Add <i class="icon-plus-sign icon-white"></i>
|
<button class="btn btn-info" ng-click="addInventory()">Add <i class="icon-plus-sign icon-white"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<form method="post" autocomplete="off">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 id="myModalLabel">Edit Receipt</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class=" control-group">
|
||||||
|
<label for="editAccount">Account</label>
|
||||||
|
<autocomplete id="editAccount" url="/Services/Accounts" selname="edit.Ledger.Name"
|
||||||
|
selid="edit.Ledger.LedgerID"></autocomplete>
|
||||||
|
<label for="editAmount">Amount</label>
|
||||||
|
|
||||||
|
<div class="input-prepend input-append">
|
||||||
|
<span class="add-on">₹</span><input type="text" id="editAmount" class="span2" autocomplete="off"
|
||||||
|
placeholder="Amount" ng-model="edit.Amount"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button id="cancel" class="btn">Cancel</button>
|
||||||
|
<button id="action" class="btn btn-primary">Update</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=" control-group" id="add">
|
<div class=" control-group" id="add">
|
||||||
<label for="txtLedger" class="control-label">Add</label>
|
<label for="txtLedger" class="control-label">Account</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<autocomplete id="txtLedger" url="/Services/Accounts" selname="name"
|
<autocomplete id="txtLedger" url="/Services/Accounts" selname="name"
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
<input type="text" id="txtAmount" class="span2" autocomplete="off"
|
<input type="text" id="txtAmount" class="span2" autocomplete="off"
|
||||||
placeholder="Amount" ng-model="amount"/>
|
placeholder="Amount" ng-model="amount"/>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-success" ng-click="addJournal()">Add <i class="icon-plus-sign icon-white"></i>
|
<button class="btn btn-info" ng-click="addJournal()">Add <i class="icon-plus-sign icon-white"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,7 +59,17 @@
|
|||||||
<td>{{journal.Ledger.Name}}</td>
|
<td>{{journal.Ledger.Name}}</td>
|
||||||
<td>{{journal.Amount}}</td>
|
<td>{{journal.Amount}}</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn" ng-click="removeJournal(journal)">Delete</button>
|
<div class="btn-group">
|
||||||
|
<a class="btn btn-danger" ng-click="removeJournal(journal)"><i
|
||||||
|
class="icon-trash icon-white"></i> Delete</a>
|
||||||
|
<a class="btn btn-danger dropdown-toggle" data-toggle="dropdown" href="#"><span
|
||||||
|
class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a ng-confirm url="/partial/receipt-modal.html" before="toggleEdit(journal)"
|
||||||
|
on-action="toggleEdit(journal, true)" on-cancel="toggleEdit(journal, false)"><i
|
||||||
|
class="icon-pencil"></i> Edit</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
function AccountListCtrl($scope, accounts) {
|
'use strict';
|
||||||
|
|
||||||
|
function AccountListCtrl($scope, accounts) {
|
||||||
$scope.info = accounts;
|
$scope.info = accounts;
|
||||||
}
|
}
|
||||||
AccountListCtrl.resolve = {
|
AccountListCtrl.resolve = {
|
||||||
@@ -12,10 +14,10 @@ AccountListCtrl.resolve = {
|
|||||||
Account.query({}, successCb);
|
Account.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function AccountCtrl($scope, $location, account, account_types, cost_centers) {
|
function AccountCtrl($scope, $location, account, account_types, cost_centers) {
|
||||||
$scope.account = account
|
$scope.account = account;
|
||||||
|
|
||||||
$scope.account_types = account_types;
|
$scope.account_types = account_types;
|
||||||
$scope.cost_centers = cost_centers;
|
$scope.cost_centers = cost_centers;
|
||||||
@@ -73,4 +75,4 @@ AccountCtrl.resolve = {
|
|||||||
CostCenter.query({}, successCb);
|
CostCenter.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
+46
-11
@@ -1,6 +1,8 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var overlord_directive = angular.module('overlord.directive', []);
|
var overlord_directive = angular.module('overlord.directive', []);
|
||||||
overlord_directive.directive('autocomplete', function () {
|
overlord_directive.directive('autocomplete', function () {
|
||||||
var directiveDefinitionObject = {
|
return {
|
||||||
restrict:'E',
|
restrict:'E',
|
||||||
replace:true,
|
replace:true,
|
||||||
transclude:true,
|
transclude:true,
|
||||||
@@ -41,11 +43,10 @@ overlord_directive.directive('autocomplete', function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return directiveDefinitionObject;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
overlord_directive.directive('autobatch', function () {
|
overlord_directive.directive('autobatch', function () {
|
||||||
var directiveDefinitionObject = {
|
return {
|
||||||
restrict:'E',
|
restrict:'E',
|
||||||
replace:true,
|
replace:true,
|
||||||
transclude:true,
|
transclude:true,
|
||||||
@@ -81,11 +82,10 @@ overlord_directive.directive('autobatch', function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return directiveDefinitionObject;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
overlord_directive.directive('datepicker', function () {
|
overlord_directive.directive('datepicker', function () {
|
||||||
var directiveDefinitionObject = {
|
return {
|
||||||
restrict:'E',
|
restrict:'E',
|
||||||
replace:true,
|
replace:true,
|
||||||
transclude:true,
|
transclude:true,
|
||||||
@@ -102,17 +102,16 @@ overlord_directive.directive('datepicker', function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return directiveDefinitionObject;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
overlord_directive.directive('fadey', function () {
|
overlord_directive.directive('fadey', function () {
|
||||||
var directiveDefinitionObject = {
|
return {
|
||||||
restrict:'A',
|
restrict:'A',
|
||||||
link:function (scope, element, attrs) {
|
link:function (scope, element, attrs) {
|
||||||
var duration = 500;
|
var duration = 500;
|
||||||
element = jQuery(element);
|
element = jQuery(element);
|
||||||
element.hide();
|
element.hide();
|
||||||
element.fadeIn(duration)
|
element.fadeIn(duration);
|
||||||
|
|
||||||
scope.destroy = function (complete) {
|
scope.destroy = function (complete) {
|
||||||
element.fadeOut(duration, function () {
|
element.fadeOut(duration, function () {
|
||||||
@@ -124,7 +123,6 @@ overlord_directive.directive('fadey', function () {
|
|||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return directiveDefinitionObject;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
overlord_directive.directive('ngConfirm', function (modal, $parse) {
|
overlord_directive.directive('ngConfirm', function (modal, $parse) {
|
||||||
@@ -197,7 +195,7 @@ overlord_directive.directive('ngConfirm', function (modal, $parse) {
|
|||||||
|
|
||||||
|
|
||||||
overlord_directive.directive('journal-edit', function () {
|
overlord_directive.directive('journal-edit', function () {
|
||||||
var directiveDefinitionObject = {
|
return {
|
||||||
restrict:'A',
|
restrict:'A',
|
||||||
replace:true,
|
replace:true,
|
||||||
transclude:true,
|
transclude:true,
|
||||||
@@ -210,5 +208,42 @@ overlord_directive.directive('journal-edit', function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return directiveDefinitionObject;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
overlord_directive.directive('ngEditRepeat', function (modal, $parse) {
|
||||||
|
return {
|
||||||
|
restrict:'E',
|
||||||
|
template:'' +
|
||||||
|
'<div class="btn-group">' +
|
||||||
|
' <a class="btn btn-danger" ng-click="removeJournal(journal)"><i class="icon-trash icon-white"></i> Delete</a>' +
|
||||||
|
' <a class="btn btn-danger dropdown-toggle" data-toggle="dropdown" href="#"><span class="caret"></span></a>' +
|
||||||
|
' <ul class="dropdown-menu">' +
|
||||||
|
' <li><a ng-confirm url="/partial/journal-modal.html" before="toggleEdit(journal)" on-action="toggleEdit(journal, true)" on-cancel="toggleEdit(journal, false)"><i class="icon-pencil"></i> Edit</a></li>' +
|
||||||
|
' </ul>' +
|
||||||
|
'</div>',
|
||||||
|
|
||||||
|
link:function postLink(scope, element, attrs) {
|
||||||
|
// Could have custom or boostrap modal options here
|
||||||
|
var options = {};
|
||||||
|
if (typeof attrs.url !== 'undefined') {
|
||||||
|
element.bind("click", function () {
|
||||||
|
if (typeof attrs.before !== 'undefined') {
|
||||||
|
var fn = $parse(attrs.before);
|
||||||
|
scope.$apply(function () {
|
||||||
|
fn(scope);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
modal.template(attrs.url, attrs.onAction, attrs.onCancel, scope, options);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
element.bind("click", function () {
|
||||||
|
var actionButton = {text:attrs["actionButtonText"], click:attrs["actionFunction"], class:attrs['class']};
|
||||||
|
var cancelButton = {text:attrs["cancelButtonText"], click:attrs["cancelFunction"]};
|
||||||
|
modal.confirm(attrs["title"], attrs["actionText"], actionButton, cancelButton, scope, options);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
+2
-1
@@ -1,3 +1,5 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var overlord_filter = angular.module('overlord.filter', []);
|
var overlord_filter = angular.module('overlord.filter', []);
|
||||||
overlord_filter.filter('debit', function () {
|
overlord_filter.filter('debit', function () {
|
||||||
return function (input) {
|
return function (input) {
|
||||||
@@ -8,7 +10,6 @@ overlord_filter.filter('debit', function () {
|
|||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
;
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var overlord_service = angular.module('overlord.service', ['ngResource']);
|
var overlord_service = angular.module('overlord.service', ['ngResource']);
|
||||||
|
|
||||||
// TODO: Replace hardcoded url with route_url
|
// TODO: Replace hardcoded url with route_url
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
function AttendanceCtrl($scope, $location, Attendance, attendance_types, info) {
|
'use strict';
|
||||||
|
|
||||||
|
function AttendanceCtrl($scope, $location, Attendance, attendance_types, info) {
|
||||||
$scope.attendance_types = attendance_types;
|
$scope.attendance_types = attendance_types;
|
||||||
$scope.info = info;
|
$scope.info = info;
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
@@ -36,4 +38,4 @@ AttendanceCtrl.resolve = {
|
|||||||
AttendanceTypes.query({}, successCb);
|
AttendanceTypes.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function CashFlowCtrl($scope, $routeParams, $location, cash_flow) {
|
'use strict';
|
||||||
|
|
||||||
|
function CashFlowCtrl($scope, $routeParams, $location, cash_flow) {
|
||||||
$scope.info = cash_flow;
|
$scope.info = cash_flow;
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
$location.path('/CashFlow').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
$location.path('/CashFlow').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
||||||
@@ -26,4 +28,4 @@ CashFlowCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function ClosingStockCtrl($scope, $location, info) {
|
'use strict';
|
||||||
|
|
||||||
|
function ClosingStockCtrl($scope, $location, info) {
|
||||||
$scope.info = info;
|
$scope.info = info;
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
$location.path('/ClosingStock/' + $scope.info.Date);
|
$location.path('/ClosingStock/' + $scope.info.Date);
|
||||||
@@ -22,4 +24,4 @@ ClosingStockCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function CostCenterListCtrl($scope, cost_centers) {
|
'use strict';
|
||||||
|
|
||||||
|
function CostCenterListCtrl($scope, cost_centers) {
|
||||||
$scope.info = cost_centers;
|
$scope.info = cost_centers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,7 +15,7 @@ CostCenterListCtrl.resolve = {
|
|||||||
CostCenter.query({}, successCb);
|
CostCenter.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function CostCenterCtrl($scope, $routeParams, $location, cost_center) {
|
function CostCenterCtrl($scope, $routeParams, $location, cost_center) {
|
||||||
$scope.cost_center = cost_center;
|
$scope.cost_center = cost_center;
|
||||||
@@ -51,4 +53,4 @@ CostCenterCtrl.resolve = {
|
|||||||
CostCenter.get({id:id}, successCb);
|
CostCenter.get({id:id}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function DaybookCtrl($scope, $location, info) {
|
'use strict';
|
||||||
|
|
||||||
|
function DaybookCtrl($scope, $location, info) {
|
||||||
$scope.info = info;
|
$scope.info = info;
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
$location.path('/Daybook').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
$location.path('/Daybook').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
||||||
@@ -23,4 +25,4 @@ DaybookCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
overlord_service.factory('modal', function ($http, $compile) {
|
'use strict';
|
||||||
|
|
||||||
|
overlord_service.factory('delete-button', function ($http, $compile) {
|
||||||
var modal = {};
|
var modal = {};
|
||||||
|
|
||||||
modal.get = function (create) {
|
modal.get = function (create) {
|
||||||
@@ -7,12 +9,12 @@ overlord_service.factory('modal', function ($http, $compile) {
|
|||||||
modal.dialog.appendTo('BODY');
|
modal.dialog.appendTo('BODY');
|
||||||
}
|
}
|
||||||
return modal.dialog;
|
return modal.dialog;
|
||||||
}
|
};
|
||||||
|
|
||||||
modal.compileAndRun = function (dialog, scope, options) {
|
modal.compileAndRun = function (dialog, scope, options) {
|
||||||
$compile(dialog)(scope);
|
$compile(dialog)(scope);
|
||||||
dialog.modal(options);
|
dialog.modal(options);
|
||||||
}
|
};
|
||||||
|
|
||||||
modal.alert = function (title, text, button, scope, options) {
|
modal.alert = function (title, text, button, scope, options) {
|
||||||
text = (text) ? text : "Alert";
|
text = (text) ? text : "Alert";
|
||||||
@@ -35,7 +37,7 @@ overlord_service.factory('modal', function ($http, $compile) {
|
|||||||
modal.close();
|
modal.close();
|
||||||
});
|
});
|
||||||
modal.compileAndRun(dialog, scope, options);
|
modal.compileAndRun(dialog, scope, options);
|
||||||
}
|
};
|
||||||
|
|
||||||
modal.confirm = function (title, actionText, actionButton, cancelButton, scope, options) {
|
modal.confirm = function (title, actionText, actionButton, cancelButton, scope, options) {
|
||||||
actionText = (actionText) ? actionText : "Are you sure?";
|
actionText = (actionText) ? actionText : "Are you sure?";
|
||||||
@@ -68,14 +70,14 @@ overlord_service.factory('modal', function ($http, $compile) {
|
|||||||
});
|
});
|
||||||
modal.compileAndRun(dialog, scope, options);
|
modal.compileAndRun(dialog, scope, options);
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
modal.close = function () {
|
modal.close = function () {
|
||||||
var dialog = modal.get()
|
var dialog = modal.get();
|
||||||
if (dialog) {
|
if (dialog) {
|
||||||
dialog.modal('hide');
|
dialog.modal('hide');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return modal;
|
return modal;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
function EmployeeAttendanceCtrl($scope, $location, EmployeeAttendance, attendance_types, info) {
|
'use strict';
|
||||||
|
|
||||||
|
function EmployeeAttendanceCtrl($scope, $location, EmployeeAttendance, attendance_types, info) {
|
||||||
$scope.attendance_types = attendance_types;
|
$scope.attendance_types = attendance_types;
|
||||||
$scope.info = info;
|
$scope.info = info;
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
@@ -39,4 +41,4 @@ EmployeeAttendanceCtrl.resolve = {
|
|||||||
AttendanceTypes.query({}, successCb);
|
AttendanceTypes.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function EmployeeFunctionsCtrl($scope) {
|
'use strict';
|
||||||
|
|
||||||
|
function EmployeeFunctionsCtrl($scope) {
|
||||||
$scope.creditSalary = function () {
|
$scope.creditSalary = function () {
|
||||||
$scope.toasts.push({Type:'Error', Message:'Not Implemented Yet'});
|
$scope.toasts.push({Type:'Error', Message:'Not Implemented Yet'});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
function EmployeeListCtrl($scope, employees) {
|
'use strict';
|
||||||
|
|
||||||
|
function EmployeeListCtrl($scope, employees) {
|
||||||
$scope.info = employees;
|
$scope.info = employees;
|
||||||
}
|
}
|
||||||
EmployeeListCtrl.resolve = {
|
EmployeeListCtrl.resolve = {
|
||||||
@@ -12,12 +14,12 @@ EmployeeListCtrl.resolve = {
|
|||||||
Employee.query({}, successCb);
|
Employee.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function EmployeeCtrl($scope, $routeParams, $location, employee, cost_centers) {
|
function EmployeeCtrl($scope, $routeParams, $location, employee, cost_centers) {
|
||||||
$scope.employee = employee;
|
$scope.employee = employee;
|
||||||
|
|
||||||
$scope.cost_centers = cost_centers
|
$scope.cost_centers = cost_centers;
|
||||||
|
|
||||||
$scope.save = function () {
|
$scope.save = function () {
|
||||||
$scope.employee.$save(function (u, putResponseHeaders) {
|
$scope.employee.$save(function (u, putResponseHeaders) {
|
||||||
@@ -62,4 +64,4 @@ EmployeeCtrl.resolve = {
|
|||||||
CostCenter.query({}, successCb);
|
CostCenter.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function GroupListCtrl($scope, groups) {
|
'use strict';
|
||||||
|
|
||||||
|
function GroupListCtrl($scope, groups) {
|
||||||
$scope.info = groups;
|
$scope.info = groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,7 +15,7 @@ GroupListCtrl.resolve = {
|
|||||||
Group.query({}, successCb);
|
Group.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function GroupCtrl($scope, $location, group) {
|
function GroupCtrl($scope, $location, group) {
|
||||||
$scope.group = group;
|
$scope.group = group;
|
||||||
@@ -51,4 +53,4 @@ GroupCtrl.resolve = {
|
|||||||
Group.get({id:id}, successCb);
|
Group.get({id:id}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function IssueCtrl($scope, $routeParams, $location, voucher, cost_centers, issue_grid, IssueGrid, Voucher) {
|
'use strict';
|
||||||
|
|
||||||
|
function IssueCtrl($scope, $routeParams, $location, voucher, cost_centers, issue_grid, IssueGrid, Voucher) {
|
||||||
$scope.voucher = voucher;
|
$scope.voucher = voucher;
|
||||||
$scope.cost_centers = cost_centers;
|
$scope.cost_centers = cost_centers;
|
||||||
$scope.smallGrid = issue_grid;
|
$scope.smallGrid = issue_grid;
|
||||||
@@ -32,8 +34,8 @@
|
|||||||
delete $scope.name;
|
delete $scope.name;
|
||||||
delete $scope.quantity;
|
delete $scope.quantity;
|
||||||
$('#txtBatch').val('');
|
$('#txtBatch').val('');
|
||||||
|
$('#txtBatch').focus();
|
||||||
}
|
}
|
||||||
$('#txtBatch').focus();
|
|
||||||
};
|
};
|
||||||
$scope.removeInventory = function (inventory) {
|
$scope.removeInventory = function (inventory) {
|
||||||
var index = this.voucher.Inventories.indexOf(inventory);
|
var index = this.voucher.Inventories.indexOf(inventory);
|
||||||
@@ -79,7 +81,7 @@
|
|||||||
if (typeof newInventories === 'undefined' || typeof oldInventories === 'undefined') {
|
if (typeof newInventories === 'undefined' || typeof oldInventories === 'undefined') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var amount = 0
|
var amount = 0;
|
||||||
for (var i = 0, l = newInventories.length; i < l; i++) {
|
for (var i = 0, l = newInventories.length; i < l; i++) {
|
||||||
amount += newInventories[i].Amount;
|
amount += newInventories[i].Amount;
|
||||||
}
|
}
|
||||||
@@ -200,4 +202,5 @@ IssueCtrl.resolve = {
|
|||||||
|
|
||||||
CostCenter.query({}, successCb);
|
CostCenter.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}}
|
}
|
||||||
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function JournalCtrl($scope, $location, voucher) {
|
'use strict';
|
||||||
|
|
||||||
|
function JournalCtrl($scope, $location, voucher) {
|
||||||
$scope.voucher = voucher;
|
$scope.voucher = voucher;
|
||||||
$scope.name = '';
|
$scope.name = '';
|
||||||
$scope.debit = 1;
|
$scope.debit = 1;
|
||||||
@@ -97,7 +99,7 @@
|
|||||||
$scope.toggleDebit = function () {
|
$scope.toggleDebit = function () {
|
||||||
$("#editDebit").button('toggle');
|
$("#editDebit").button('toggle');
|
||||||
$scope.edit.Debit = ($scope.edit.Debit === 1) ? -1 : 1;
|
$scope.edit.Debit = ($scope.edit.Debit === 1) ? -1 : 1;
|
||||||
}
|
};
|
||||||
$scope.toggleEdit = function (journal, update) {
|
$scope.toggleEdit = function (journal, update) {
|
||||||
if (typeof update === 'undefined') {
|
if (typeof update === 'undefined') {
|
||||||
$scope.edit = {};
|
$scope.edit = {};
|
||||||
@@ -137,5 +139,4 @@ JournalCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function LedgerCtrl($scope, $routeParams, $location, ledger) {
|
'use strict';
|
||||||
|
|
||||||
|
function LedgerCtrl($scope, $routeParams, $location, ledger) {
|
||||||
$scope.info = ledger;
|
$scope.info = ledger;
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
$location.path('/Ledger/' + $scope.info.Ledger.LedgerID).search('StartDate', $scope.info.StartDate).search('FinishDate', $scope.info.FinishDate);
|
$location.path('/Ledger/' + $scope.info.Ledger.LedgerID).search('StartDate', $scope.info.StartDate).search('FinishDate', $scope.info.FinishDate);
|
||||||
@@ -25,6 +27,6 @@ LedgerCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function LoginCtrl($scope, $http, $location, $route, $routeParams) {
|
'use strict';
|
||||||
|
|
||||||
|
function LoginCtrl($scope, $http, $location, $route, $routeParams) {
|
||||||
$scope.submit = function () {
|
$scope.submit = function () {
|
||||||
$http.
|
$http.
|
||||||
post('/login', {username:$scope.username, password:$scope.password}).
|
post('/login', {username:$scope.username, password:$scope.password}).
|
||||||
@@ -12,7 +14,7 @@
|
|||||||
error(function (errorMessage) {
|
error(function (errorMessage) {
|
||||||
$scope.toasts.push({Type:'Error', Message:errorMessage});
|
$scope.toasts.push({Type:'Error', Message:errorMessage});
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
$('#username').focus();
|
$('#username').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
overlord_service.factory('modal', function ($http, $compile) {
|
overlord_service.factory('modal', function ($http, $compile) {
|
||||||
var modal = {};
|
var modal = {};
|
||||||
|
|
||||||
@@ -7,12 +9,12 @@ overlord_service.factory('modal', function ($http, $compile) {
|
|||||||
modal.dialog.appendTo('BODY');
|
modal.dialog.appendTo('BODY');
|
||||||
}
|
}
|
||||||
return modal.dialog;
|
return modal.dialog;
|
||||||
}
|
};
|
||||||
|
|
||||||
modal.compileAndRun = function (dialog, scope, options) {
|
modal.compileAndRun = function (dialog, scope, options) {
|
||||||
$compile(dialog)(scope);
|
$compile(dialog)(scope);
|
||||||
dialog.modal(options);
|
dialog.modal(options);
|
||||||
}
|
};
|
||||||
|
|
||||||
modal.alert = function (title, text, button, scope, options) {
|
modal.alert = function (title, text, button, scope, options) {
|
||||||
text = (text) ? text : "Alert";
|
text = (text) ? text : "Alert";
|
||||||
@@ -35,7 +37,7 @@ overlord_service.factory('modal', function ($http, $compile) {
|
|||||||
modal.close();
|
modal.close();
|
||||||
});
|
});
|
||||||
modal.compileAndRun(dialog, scope, options);
|
modal.compileAndRun(dialog, scope, options);
|
||||||
}
|
};
|
||||||
|
|
||||||
modal.confirm = function (title, actionText, actionButton, cancelButton, scope, options) {
|
modal.confirm = function (title, actionText, actionButton, cancelButton, scope, options) {
|
||||||
actionText = (actionText) ? actionText : "Are you sure?";
|
actionText = (actionText) ? actionText : "Are you sure?";
|
||||||
@@ -68,7 +70,7 @@ overlord_service.factory('modal', function ($http, $compile) {
|
|||||||
});
|
});
|
||||||
modal.compileAndRun(dialog, scope, options);
|
modal.compileAndRun(dialog, scope, options);
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
modal.template = function (url, onSuccess, onCancel, scope, options) {
|
modal.template = function (url, onSuccess, onCancel, scope, options) {
|
||||||
$http.get(url).success(function (data) {
|
$http.get(url).success(function (data) {
|
||||||
@@ -85,20 +87,20 @@ overlord_service.factory('modal', function ($http, $compile) {
|
|||||||
if (onCancel) {
|
if (onCancel) {
|
||||||
scope.$eval(onCancel);
|
scope.$eval(onCancel);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
dialog.find("#cancel").click(function () {
|
dialog.find("#cancel").click(function () {
|
||||||
modal.close();
|
modal.close();
|
||||||
});
|
});
|
||||||
modal.compileAndRun(dialog, scope, options);
|
modal.compileAndRun(dialog, scope, options);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
modal.close = function () {
|
modal.close = function () {
|
||||||
var dialog = modal.get()
|
var dialog = modal.get();
|
||||||
if (dialog) {
|
if (dialog) {
|
||||||
dialog.modal('hide');
|
dialog.modal('hide');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return modal;
|
return modal;
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ var overlord = angular.module('overlord', ['overlord.directive', 'overlord.filte
|
|||||||
when('/Purchase', {templateUrl:'/partial/purchase.html', controller:PurchaseCtrl, resolve:PurchaseCtrl.resolve}).
|
when('/Purchase', {templateUrl:'/partial/purchase.html', controller:PurchaseCtrl, resolve:PurchaseCtrl.resolve}).
|
||||||
when('/Purchase/:id', {templateUrl:'/partial/purchase.html', controller:PurchaseCtrl, resolve:PurchaseCtrl.resolve}).
|
when('/Purchase/:id', {templateUrl:'/partial/purchase.html', controller:PurchaseCtrl, resolve:PurchaseCtrl.resolve}).
|
||||||
|
|
||||||
|
when('/Return', {templateUrl:'/partial/purchase-return.html', controller:PurchaseReturnCtrl, resolve:PurchaseReturnCtrl.resolve}).
|
||||||
|
when('/Return/:id', {templateUrl:'/partial/purchase-return.html', controller:PurchaseReturnCtrl, resolve:PurchaseReturnCtrl.resolve}).
|
||||||
|
|
||||||
when('/Issue', {templateUrl:'/partial/issue.html', controller:IssueCtrl, resolve:IssueCtrl.resolve}).
|
when('/Issue', {templateUrl:'/partial/issue.html', controller:IssueCtrl, resolve:IssueCtrl.resolve}).
|
||||||
when('/Issue/:id', {templateUrl:'/partial/issue.html', controller:IssueCtrl, resolve:IssueCtrl.resolve}).
|
when('/Issue/:id', {templateUrl:'/partial/issue.html', controller:IssueCtrl, resolve:IssueCtrl.resolve}).
|
||||||
|
|
||||||
@@ -123,13 +126,16 @@ var overlord = angular.module('overlord', ['overlord.directive', 'overlord.filte
|
|||||||
};
|
};
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
function BaseCtrl($rootScope, $scope, Auth, $location) {
|
function BaseCtrl($rootScope, $scope, Auth, $location, $routeParams) {
|
||||||
$rootScope.spinner = {http:0, route:false};
|
$rootScope.spinner = {http:0, route:false};
|
||||||
$rootScope.$on('event:loginRequired', function () {
|
$rootScope.$on('event:loginRequired', function () {
|
||||||
if ($rootScope.auth.isAuthenticated) {
|
if ($rootScope.auth.isAuthenticated) {
|
||||||
$location.path('/');
|
$location.path('/');
|
||||||
} else {
|
} else {
|
||||||
var came_from = $location.path();
|
var came_from = $routeParams.came_from;
|
||||||
|
if (typeof came_from === 'undefined' && $location.path() === '/login') {
|
||||||
|
came_from = $location.path();
|
||||||
|
}
|
||||||
$location.path('/login').search({came_from:came_from});
|
$location.path('/login').search({came_from:came_from});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,27 +1,33 @@
|
|||||||
function PaymentCtrl($scope, $location, voucher, ledgers) {
|
'use strict';
|
||||||
$scope.voucher = voucher
|
|
||||||
$scope.ledgers = ledgers;
|
|
||||||
|
|
||||||
$scope.addJournal = function () {
|
function PaymentCtrl($scope, $location, voucher, ledgers) {
|
||||||
for (var i = 0, l = this.voucher.Journals.length; i < l; i++) {
|
$scope.voucher = voucher;
|
||||||
if (this.voucher.Journals[i].Ledger.LedgerID === $scope.id) {
|
$scope.ledgers = ledgers;
|
||||||
var amount = (this.voucher.Journals[i].Debit * this.voucher.Journals[i].Amount) + (parseInt($scope.debit) * Number($scope.amount));
|
function getOldJournal(ledgerID, journals) {
|
||||||
if (amount < 0) {
|
for (var i = 0, l = journals.length; i < l; i++) {
|
||||||
this.voucher.Journals[i].Debit = -1;
|
if (journals[i].Ledger.LedgerID === ledgerID) {
|
||||||
this.voucher.Journals[i].Amount = amount * -1;
|
return journals[i];
|
||||||
} else {
|
|
||||||
this.voucher.Journals[i].Debit = 1;
|
|
||||||
this.voucher.Journals[i].Amount = amount;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i >= l) {
|
|
||||||
this.voucher.Journals.push({Debit:1, Amount:Number($scope.amount), Ledger:{LedgerID:$scope.id, Name:$scope.name}});
|
}
|
||||||
|
|
||||||
|
$scope.addJournal = function () {
|
||||||
|
var oldJournal = getOldJournal($scope.ledger.LedgerID, this.voucher.Journals);
|
||||||
|
if (typeof oldJournal !== 'undefined') {
|
||||||
|
var amount = (oldJournal.Debit * oldJournal.Amount) + (parseInt($scope.debit) * Number($scope.amount));
|
||||||
|
if (amount < 0) {
|
||||||
|
oldJournal.Debit = -1;
|
||||||
|
oldJournal.Amount = amount * -1;
|
||||||
|
} else {
|
||||||
|
oldJournal.Debit = 1;
|
||||||
|
oldJournal.Amount = amount;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.voucher.Journals.push({Debit:1, Amount:Number($scope.amount), Ledger:$scope.ledger});
|
||||||
}
|
}
|
||||||
|
delete $scope.ledger;
|
||||||
delete $scope.amount;
|
delete $scope.amount;
|
||||||
delete $scope.id;
|
|
||||||
delete $scope.name;
|
|
||||||
$('#txtLedger').focus();
|
$('#txtLedger').focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,6 +99,27 @@
|
|||||||
$scope.toasts.push({Type:'Error', Message:data.data});
|
$scope.toasts.push({Type:'Error', Message:data.data});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.toggleEdit = function (journal, update) {
|
||||||
|
if (typeof update === 'undefined') {
|
||||||
|
$scope.edit = {};
|
||||||
|
angular.copy(journal, $scope.edit);
|
||||||
|
} else {
|
||||||
|
if (update === true && typeof $scope.edit !== 'undefined') {
|
||||||
|
if (journal.Ledger.LedgerID !== $scope.edit.Ledger.LedgerID) {
|
||||||
|
var oldJournal = getOldJournal($scope.edit.Ledger.LedgerID, $scope.voucher.Journals);
|
||||||
|
if (typeof oldJournal !== 'undefined') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
angular.copy($scope.edit, journal);
|
||||||
|
$scope.$apply();
|
||||||
|
return true;
|
||||||
|
} else if (update === false) {
|
||||||
|
delete $scope.edit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PaymentCtrl.resolve = {
|
PaymentCtrl.resolve = {
|
||||||
@@ -117,9 +144,9 @@ PaymentCtrl.resolve = {
|
|||||||
|
|
||||||
var successCb = function (result) {
|
var successCb = function (result) {
|
||||||
deferred.resolve(result);
|
deferred.resolve(result);
|
||||||
}
|
};
|
||||||
|
|
||||||
LedgerService.query({type:1}, successCb);
|
LedgerService.query({type:1}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function ProductGroupListCtrl($scope, product_groups) {
|
'use strict';
|
||||||
|
|
||||||
|
function ProductGroupListCtrl($scope, product_groups) {
|
||||||
$scope.info = product_groups
|
$scope.info = product_groups
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,7 +15,7 @@ ProductGroupListCtrl.resolve = {
|
|||||||
ProductGroup.query({}, successCb);
|
ProductGroup.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function ProductGroupCtrl($scope, $location, product_group) {
|
function ProductGroupCtrl($scope, $location, product_group) {
|
||||||
$scope.product_group = product_group;
|
$scope.product_group = product_group;
|
||||||
@@ -51,4 +53,4 @@ ProductGroupCtrl.resolve = {
|
|||||||
ProductGroup.get({id:id}, successCb);
|
ProductGroup.get({id:id}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function ProductLedgerCtrl($scope, $routeParams, $location, product_ledger) {
|
'use strict';
|
||||||
|
|
||||||
|
function ProductLedgerCtrl($scope, $routeParams, $location, product_ledger) {
|
||||||
$scope.info = product_ledger;
|
$scope.info = product_ledger;
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
$location.path('/ProductLedger/' + $scope.info.Product.ProductID).search('StartDate', $scope.info.StartDate).search('FinishDate', $scope.info.FinishDate);
|
$location.path('/ProductLedger/' + $scope.info.Product.ProductID).search('StartDate', $scope.info.StartDate).search('FinishDate', $scope.info.FinishDate);
|
||||||
@@ -24,4 +26,4 @@ ProductLedgerCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function ProductListCtrl($scope, products) {
|
'use strict';
|
||||||
|
|
||||||
|
function ProductListCtrl($scope, products) {
|
||||||
$scope.info = products;
|
$scope.info = products;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,10 +15,10 @@ ProductListCtrl.resolve = {
|
|||||||
Product.query({}, successCb);
|
Product.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function ProductCtrl($scope, $location, product, product_groups) {
|
function ProductCtrl($scope, $location, product, product_groups) {
|
||||||
$scope.product = product
|
$scope.product = product;
|
||||||
$scope.product_groups = product_groups;
|
$scope.product_groups = product_groups;
|
||||||
|
|
||||||
$scope.save = function () {
|
$scope.save = function () {
|
||||||
@@ -62,4 +64,4 @@ ProductCtrl.resolve = {
|
|||||||
ProductGroup.query({}, successCb);
|
ProductGroup.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function ProfitLossCtrl($scope, $location, profit_loss) {
|
'use strict';
|
||||||
|
|
||||||
|
function ProfitLossCtrl($scope, $location, profit_loss) {
|
||||||
$scope.info = profit_loss;
|
$scope.info = profit_loss;
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
$location.path('/ProfitLoss').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
$location.path('/ProfitLoss').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
||||||
@@ -24,4 +26,4 @@ ProfitLossCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function PurchaseEntriesCtrl($scope, $location, purchase_entries) {
|
'use strict';
|
||||||
|
|
||||||
|
function PurchaseEntriesCtrl($scope, $location, purchase_entries) {
|
||||||
$scope.info = purchase_entries;
|
$scope.info = purchase_entries;
|
||||||
|
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
@@ -25,6 +27,6 @@ PurchaseEntriesCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
function PurchaseReturnCtrl($scope, $location, voucher) {
|
||||||
|
$scope.voucher = voucher;
|
||||||
|
|
||||||
|
$scope.rate = 0;
|
||||||
|
$scope.addInventory = function () {
|
||||||
|
for (var i = 0, l = this.voucher.Inventories.length; i < l; i++) {
|
||||||
|
if (this.voucher.Inventories[i].Product.ProductID === $scope.batch.Product.ProductID) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i >= l && Number($scope.quantity) <= $scope.batch.QuantityRemaining) {
|
||||||
|
var amount = Number($scope.quantity) * $scope.batch.Rate * (1 + $scope.batch.Tax) * (1 - $scope.batch.Discount);
|
||||||
|
this.voucher.Inventories.push(
|
||||||
|
{
|
||||||
|
Product:$scope.batch.Product,
|
||||||
|
Quantity:Number($scope.quantity),
|
||||||
|
Rate:Number($scope.batch.Rate),
|
||||||
|
Tax:Number($scope.batch.Tax),
|
||||||
|
Discount:Number($scope.batch.Discount),
|
||||||
|
Amount:amount,
|
||||||
|
Batch:$scope.batch
|
||||||
|
});
|
||||||
|
delete $scope.batch;
|
||||||
|
delete $scope.name;
|
||||||
|
delete $scope.quantity;
|
||||||
|
$('#txtBatch').val('');
|
||||||
|
$('#txtBatch').focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$scope.removeInventory = function (inventory) {
|
||||||
|
var index = this.voucher.Inventories.indexOf(inventory);
|
||||||
|
this.voucher.Inventories.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.$watch('voucher.Inventories', function (inventories, oldValue) {
|
||||||
|
var amount = 0;
|
||||||
|
if (typeof inventories !== 'undefined') {
|
||||||
|
for (var i = 0, l = inventories.length; i < l; i++) {
|
||||||
|
amount += Number(inventories[i].Amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof $scope.voucher.Journals !== 'undefined') {
|
||||||
|
for (var i = 0, l = $scope.voucher.Journals.length; i < l; i++) {
|
||||||
|
if ($scope.voucher.Journals[i].Debit === 1) {
|
||||||
|
$scope.voucher.Journals[i].Amount = amount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
$scope.preventAlteration = function (voucher) {
|
||||||
|
if (typeof $scope.perms === 'undefined') {
|
||||||
|
return false;
|
||||||
|
} else if (typeof voucher.VoucherID === 'undefined') {
|
||||||
|
return !$scope.perms['Purchase Return'];
|
||||||
|
} else if (voucher.Posted && !$scope.perms['Edit Posted Vouchers']) {
|
||||||
|
return true;
|
||||||
|
} else if (voucher.User.UserID != $scope.auth.UserID && !$scope.perms["Edit Other User's Vouchers"]) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.get = function (voucherid) {
|
||||||
|
$scope.voucher = Voucher.get({VoucherID:voucherid}, function (u, putResponseHeaders) {
|
||||||
|
$scope.toasts.push({Type:'Success', Message:u.Code});
|
||||||
|
}, function (data, status) {
|
||||||
|
$scope.toasts.push({Type:'Error', Message:data.data});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.save = function () {
|
||||||
|
$scope.voucher.$save({type:'Purchase Return'}, function (u, putResponseHeaders) {
|
||||||
|
$scope.toasts.push({Type:'Success', Message:u.Code});
|
||||||
|
$location.path('/Return/' + u.VoucherID);
|
||||||
|
}, function (data, status) {
|
||||||
|
$scope.toasts.push({Type:'Error', Message:data.data});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.delete = function () {
|
||||||
|
$scope.voucher.$delete(function (u, putResponseHeaders) {
|
||||||
|
$scope.toasts.push({Type:'Success', Message:''});
|
||||||
|
$location.path('/Return').replace();
|
||||||
|
}, function (data, status) {
|
||||||
|
$scope.toasts.push({Type:'Error', Message:data.data});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.post = function () {
|
||||||
|
$scope.voucher.$post(function (u, putResponseHeaders) {
|
||||||
|
$scope.toasts.push({Type:'Success', Message:u.code});
|
||||||
|
}, function (data, status) {
|
||||||
|
$scope.toasts.push({Type:'Error', Message:data.data});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
PurchaseReturnCtrl.resolve = {
|
||||||
|
voucher:function ($q, $route, Voucher) {
|
||||||
|
var deferred = $q.defer();
|
||||||
|
|
||||||
|
var id = $route.current.params.id;
|
||||||
|
|
||||||
|
var successCb = function (result) {
|
||||||
|
deferred.resolve(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof id === 'undefined') {
|
||||||
|
Voucher.get({type:'Purchase Return'}, successCb);
|
||||||
|
} else {
|
||||||
|
Voucher.get({id:id}, successCb);
|
||||||
|
}
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
function PurchaseCtrl($scope, $location, voucher) {
|
'use strict';
|
||||||
$scope.voucher = voucher
|
|
||||||
|
function PurchaseCtrl($scope, $location, voucher) {
|
||||||
|
$scope.voucher = voucher;
|
||||||
|
|
||||||
$scope.rate = 0;
|
$scope.rate = 0;
|
||||||
$scope.addInventory = function () {
|
$scope.addInventory = function () {
|
||||||
@@ -37,10 +39,6 @@
|
|||||||
this.voucher.Inventories.splice(index, 1);
|
this.voucher.Inventories.splice(index, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.ledgerName = function (journal) {
|
|
||||||
return journal.Ledger.Name;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.$watch('voucher.Inventories', function (inventories, oldValue) {
|
$scope.$watch('voucher.Inventories', function (inventories, oldValue) {
|
||||||
var amount = 0;
|
var amount = 0;
|
||||||
if (typeof inventories !== 'undefined') {
|
if (typeof inventories !== 'undefined') {
|
||||||
@@ -124,4 +122,4 @@ PurchaseCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function RawMaterialCostCtrl($scope, $routeParams, $location, raw_material_cost) {
|
'use strict';
|
||||||
|
|
||||||
|
function RawMaterialCostCtrl($scope, $routeParams, $location, raw_material_cost) {
|
||||||
$scope.info = raw_material_cost;
|
$scope.info = raw_material_cost;
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
$location.path('/RawMaterialCost').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
$location.path('/RawMaterialCost').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
||||||
@@ -26,4 +28,4 @@ RawMaterialCostCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,27 +1,33 @@
|
|||||||
function ReceiptCtrl($scope, $routeParams, $location, voucher, ledgers, Voucher) {
|
'use strict';
|
||||||
$scope.voucher = voucher
|
|
||||||
$scope.ledgers = ledgers;
|
|
||||||
|
|
||||||
$scope.addJournal = function () {
|
function ReceiptCtrl($scope, $routeParams, $location, voucher, ledgers, Voucher) {
|
||||||
for (var i = 0, l = this.voucher.Journals.length; i < l; i++) {
|
$scope.voucher = voucher;
|
||||||
if (this.voucher.Journals[i].Ledger.LedgerID === $scope.id) {
|
$scope.ledgers = ledgers;
|
||||||
var amount = (this.voucher.Journals[i].Debit * this.voucher.Journals[i].Amount) + (parseInt($scope.debit) * Number($scope.amount));
|
function getOldJournal(ledgerID, journals) {
|
||||||
if (amount < 0) {
|
for (var i = 0, l = journals.length; i < l; i++) {
|
||||||
this.voucher.Journals[i].Debit = -1;
|
if (journals[i].Ledger.LedgerID === ledgerID) {
|
||||||
this.voucher.Journals[i].Amount = amount * -1;
|
return journals[i];
|
||||||
} else {
|
|
||||||
this.voucher.Journals[i].Debit = 1;
|
|
||||||
this.voucher.Journals[i].Amount = amount;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i >= l) {
|
|
||||||
this.voucher.Journals.push({Debit:-1, Amount:Number($scope.amount), Ledger:{LedgerID:$scope.id, Name:$scope.name}});
|
}
|
||||||
|
|
||||||
|
$scope.addJournal = function () {
|
||||||
|
var oldJournal = getOldJournal($scope.ledger.LedgerID, this.voucher.Journals);
|
||||||
|
if (typeof oldJournal !== 'undefined') {
|
||||||
|
var amount = (oldJournal.Debit * oldJournal.Amount) + (parseInt($scope.debit) * Number($scope.amount));
|
||||||
|
if (amount < 0) {
|
||||||
|
oldJournal.Debit = -1;
|
||||||
|
oldJournal.Amount = amount * -1;
|
||||||
|
} else {
|
||||||
|
oldJournal.Debit = 1;
|
||||||
|
oldJournal.Amount = amount;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.voucher.Journals.push({Debit:-1, Amount:Number($scope.amount), Ledger:$scope.ledger});
|
||||||
}
|
}
|
||||||
|
delete $scope.ledger;
|
||||||
delete $scope.amount;
|
delete $scope.amount;
|
||||||
delete $scope.id;
|
|
||||||
delete $scope.name;
|
|
||||||
$('#txtLedger').focus();
|
$('#txtLedger').focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,6 +99,27 @@
|
|||||||
$scope.toasts.push({Type:'Error', Message:data.data});
|
$scope.toasts.push({Type:'Error', Message:data.data});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.toggleEdit = function (journal, update) {
|
||||||
|
if (typeof update === 'undefined') {
|
||||||
|
$scope.edit = {};
|
||||||
|
angular.copy(journal, $scope.edit);
|
||||||
|
} else {
|
||||||
|
if (update === true && typeof $scope.edit !== 'undefined') {
|
||||||
|
if (journal.Ledger.LedgerID !== $scope.edit.Ledger.LedgerID) {
|
||||||
|
var oldJournal = getOldJournal($scope.edit.Ledger.LedgerID, $scope.voucher.Journals);
|
||||||
|
if (typeof oldJournal !== 'undefined') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
angular.copy($scope.edit, journal);
|
||||||
|
$scope.$apply();
|
||||||
|
return true;
|
||||||
|
} else if (update === false) {
|
||||||
|
delete $scope.edit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceiptCtrl.resolve = {
|
ReceiptCtrl.resolve = {
|
||||||
@@ -117,9 +144,9 @@ ReceiptCtrl.resolve = {
|
|||||||
|
|
||||||
var successCb = function (result) {
|
var successCb = function (result) {
|
||||||
deferred.resolve(result);
|
deferred.resolve(result);
|
||||||
}
|
};
|
||||||
|
|
||||||
LedgerService.query({type:1}, successCb);
|
LedgerService.query({type:1}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function TrialBalanceCtrl($scope, $routeParams, $location, trial_balance) {
|
'use strict';
|
||||||
|
|
||||||
|
function TrialBalanceCtrl($scope, $routeParams, $location, trial_balance) {
|
||||||
$scope.info = trial_balance;
|
$scope.info = trial_balance;
|
||||||
|
|
||||||
$scope.show = function () {
|
$scope.show = function () {
|
||||||
@@ -23,4 +25,4 @@ TrialBalanceCtrl.resolve = {
|
|||||||
}
|
}
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function UnpostedCtrl($scope, info) {
|
'use strict';
|
||||||
|
|
||||||
|
function UnpostedCtrl($scope, info) {
|
||||||
$scope.info = info;
|
$scope.info = info;
|
||||||
}
|
}
|
||||||
UnpostedCtrl.resolve = {
|
UnpostedCtrl.resolve = {
|
||||||
@@ -12,4 +14,4 @@ UnpostedCtrl.resolve = {
|
|||||||
Unposted.query({}, successCb);
|
Unposted.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function UserListCtrl($scope, users) {
|
'use strict';
|
||||||
|
|
||||||
|
function UserListCtrl($scope, users) {
|
||||||
$scope.info = users;
|
$scope.info = users;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,7 +15,7 @@ UserListCtrl.resolve = {
|
|||||||
User.query({}, successCb);
|
User.query({}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function UserCtrl($scope, $location, user) {
|
function UserCtrl($scope, $location, user) {
|
||||||
$scope.user = user;
|
$scope.user = user;
|
||||||
@@ -51,4 +53,4 @@ UserCtrl.resolve = {
|
|||||||
User.get({id:id}, successCb);
|
User.get({id:id}, successCb);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -37,6 +37,7 @@
|
|||||||
<script src="/script/payment.js"> </script>
|
<script src="/script/payment.js"> </script>
|
||||||
<script src="/script/receipt.js"> </script>
|
<script src="/script/receipt.js"> </script>
|
||||||
<script src="/script/purchase.js"> </script>
|
<script src="/script/purchase.js"> </script>
|
||||||
|
<script src="/script/purchase-return.js"> </script>
|
||||||
<script src="/script/issue.js"> </script>
|
<script src="/script/issue.js"> </script>
|
||||||
|
|
||||||
<script src="/script/employee-attendance.js"> </script>
|
<script src="/script/employee-attendance.js"> </script>
|
||||||
@@ -90,7 +91,7 @@
|
|||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="/Journal">Journal</a></li>
|
<li><a href="/Journal">Journal</a></li>
|
||||||
<li><a href="/Purchase">Purchase</a></li>
|
<li><a href="/Purchase">Purchase</a></li>
|
||||||
<li><a href="/PurchaseReturn">Purchase Return</a></li>
|
<li><a href="/Return">Purchase Return</a></li>
|
||||||
<li><a href="/Payment">Payment</a></li>
|
<li><a href="/Payment">Payment</a></li>
|
||||||
<li><a href="/Receipt">Receipt</a></li>
|
<li><a href="/Receipt">Receipt</a></li>
|
||||||
<li><a href="/Issue">Issue</a></li>
|
<li><a href="/Issue">Issue</a></li>
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ def save_update(request):
|
|||||||
try:
|
try:
|
||||||
id = request.matchdict.get('id', None)
|
id = request.matchdict.get('id', None)
|
||||||
if id is None:
|
if id is None:
|
||||||
item = Ledger(0, request.json_body['Name'], int(request.json_body['Type']), request.json_body['IsActive'],
|
item = Ledger(code=0, name=request.json_body['Name'], type=int(request.json_body['Type']),
|
||||||
uuid.UUID(request.json_body['CostCenter']['CostCenterID'])).create()
|
is_active=request.json_body['IsActive'], is_reconcilble=request.json_body['IsReconcilable'],
|
||||||
|
costcenter_id=uuid.UUID(request.json_body['CostCenter']['CostCenterID'])).create()
|
||||||
else:
|
else:
|
||||||
new_type = int(request.json_body['Type'])
|
new_type = int(request.json_body['Type'])
|
||||||
item = Ledger.by_id(uuid.UUID(id))
|
item = Ledger.by_id(uuid.UUID(id))
|
||||||
@@ -32,6 +33,7 @@ def save_update(request):
|
|||||||
item.type = new_type
|
item.type = new_type
|
||||||
item.name = request.json_body['Name']
|
item.name = request.json_body['Name']
|
||||||
item.is_active = request.json_body['IsActive']
|
item.is_active = request.json_body['IsActive']
|
||||||
|
item.is_reconcilable = request.json_body['IsReconcilable']
|
||||||
item.costcenter_id = uuid.UUID(request.json_body['CostCenter']['CostCenterID'])
|
item.costcenter_id = uuid.UUID(request.json_body['CostCenter']['CostCenterID'])
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
return account_info(item.id)
|
return account_info(item.id)
|
||||||
@@ -65,17 +67,20 @@ def show_blank(request):
|
|||||||
return account_info(None)
|
return account_info(None)
|
||||||
|
|
||||||
|
|
||||||
@view_config(request_method='GET', route_name='account', renderer='json', request_param='list', xhr=True, permission='Authenticated')
|
@view_config(request_method='GET', route_name='account', renderer='json', request_param='list', xhr=True,
|
||||||
|
permission='Authenticated')
|
||||||
def show_list(request):
|
def show_list(request):
|
||||||
list = Ledger.list()
|
list = Ledger.list()
|
||||||
ledgers = []
|
ledgers = []
|
||||||
for item in list:
|
for item in list:
|
||||||
ledgers.append({'Name': item.name, 'Type': item.type_object.name, 'IsActive': item.is_active,
|
ledgers.append({'Name': item.name, 'Type': item.type_object.name, 'IsActive': 'Yes' if item.is_active else 'No',
|
||||||
'CostCenter': item.costcenter.name, 'Url': request.route_url('account_id', id=item.id)})
|
'IsReconcilable': 'Yes' if item.is_reconcilable else '', 'CostCenter': item.costcenter.name,
|
||||||
|
'Url': request.route_url('account_id', id=item.id)})
|
||||||
return ledgers
|
return ledgers
|
||||||
|
|
||||||
|
|
||||||
@view_config(request_method='GET', route_name='account_type_list', renderer='json', xhr=True, permission='Authenticated')
|
@view_config(request_method='GET', route_name='account_type_list', renderer='json', xhr=True,
|
||||||
|
permission='Authenticated')
|
||||||
def account_type_list(request):
|
def account_type_list(request):
|
||||||
account_types = []
|
account_types = []
|
||||||
for item in LedgerType.list():
|
for item in LedgerType.list():
|
||||||
@@ -86,11 +91,11 @@ def account_type_list(request):
|
|||||||
def account_info(id):
|
def account_info(id):
|
||||||
if id is None:
|
if id is None:
|
||||||
account = {'Code': '(Auto)', 'Type': LedgerType.by_name('Creditors').id, 'IsActive': True,
|
account = {'Code': '(Auto)', 'Type': LedgerType.by_name('Creditors').id, 'IsActive': True,
|
||||||
'CostCenter': CostCenter.overall()}
|
'IsReconcilable': False, 'CostCenter': CostCenter.overall()}
|
||||||
else:
|
else:
|
||||||
account = Ledger.by_id(id)
|
account = Ledger.by_id(id)
|
||||||
account = {'LedgerID': account.id, 'Code': account.code, 'Name': account.name, 'Type': account.type,
|
account = {'LedgerID': account.id, 'Code': account.code, 'Name': account.name, 'Type': account.type,
|
||||||
'IsActive': account.is_active,
|
'IsActive': account.is_active, 'IsReconcilable':account.is_reconcilable,
|
||||||
'CostCenter': {'CostCenterID': account.costcenter_id, 'Name': account.costcenter.name}}
|
'CostCenter': {'CostCenterID': account.costcenter_id, 'Name': account.costcenter.name}}
|
||||||
return account
|
return account
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
import uuid
|
import uuid
|
||||||
from pyramid.httpexceptions import HTTPFound
|
|
||||||
from pyramid.response import Response
|
from pyramid.response import Response
|
||||||
from pyramid.security import authenticated_userid, remember
|
from pyramid.security import authenticated_userid, remember
|
||||||
|
|
||||||
from pyramid.view import view_config
|
from pyramid.view import view_config
|
||||||
|
import transaction
|
||||||
from brewman import groupfinder
|
from brewman import groupfinder
|
||||||
from brewman.models.auth import Role, User
|
from brewman.models.auth import Role, User, Client
|
||||||
from brewman.views.transactions import session_current_date
|
from brewman.views.transactions import session_current_date
|
||||||
|
|
||||||
@view_config(route_name='services_session_current_date', renderer='json', xhr=True, permission='Authenticated')
|
@view_config(route_name='services_session_current_date', renderer='json', xhr=True, permission='Authenticated')
|
||||||
@@ -48,17 +48,70 @@ def user_permission(request):
|
|||||||
|
|
||||||
@view_config(request_method='POST', route_name='login', renderer='json')
|
@view_config(request_method='POST', route_name='login', renderer='json')
|
||||||
def login(request):
|
def login(request):
|
||||||
username = request.json_body['username']
|
username = request.json_body.get('username', None)
|
||||||
password = request.json_body['password']
|
password = request.json_body.get('password', None)
|
||||||
found, user = User.auth(username, password)
|
found, user = User.auth(username, password)
|
||||||
|
|
||||||
|
# client = request.cookies.get('ClientID', None)
|
||||||
|
# otp = request.json_body.get('otp', None)
|
||||||
|
# client_name = request.json_body.get('ClientName', None)
|
||||||
|
# allowed, response = check_client(client, otp, client_name, user if found else None)
|
||||||
|
|
||||||
|
# if found and allowed:
|
||||||
if found:
|
if found:
|
||||||
headers = remember(request, str(user.id))
|
headers = remember(request, str(user.id))
|
||||||
request.response.headers = headers
|
request.response.headers = headers
|
||||||
|
# if allowed and isinstance(response, Client):
|
||||||
|
# request.response.set_cookie('ClientID', value=str(response.code), max_age=10 * 365 * 24 * 60 * 60)
|
||||||
return request.response
|
return request.response
|
||||||
else:
|
elif not found:
|
||||||
response = Response("Login failed")
|
response = Response("Login failed")
|
||||||
response.status_int = 500
|
response.status_int = 500
|
||||||
return response
|
return response
|
||||||
|
# else:
|
||||||
|
# return response
|
||||||
|
|
||||||
|
|
||||||
|
def check_client(client, otp, client_name, user):
|
||||||
|
client = None if client is None else Client.by_code(client)
|
||||||
|
|
||||||
|
if len(Client.enabled_list()) == 0 and user is not None and 'Clients' in groupfinder(user.id, None):
|
||||||
|
client = Client.create()
|
||||||
|
client.otp = None
|
||||||
|
client.name = 'First'
|
||||||
|
client.enabled = True
|
||||||
|
transaction.commit()
|
||||||
|
return True, client
|
||||||
|
|
||||||
|
if client is None:
|
||||||
|
client = Client.create()
|
||||||
|
response = Response("Unknown Client")
|
||||||
|
response.status_int = 401
|
||||||
|
response.set_cookie('ClientID', value=str(client.code), max_age=10 * 365 * 24 * 60 * 60)
|
||||||
|
return False, response
|
||||||
|
|
||||||
|
if client.enabled:
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
if client.otp is None:
|
||||||
|
response = Response("Client is Forbidden")
|
||||||
|
response.status_int = 401
|
||||||
|
return False, response
|
||||||
|
|
||||||
|
if otp is None:
|
||||||
|
response = Response("OTP not supplied")
|
||||||
|
response.status_int = 401
|
||||||
|
return False, response
|
||||||
|
elif client.otp != int(otp):
|
||||||
|
response = Response("OTP is wrong")
|
||||||
|
response.status_int = 401
|
||||||
|
return False, response
|
||||||
|
else:
|
||||||
|
client.otp = None
|
||||||
|
client.enabled = True
|
||||||
|
client.name = client_name
|
||||||
|
transaction.commit()
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
|
||||||
def get_first_day(dt, d_years=0, d_months=0):
|
def get_first_day(dt, d_years=0, d_months=0):
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ def delete(request):
|
|||||||
item.product.name))
|
item.product.name))
|
||||||
item.batch.quantity_remaining -= item.quantity
|
item.batch.quantity_remaining -= item.quantity
|
||||||
elif voucher.type == 'Purchase Return':
|
elif voucher.type == 'Purchase Return':
|
||||||
pass
|
for item in voucher.inventories:
|
||||||
|
item.batch.quantity_remaining += item.quantity
|
||||||
DBSession.delete(voucher)
|
DBSession.delete(voucher)
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
return blank_voucher(additionalInfo=json_voucher)
|
return blank_voucher(additionalInfo=json_voucher)
|
||||||
@@ -142,6 +143,8 @@ def blank_voucher(type=None, date=None, additionalInfo=None):
|
|||||||
json_voucher['Journals'].append({'Ledger': LedgerBase.cash_in_hand(), 'Amount': 0, 'Debit': 1})
|
json_voucher['Journals'].append({'Ledger': LedgerBase.cash_in_hand(), 'Amount': 0, 'Debit': 1})
|
||||||
elif type == 'Purchase':
|
elif type == 'Purchase':
|
||||||
json_voucher['Journals'].append({'Ledger': LedgerBase.local_purchase(), 'Amount': 0, 'Debit': -1})
|
json_voucher['Journals'].append({'Ledger': LedgerBase.local_purchase(), 'Amount': 0, 'Debit': -1})
|
||||||
|
elif type == 'Purchase Return':
|
||||||
|
json_voucher['Journals'].append({'Ledger': LedgerBase.local_purchase(), 'Amount': 0, 'Debit': 1})
|
||||||
elif type == 'Issue':
|
elif type == 'Issue':
|
||||||
if additionalInfo is None:
|
if additionalInfo is None:
|
||||||
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
|
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ class blank_voucher_view(object):
|
|||||||
return self.get_blank()
|
return self.get_blank()
|
||||||
|
|
||||||
|
|
||||||
|
@view_config(request_param='type=Purchase Return', permission='Purchase Return')
|
||||||
|
def purchase_return(self):
|
||||||
|
return self.get_blank()
|
||||||
|
|
||||||
|
|
||||||
@view_config(request_param='type=Issue', permission='Issue')
|
@view_config(request_param='type=Issue', permission='Issue')
|
||||||
def issue(self):
|
def issue(self):
|
||||||
voucher_type = self.request.GET.get('type', None)
|
voucher_type = self.request.GET.get('type', None)
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ def purchase_update_journals(voucher, journals):
|
|||||||
journals = dict()
|
journals = dict()
|
||||||
amount = 0
|
amount = 0
|
||||||
for item in voucher.inventories:
|
for item in voucher.inventories:
|
||||||
ledger = Product.by_id(item.product_id).purchase_ledger
|
ledger = Product.by_id(item.product_id).ledger
|
||||||
amount += item.amount
|
amount += item.amount
|
||||||
if ledger.id in journals:
|
if ledger.id in journals:
|
||||||
journals[ledger.id].amount += item.amount
|
journals[ledger.id].amount += item.amount
|
||||||
@@ -142,7 +142,7 @@ def purchase_update_journals(voucher, journals):
|
|||||||
else:
|
else:
|
||||||
DBSession.delete(item)
|
DBSession.delete(item)
|
||||||
voucher.journals.remove(item)
|
voucher.journals.remove(item)
|
||||||
for item in journals:
|
for item in journals.values():
|
||||||
DBSession.add(item)
|
DBSession.add(item)
|
||||||
voucher.journals.append(item)
|
voucher.journals.append(item)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
import datetime
|
||||||
|
from decimal import Decimal
|
||||||
|
import uuid
|
||||||
|
from brewman.models import DBSession
|
||||||
|
from brewman.models.master import Product, LedgerBase
|
||||||
|
from brewman.models.operations import create_purchase_voucher, create_basic
|
||||||
|
from brewman.models.validation_exception import ValidationError
|
||||||
|
from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journal
|
||||||
|
|
||||||
|
__author__ = 'tanshu'
|
||||||
|
|
||||||
|
def purchase_return_create_voucher(json, user):
|
||||||
|
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']), posted=False)
|
||||||
|
|
||||||
|
create_basic(voucher)
|
||||||
|
|
||||||
|
for item in json['Inventories']:
|
||||||
|
purchase_return_create_inventory(voucher, item)
|
||||||
|
for item in purchase_return_create_journals(voucher.inventories, json['Journals'][0]['Ledger']['LedgerID']):
|
||||||
|
DBSession.add(item)
|
||||||
|
voucher.journals.append(item)
|
||||||
|
create_purchase_voucher(voucher)
|
||||||
|
DBSession.flush()
|
||||||
|
return voucher
|
||||||
|
|
||||||
|
|
||||||
|
def purchase_return_create_inventory(voucher, item):
|
||||||
|
batch = Batch.by_id(uuid.UUID(item['Batch']['BatchID']))
|
||||||
|
inventory_id = uuid.UUID(item['InventoryID']) if 'InventoryID' in item else None
|
||||||
|
quantity = Decimal(item['Quantity'])
|
||||||
|
|
||||||
|
if quantity <= 0:
|
||||||
|
raise ValidationError("Quantity of {0} cannot be zero".format(item.product.name))
|
||||||
|
if quantity > batch.quantity_remaining:
|
||||||
|
raise ValidationError("Quantity available is {0} only".format(batch.quantity_remaining))
|
||||||
|
|
||||||
|
batch.quantity_remaining -= quantity
|
||||||
|
|
||||||
|
item = Inventory(id=inventory_id, product_id=batch.product.id, quantity=quantity, rate=batch.rate, tax=batch.tax,
|
||||||
|
discount=batch.discount, batch=batch)
|
||||||
|
DBSession.add(item)
|
||||||
|
voucher.inventories.append(item)
|
||||||
|
|
||||||
|
|
||||||
|
def purchase_return_create_journals(inventories, ledgerID):
|
||||||
|
otherLedger = LedgerBase.by_id(uuid.UUID(ledgerID))
|
||||||
|
journals = dict()
|
||||||
|
amount = 0
|
||||||
|
for item in inventories:
|
||||||
|
ledger = Product.by_id(item.product_id).ledger
|
||||||
|
amount += item.amount
|
||||||
|
if ledger.id in journals:
|
||||||
|
journals[ledger.id].amount += item.amount
|
||||||
|
else:
|
||||||
|
journals[ledger.id] = Journal(debit=-1, cost_center_id=ledger.costcenter_id, ledger_id=ledger.id,
|
||||||
|
amount=item.amount)
|
||||||
|
journals[otherLedger.id] = Journal(debit=1, cost_center_id=otherLedger.costcenter_id, ledger_id=otherLedger.id,
|
||||||
|
amount=amount)
|
||||||
|
return list(journals.values())
|
||||||
|
|
||||||
|
|
||||||
|
def purchase_return_update_voucher(voucher, json, user):
|
||||||
|
voucher.date = datetime.datetime.strptime(json['Date'], '%d-%b-%Y')
|
||||||
|
voucher.narration = json['Narration']
|
||||||
|
voucher.user_id = user.id
|
||||||
|
voucher.posted = False
|
||||||
|
voucher.last_edit_date = datetime.datetime.now()
|
||||||
|
|
||||||
|
purchase_return_update_inventory(voucher, json['Inventories'], json['Date'])
|
||||||
|
purchase_return_update_journals(voucher, json['Journals'])
|
||||||
|
return voucher
|
||||||
|
|
||||||
|
|
||||||
|
def purchase_return_update_inventory(voucher, newInventories, date):
|
||||||
|
for it in range(len(voucher.inventories), 0, -1):
|
||||||
|
item = voucher.inventories[it - 1]
|
||||||
|
found = False
|
||||||
|
for j in range(len(newInventories), 0, -1):
|
||||||
|
i = newInventories[j - 1]
|
||||||
|
if 'InventoryID' in i and item.id == uuid.UUID(i['InventoryID']):
|
||||||
|
product = Product.by_id(uuid.UUID(i['Product']['ProductID']))
|
||||||
|
found = True
|
||||||
|
if item.product_id != product.id:
|
||||||
|
raise ValidationError('Product cannot be changed')
|
||||||
|
quantity = Decimal(i['Quantity'])
|
||||||
|
if quantity == 0:
|
||||||
|
raise ValidationError("Quantity of {0} cannot be zero".format(item.product.name))
|
||||||
|
if quantity - item.quantity > item.batch.quantity_remaining:
|
||||||
|
raise ValidationError("Maximum quantity available is {0}".format(
|
||||||
|
item.quantity + item.batch.quantity_remaining))
|
||||||
|
item.batch.quantity_remaining -= (quantity - item.quantity)
|
||||||
|
item.quantity = quantity
|
||||||
|
newInventories.remove(i)
|
||||||
|
break
|
||||||
|
if not found:
|
||||||
|
item.batch.quantity_remaining += item.quantity
|
||||||
|
DBSession.delete(item)
|
||||||
|
voucher.inventories.remove(item)
|
||||||
|
for i in newInventories:
|
||||||
|
purchase_return_create_inventory(voucher, i)
|
||||||
|
|
||||||
|
|
||||||
|
def purchase_return_update_journals(voucher, journals):
|
||||||
|
otherLedger = [ff for ff in journals if ff['Debit'] == 1]
|
||||||
|
otherLedger = LedgerBase.by_id(uuid.UUID(otherLedger[0]['Ledger']['LedgerID']))
|
||||||
|
journals = dict()
|
||||||
|
amount = 0
|
||||||
|
for item in voucher.inventories:
|
||||||
|
ledger = Product.by_id(item.product_id).ledger
|
||||||
|
amount += item.amount
|
||||||
|
if ledger.id in journals:
|
||||||
|
journals[ledger.id].amount += item.amount
|
||||||
|
else:
|
||||||
|
journals[ledger.id] = Journal(debit=-1, cost_center_id=ledger.costcenter_id, ledger_id=ledger.id,
|
||||||
|
amount=item.amount)
|
||||||
|
journals[otherLedger.id] = Journal(debit=1, cost_center_id=otherLedger.costcenter_id, ledger_id=otherLedger.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_center_id = journals[item.ledger_id].cost_center_id
|
||||||
|
del journals[item.ledger_id]
|
||||||
|
else:
|
||||||
|
DBSession.delete(item)
|
||||||
|
voucher.journals.remove(item)
|
||||||
|
for item in journals.values():
|
||||||
|
DBSession.add(item)
|
||||||
|
voucher.journals.append(item)
|
||||||
|
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@ from brewman.models.auth import User
|
|||||||
from brewman.models.validation_exception import ValidationError
|
from brewman.models.validation_exception import ValidationError
|
||||||
from brewman.models.voucher import Voucher
|
from brewman.models.voucher import Voucher
|
||||||
from brewman.views.services.voucher import voucher_info, journal_create_voucher, purchase_create_voucher, issue_create_voucher
|
from brewman.views.services.voucher import voucher_info, journal_create_voucher, purchase_create_voucher, issue_create_voucher
|
||||||
|
from brewman.views.services.voucher.purchase_return import purchase_return_create_voucher
|
||||||
|
|
||||||
__author__ = 'tanshu'
|
__author__ = 'tanshu'
|
||||||
|
|
||||||
@@ -36,6 +37,11 @@ class save_voucher(object):
|
|||||||
return self.save()
|
return self.save()
|
||||||
|
|
||||||
|
|
||||||
|
@view_config(request_param='type=Purchase Return', permission='Purchase Return')
|
||||||
|
def purchase_return(self):
|
||||||
|
return self.save()
|
||||||
|
|
||||||
|
|
||||||
@view_config(request_param='type=Issue', permission='Issue')
|
@view_config(request_param='type=Issue', permission='Issue')
|
||||||
def issue(self):
|
def issue(self):
|
||||||
return self.save()
|
return self.save()
|
||||||
@@ -49,6 +55,8 @@ class save_voucher(object):
|
|||||||
voucher = journal_create_voucher(request.json_body, user)
|
voucher = journal_create_voucher(request.json_body, user)
|
||||||
elif request.json_body['Type'] in ['Purchase']:
|
elif request.json_body['Type'] in ['Purchase']:
|
||||||
voucher = purchase_create_voucher(request.json_body, user)
|
voucher = purchase_create_voucher(request.json_body, user)
|
||||||
|
elif request.json_body['Type'] in ['Purchase Return']:
|
||||||
|
voucher = purchase_return_create_voucher(request.json_body, user)
|
||||||
elif request.json_body['Type'] in ['Issue']:
|
elif request.json_body['Type'] in ['Issue']:
|
||||||
voucher = issue_create_voucher(request.json_body, user)
|
voucher = issue_create_voucher(request.json_body, user)
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from brewman.models.auth import User
|
|||||||
from brewman.models.validation_exception import ValidationError
|
from brewman.models.validation_exception import ValidationError
|
||||||
from brewman.models.voucher import Voucher
|
from brewman.models.voucher import Voucher
|
||||||
from brewman.views.services.voucher import voucher_info, issue_update_voucher, purchase_update_voucher, journal_update_voucher
|
from brewman.views.services.voucher import voucher_info, issue_update_voucher, purchase_update_voucher, journal_update_voucher
|
||||||
|
from brewman.views.services.voucher.purchase_return import purchase_return_update_voucher
|
||||||
|
|
||||||
__author__ = 'tanshu'
|
__author__ = 'tanshu'
|
||||||
|
|
||||||
@@ -53,6 +54,11 @@ class update_voucher(object):
|
|||||||
return self.update()
|
return self.update()
|
||||||
|
|
||||||
|
|
||||||
|
@view_config(request_param='type=Purchase Return', permission='Purchase Return')
|
||||||
|
def purchase_return(self):
|
||||||
|
return self.update()
|
||||||
|
|
||||||
|
|
||||||
@view_config(request_param='type=Issue', permission='Issue')
|
@view_config(request_param='type=Issue', permission='Issue')
|
||||||
def issue(self):
|
def issue(self):
|
||||||
return self.update()
|
return self.update()
|
||||||
@@ -65,6 +71,8 @@ class update_voucher(object):
|
|||||||
voucher = journal_update_voucher(self.voucher, self.json, self.user)
|
voucher = journal_update_voucher(self.voucher, self.json, self.user)
|
||||||
elif self.json['Type'] in ['Purchase']:
|
elif self.json['Type'] in ['Purchase']:
|
||||||
voucher = purchase_update_voucher(self.voucher, self.json, self.user)
|
voucher = purchase_update_voucher(self.voucher, self.json, self.user)
|
||||||
|
elif self.json['Type'] in ['Purchase Return']:
|
||||||
|
voucher = purchase_return_update_voucher(self.voucher, self.json, self.user)
|
||||||
elif self.json['Type'] in ['Issue']:
|
elif self.json['Type'] in ['Issue']:
|
||||||
voucher = issue_update_voucher(self.voucher, self.json, self.user)
|
voucher = issue_update_voucher(self.voucher, self.json, self.user)
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from datetime import date
|
from datetime import date
|
||||||
from pyramid.view import view_config
|
from pyramid.view import view_config
|
||||||
|
|
||||||
|
__author__ = 'tanshu'
|
||||||
|
|
||||||
@view_config(request_method='GET', route_name='journal_id', renderer='brewman:templates/angular_base.mako',
|
@view_config(request_method='GET', route_name='journal_id', renderer='brewman:templates/angular_base.mako',
|
||||||
permission='Journal')
|
permission='Journal')
|
||||||
@@ -18,6 +19,10 @@ from pyramid.view import view_config
|
|||||||
permission='Purchase')
|
permission='Purchase')
|
||||||
@view_config(request_method='GET', route_name='purchase', renderer='brewman:templates/angular_base.mako',
|
@view_config(request_method='GET', route_name='purchase', renderer='brewman:templates/angular_base.mako',
|
||||||
permission='Purchase')
|
permission='Purchase')
|
||||||
|
@view_config(request_method='GET', route_name='purchase_return_id', renderer='brewman:templates/angular_base.mako',
|
||||||
|
permission='Purchase Return')
|
||||||
|
@view_config(request_method='GET', route_name='purchase_return', renderer='brewman:templates/angular_base.mako',
|
||||||
|
permission='Purchase Return')
|
||||||
@view_config(request_method='GET', route_name='issue_id', renderer='brewman:templates/angular_base.mako',
|
@view_config(request_method='GET', route_name='issue_id', renderer='brewman:templates/angular_base.mako',
|
||||||
permission='Issue')
|
permission='Issue')
|
||||||
@view_config(request_method='GET', route_name='issue', renderer='brewman:templates/angular_base.mako',
|
@view_config(request_method='GET', route_name='issue', renderer='brewman:templates/angular_base.mako',
|
||||||
@@ -1,226 +0,0 @@
|
|||||||
import datetime
|
|
||||||
import transaction
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
from decimal import Decimal
|
|
||||||
from pyramid.response import Response
|
|
||||||
|
|
||||||
from pyramid.security import authenticated_userid
|
|
||||||
from pyramid.view import view_config
|
|
||||||
|
|
||||||
|
|
||||||
from brewman.models import DBSession
|
|
||||||
from brewman.models.auth import User
|
|
||||||
from brewman.models.master import Product, Ledger
|
|
||||||
from brewman.models.validation_exception import ValidationError
|
|
||||||
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory, Batch
|
|
||||||
|
|
||||||
|
|
||||||
@view_config(request_method='GET', route_name='purchase_return_id', renderer='brewman:templates/transaction/purchase_return.mako',
|
|
||||||
permission='Purchase Return Update')
|
|
||||||
@view_config(request_method='GET', route_name='purchase_return', renderer='brewman:templates/transaction/purchase_return.mako',
|
|
||||||
permission='Purchase Return Create')
|
|
||||||
def purchase_get(request):
|
|
||||||
id = request.matchdict.get('id', None)
|
|
||||||
if id is None:
|
|
||||||
currentDate = Literal(
|
|
||||||
"CurrentDate('#txtDate', '{0}');".format(request.route_url('services_session_current_date')))
|
|
||||||
voucher_id = ''
|
|
||||||
posted = ''
|
|
||||||
code = ''
|
|
||||||
narration = ''
|
|
||||||
body = ''
|
|
||||||
ledger = ''
|
|
||||||
else:
|
|
||||||
voucher = Voucher.by_id(uuid.UUID(id))
|
|
||||||
currentDate = Literal("$('#txtDate').val('{0}');".format(voucher.date.strftime('%d-%b-%Y')))
|
|
||||||
voucher_id = Literal("$('#VoucherID').val('{0}');".format(voucher.id))
|
|
||||||
posted = Literal("$('#Posted').val(true);") if voucher.posted else ''
|
|
||||||
code = Literal("$('#txtCode').val('{0}');".format(voucher.code))
|
|
||||||
narration = Literal("$('#txtNarration').val('{0}');".format(voucher.narration))
|
|
||||||
body = Literal(build_body(voucher))
|
|
||||||
|
|
||||||
for item in voucher.journals:
|
|
||||||
if item.debit == 1:
|
|
||||||
journal = item
|
|
||||||
break
|
|
||||||
ledger = Literal("$('#txtLedger').val('{0}');".format(journal.ledger.name))
|
|
||||||
|
|
||||||
return {'title': 'Purchase - Hops n Grains',
|
|
||||||
'pageclass': "page-blogpost page-sidebar-right",
|
|
||||||
'pagecontentclass': "page-content grid_12",
|
|
||||||
'page_header': '',
|
|
||||||
'id': id,
|
|
||||||
'currentDate': currentDate,
|
|
||||||
'voucher_id': voucher_id,
|
|
||||||
'posted': posted,
|
|
||||||
'code': code,
|
|
||||||
'narration': narration,
|
|
||||||
'body': body,
|
|
||||||
'ledger': ledger}
|
|
||||||
|
|
||||||
|
|
||||||
@view_config(request_method='POST', route_name='purchase_return_id', renderer='json', xhr=True, permission='Purchase Return Update')
|
|
||||||
@view_config(request_method='POST', route_name='purchase_return', renderer='json', xhr=True, permission='Purchase Return Create')
|
|
||||||
def purchase_post(request):
|
|
||||||
try:
|
|
||||||
id = request.matchdict.get('id', None)
|
|
||||||
user = User.get_by_id(uuid.UUID(authenticated_userid(request)))
|
|
||||||
if id == None:
|
|
||||||
voucher = create_voucher(request.json_body['voucher'], user)
|
|
||||||
else:
|
|
||||||
voucher = update_voucher(uuid.UUID(id), request.json_body['voucher'], user)
|
|
||||||
transaction.commit()
|
|
||||||
return "Voucher with Code {0} {1}".format(voucher.code, ('Created' if id is None else 'Updated' ))
|
|
||||||
except ValidationError as ex:
|
|
||||||
transaction.abort()
|
|
||||||
response = Response("Failed validation: {0}".format(ex.message))
|
|
||||||
response.status_int = 500
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
def build_body(voucher):
|
|
||||||
body = ''
|
|
||||||
for item in voucher.inventories:
|
|
||||||
body += '<tr class="Inventory" id="{0}"><td class="InventoryID hide">{1}</td>'\
|
|
||||||
'<td class="ProductID hide">{0}</td><td class="Product">{2}</td><td class="Quantity">{3:.5f}</td>'\
|
|
||||||
'<td class="Rate">{4:.5f}</td><td class="Tax">{5:.5f}</td><td class="Discount">{6:.5f}</td>'\
|
|
||||||
'<td class="Amount">{7:.5f}</td><td class="BatchID hide">{8}</td><td class="Delete">'\
|
|
||||||
'<input type="submit" class="subtract" onClick="return DeleteRow(\'{0}\');" value="Delete"/></td></tr>'\
|
|
||||||
.format(str(item.product_id), str(item.id), item.product.full_name, item.quantity, item. rate, item.tax,
|
|
||||||
item.discount, item.amount, str(item.batch_id))
|
|
||||||
return body
|
|
||||||
|
|
||||||
|
|
||||||
def create_voucher(json, user):
|
|
||||||
dt = datetime.datetime.strptime(json['Date'], '%d-%b-%Y')
|
|
||||||
voucher = Voucher(date=dt, narration=json['Narration'], user_id=user.id,
|
|
||||||
type=VoucherType.by_name('Purchase Return'), posted=False)
|
|
||||||
for item in json['Inventories']:
|
|
||||||
voucher.inventories.append(create_inventory(item, json['Date']))
|
|
||||||
for item in create_journals(voucher.inventories, json['Journals'][0]['Ledger']['Name']):
|
|
||||||
voucher.journals.append(item)
|
|
||||||
voucher.create()
|
|
||||||
return voucher
|
|
||||||
|
|
||||||
|
|
||||||
def create_inventory(item, date):
|
|
||||||
product = Product.by_id(uuid.UUID(item['Product']['ProductID']))
|
|
||||||
inventory_id = uuid.UUID(item['InventoryID'])
|
|
||||||
if uuid.UUID('00000000-0000-0000-0000-000000000000') == inventory_id:
|
|
||||||
inventory_id = None
|
|
||||||
quantity = Decimal(item['Quantity'])
|
|
||||||
rate = Decimal(item['Rate'])
|
|
||||||
tax = Decimal(item['Tax'])
|
|
||||||
discount = Decimal(item['Discount'])
|
|
||||||
batch = Batch(name=date, product_id=product.id, quantity_remaining=quantity, rate=rate, tax=tax,
|
|
||||||
discount=discount)
|
|
||||||
return Inventory(id=inventory_id, product_id=product.id, batch=batch, quantity=quantity, rate=rate, tax=tax,
|
|
||||||
discount=discount)
|
|
||||||
|
|
||||||
|
|
||||||
def create_journals(inventories, ledgerString):
|
|
||||||
otherLedger = Ledger.by_name(ledgerString)
|
|
||||||
journals = dict()
|
|
||||||
amount = 0
|
|
||||||
for item in inventories:
|
|
||||||
ledger = Product.by_id(item.product_id).purchase_ledger
|
|
||||||
amount += item.amount
|
|
||||||
if ledger.id in journals:
|
|
||||||
journals[ledger.id].amount += item.amount
|
|
||||||
else:
|
|
||||||
journals[ledger.id] = Journal(debit=1, cost_center_id=ledger.costcenter_id, ledger_id=ledger.id,
|
|
||||||
amount=item.amount)
|
|
||||||
journals[otherLedger.id] = Journal(debit=-1, cost_center_id=otherLedger.costcenter_id, ledger_id=otherLedger.id,
|
|
||||||
amount=amount)
|
|
||||||
return list(journals.values())
|
|
||||||
|
|
||||||
|
|
||||||
def update_voucher(id, json, user):
|
|
||||||
voucher = Voucher.by_id(id)
|
|
||||||
voucher.date = datetime.datetime.strptime(json['Date'], '%d-%b-%Y')
|
|
||||||
voucher.narration = json['Narration']
|
|
||||||
voucher.user_id = user.id
|
|
||||||
voucher.posted = False
|
|
||||||
voucher.last_edit_date = datetime.datetime.now()
|
|
||||||
|
|
||||||
update_inventory(voucher, json['Inventories'], json['Date'])
|
|
||||||
update_journals(voucher, json['Journals'][0]['Ledger']['Name'])
|
|
||||||
return voucher
|
|
||||||
|
|
||||||
|
|
||||||
def update_inventory(voucher, newInventories, date):
|
|
||||||
for item in voucher.inventories:
|
|
||||||
found = False
|
|
||||||
for i in newInventories:
|
|
||||||
if item.id == uuid.UUID(i['InventoryID']):
|
|
||||||
product = Product.by_id(uuid.UUID(i['Product']['ProductID']))
|
|
||||||
found = True
|
|
||||||
if item.product_id != product.id:
|
|
||||||
raise ValidationError('Product cannot be changed')
|
|
||||||
quantity = Decimal(i['Quantity'])
|
|
||||||
if quantity == 0:
|
|
||||||
raise ValidationError("Quantity of {0} cannot be zero".format(item.product.name))
|
|
||||||
if item.quantity - quantity > 0 and item.batch.quantity_remaining < (item.quantity - quantity):
|
|
||||||
raise ValidationError("{0} has been issued, minimum quantity is".format(
|
|
||||||
item.quantity - item.batch.quantity_remaining))
|
|
||||||
item.batch.quantity_remaining -= (item.quantity - quantity)
|
|
||||||
item.quantity = quantity
|
|
||||||
rate = Decimal(i['Rate'])
|
|
||||||
discount = Decimal(i['Discount'])
|
|
||||||
tax = Decimal(i['Tax'])
|
|
||||||
item.rate = rate
|
|
||||||
item.batch.rate = rate
|
|
||||||
item.discount = discount
|
|
||||||
item.batch.discount = discount
|
|
||||||
item.tax = tax
|
|
||||||
item.batch.tax = tax
|
|
||||||
newInventories.remove(i)
|
|
||||||
break
|
|
||||||
if not found:
|
|
||||||
if item.quantity != item.batch.quantity_remaining:
|
|
||||||
raise ValidationError("{0} has been issued, it cannot be deleted".format(item.product.name))
|
|
||||||
else:
|
|
||||||
DBSession.delete(item.batch)
|
|
||||||
DBSession.delete(item)
|
|
||||||
voucher.inventories.remove(item)
|
|
||||||
for i in newInventories:
|
|
||||||
product = Product.by_id(uuid.UUID(i['Product']['ProductID']))
|
|
||||||
quantity = Decimal(i['Quantity'])
|
|
||||||
rate = Decimal(i['Rate'])
|
|
||||||
tax = Decimal(i['Tax'])
|
|
||||||
discount = Decimal(i['Discount'])
|
|
||||||
batch = Batch(name=date, product_id=product.id, quantity_remaining=quantity, rate=rate, tax=tax,
|
|
||||||
discount=discount)
|
|
||||||
inventory = Inventory(id=None, product_id=product.id, batch=batch, quantity=quantity, rate=rate, tax=tax,
|
|
||||||
discount=discount)
|
|
||||||
inventory.create(DBSession)
|
|
||||||
voucher.inventories.append(inventory)
|
|
||||||
|
|
||||||
|
|
||||||
def update_journals(voucher, ledgerString):
|
|
||||||
otherLedger = Ledger.by_name(ledgerString)
|
|
||||||
journals = dict()
|
|
||||||
amount = 0
|
|
||||||
for item in voucher.inventories:
|
|
||||||
ledger = Product.by_id(item.product_id).purchase_ledger
|
|
||||||
amount += item.amount
|
|
||||||
if ledger.id in journals:
|
|
||||||
journals[ledger.id].amount += item.amount
|
|
||||||
else:
|
|
||||||
journals[ledger.id] = Journal(debit=1, cost_center_id=ledger.costcenter_id, ledger_id=ledger.id,
|
|
||||||
amount=item.amount)
|
|
||||||
journals[otherLedger.id] = Journal(debit=-1, cost_center_id=otherLedger.costcenter_id, ledger_id=otherLedger.id,
|
|
||||||
amount=amount)
|
|
||||||
for item in voucher.journals:
|
|
||||||
if item.ledger_id in journals:
|
|
||||||
item.debit = journals[item.ledger_id].debit
|
|
||||||
item.amount = journals[item.ledger_id].amount
|
|
||||||
item.cost_center_id = journals[item.ledger_id].cost_center_id
|
|
||||||
del journals[item.ledger_id]
|
|
||||||
else:
|
|
||||||
DBSession.delete(item)
|
|
||||||
voucher.journals.remove(item)
|
|
||||||
for item in journals:
|
|
||||||
DBSession.add(item)
|
|
||||||
voucher.journals.append(item)
|
|
||||||
Reference in new issue
Block a user