Voucher Service moved into its own directory.

Journal / Payment / Reciept / Purchase / Issue should be complete.
This commit is contained in:
unknown
2012-09-12 13:52:28 +05:30
parent d2dc97695f
commit 9ef3f751f9
13 changed files with 629 additions and 492 deletions

View File

@ -202,6 +202,18 @@ class LedgerBase(Base):
DBSession.add(self)
return self
@classmethod
def all_purchases(cls):
return uuid.UUID('240dd899-c413-854c-a7eb-67a29d154490')
@classmethod
def cash_in_hand(cls):
return {'LedgerID': 'ed2341bb-80b8-9649-90db-f9aaca183bb3', 'Name': 'Cash in Hand'}
@classmethod
def local_purchase(cls):
return {'LedgerID': 'd2b75912-505f-2548-9093-466dfff6a0f9', 'Name': 'local purchase'}
class Employee(LedgerBase):
__tablename__ = 'entities_employees'

View File

@ -51,34 +51,39 @@
}, true);
$scope.$watch('voucher.Journals', function (newJournals, oldJournals) {
if (typeof newJournals === 'undefined' || typeof oldJournals === 'undefined') {
if (typeof newJournals === 'undefined') {
return;
}
var updateGrid = false;
var doUpdate = false;
for (var i = 0, l = newJournals.length; i < l; i++) {
if (newJournals[i].Debit === -1) {
var creditJournal = newJournals[i];
} else {
var debitJournal = newJournals[i];
if (typeof oldJournals !== 'undefined' && typeof $scope.source === 'undefined' ) {
for (var i = 0, l = oldJournals.length; i < l; i++) {
if (oldJournals[i].Debit === -1) {
$scope.source = oldJournals[i].CostCenter.CostCenterID;
} else {
$scope.destination = oldJournals[i].CostCenter.CostCenterID;
}
}
doUpdate = true;
}
if (!doUpdate) {
for (var i = 0, l = newJournals.length; i < l; i++) {
if (newJournals[i].Debit === -1) {
if (newJournals[i].CostCenter.CostCenterID != $scope.source){
$scope.source = newJournals[i].CostCenter.CostCenterID;
doUpdate = true;
}
} else {
if (newJournals[i].CostCenter.CostCenterID != $scope.destination){
$scope.destination = newJournals[i].CostCenter.CostCenterID;
doUpdate = true;
}
}
}
}
for (var i = 0, l = oldJournals.length; i < l; i++) {
if (oldJournals[i].Debit === -1) {
if (creditJournal.CostCenter.CostCenterID != newJournals[i].CostCenter.CostCenterID) {
updateGrid = true;
break;
}
;
} else {
if (debitJournal.CostCenter.CostCenterID != newJournals[i].CostCenter.CostCenterID) {
updateGrid = true;
break;
}
;
}
}
if (updateGrid) {
if (doUpdate) {
$scope.updateGrid();
}
}, true);
@ -96,9 +101,15 @@
}
}, true);
$scope.resetVoucher = function (voucherid) {
$scope.voucher = Voucher.get({id:voucherid, type:'Issue'}, function () {
}, function (data, status) {
$scope.toasts.push({Type:'Error', Message:data.data});
});
};
$scope.get = function (voucherid) {
$scope.voucher = Voucher.get({id:voucherid}, function (u, putResponseHeaders) {
$scope.toasts.push({Type:'Success', Message:u.Code});
$scope.voucher = Voucher.get({id:voucherid}, function () {
}, function (data, status) {
$scope.toasts.push({Type:'Error', Message:data.data});
});
@ -107,6 +118,7 @@
$scope.save = function () {
$scope.voucher.$save(function (u, putResponseHeaders) {
$scope.toasts.push({Type:'Success', Message:u.Code});
$scope.updateGrid();
}, function (data, status) {
$scope.toasts.push({Type:'Error', Message:data.data});
});
@ -115,14 +127,7 @@
$scope.delete = function () {
$scope.voucher.$delete(function (u, putResponseHeaders) {
$scope.toasts.push({Type:'Success', Message:''});
}, 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});
$scope.updateGrid();
}, function (data, status) {
$scope.toasts.push({Type:'Error', Message:data.data});
});

View File

@ -141,9 +141,13 @@
ng-disabled="!auth.isUserInRole('Issue Update')">
Update
</button>
<button class="btn btn-danger">
<button class="btn btn-danger" ng-click="resetVoucher(voucher.VoucherID)" ng-hide="voucher.Code == '(Auto)'">
New Entry
</button>
<button class="btn btn-danger" ng-click="delete()" ng-hide="voucher.Code == '(Auto)'"
ng-disabled="!auth.isUserInRole('Issue Delete')">
Delete
</button>
</div>
<div class="row-fluid">
Created on {{voucher.CreationDate}} and Last Edited on {{voucher.LastEditDate}} by {{voucher.User}}. Posted

View File

@ -1,349 +0,0 @@
import datetime
from decimal import Decimal
import uuid
from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.view import view_config
import transaction
from brewman.models import DBSession
from brewman.models.auth import User
from brewman.models.master import LedgerBase, Product
from brewman.models.operations import create_journal_voucher, update_journal_voucher, create_purchase_voucher
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Voucher, VoucherType, Journal, Inventory, Batch
@view_config(request_method='POST', route_name='voucher_new', renderer='json', xhr=True)
@view_config(request_method='POST', route_name='voucher', renderer='json', xhr=True)
def voucher_post(request):
print('Voucher Posted')
id = request.matchdict.get('id', None)
post_voucher = request.POST.get('post', None)
user = User.get_by_id(uuid.UUID(authenticated_userid(request)))
try:
if id and post_voucher:
return post_voucher(id, user)
elif id:
""" update voucher """
id = uuid.UUID(id)
if request.json_body['Type'] in ['Journal', 'Payment', 'Receipt']:
voucher = journal_update_voucher(id, request.json_body, user)
elif request.json_body['Type'] in ['Purchase']:
voucher = purchase_update_voucher(id, request.json_body, user)
elif request.json_body['Type'] in ['Issue']:
voucher = issue_update_voucher(id, request.json_body, user)
else:
""" new voucher """
if request.json_body['Type'] in ['Journal', 'Payment', 'Receipt']:
voucher = journal_create_voucher(request.json_body, user)
elif request.json_body['Type'] in ['Purchase']:
voucher = purchase_create_voucher(request.json_body, user)
elif request.json_body['Type'] in ['Issue']:
voucher = issue_create_voucher(request.json_body, user)
transaction.commit()
return voucher_info(Voucher.by_id(voucher.id))
except ValidationError as ex:
print('error')
print(ex.message)
transaction.abort()
response = Response("Failed validation: {0}".format(ex.message))
response.status_int = 500
return response
def journal_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)
for item in json['Journals']:
ledger = LedgerBase.by_id(uuid.UUID(item['Ledger']['LedgerID']))
journal_id = uuid.UUID(item['JournalID']) if 'JournalID' in item else None
voucher.journals.append(
Journal(id=journal_id, amount=Decimal(item['Amount']), debit=int(item['Debit']), ledger_id=ledger.id,
cost_center_id=ledger.costcenter_id))
create_journal_voucher(voucher)
return voucher
def journal_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()
newJournals = json['Journals']
for i in range(len(voucher.journals), 0, -1):
item = voucher.journals[i - 1]
found = False
for i in range(len(newJournals), 0, -1):
j = newJournals[i - 1]
if 'JournalID' in j and item.id == uuid.UUID(j['JournalID']):
ledger = LedgerBase.by_id(uuid.UUID(j['Ledger']['LedgerID']))
found = True
item.debit = int(j['Debit'])
item.amount = Decimal(j['Amount'])
item.ledger_id = ledger.id
item.cost_center_id = ledger.costcenter_id
newJournals.remove(j)
break
if not found:
voucher.journals.remove(item)
for j in newJournals:
ledger = LedgerBase.by_id(uuid.UUID(j['Ledger']['LedgerID']))
journal = Journal(id=None, amount=Decimal(j['Amount']), debit=int(j['Debit']), ledger_id=ledger.id,
cost_center_id=ledger.costcenter_id)
DBSession.add(journal)
voucher.journals.append(journal)
update_journal_voucher(voucher)
# voucher.validate()
return voucher
def purchase_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)
for item in json['Inventories']:
voucher.inventories.append(purchase_create_inventory(item, json['Date']))
for item in purchase_create_journals(voucher.inventories, json['Journals'][0]['Ledger']['LedgerID']):
voucher.journals.append(item)
create_purchase_voucher(voucher)
return voucher
def purchase_create_inventory(item, date):
product = Product.by_id(uuid.UUID(item['Product']['ProductID']))
inventory_id = uuid.UUID(item['InventoryID']) if 'InventoryID' in item else 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 purchase_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).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 purchase_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()
purchase_update_inventory(voucher, json['Inventories'], json['Date'])
purchase_update_journals(voucher, json['Journals'])
return voucher
def purchase_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 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.voucher_id = voucher.id
DBSession.add(inventory.batch)
inventory.batch_id = inventory.batch.id
DBSession.add(inventory)
voucher.inventories.append(inventory)
def purchase_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).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 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:
print(item)
DBSession.add(item)
voucher.journals.append(item)
def issue_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('Issue'),
posted=False)
for item in json['Inventories']:
voucher.inventories.append(issue_get_inventory(item))
for item in json['Journals']:
if int(item['Debit']) == 1:
destination = uuid.UUID(item['CostCenter']['CostCenterID'])
else:
source = uuid.UUID(item['CostCenter']['CostCenterID'])
for item in issue_get_journals(voucher.inventories, source, destination):
voucher.journals.append(item)
voucher.create()
return voucher
def issue_get_inventory(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'])
print(str(batch.quantity_remaining))
return Inventory(id=inventory_id, product_id=batch.product.id, quantity=quantity, rate=batch.rate, tax=batch.tax,
discount=batch.discount, batch=batch)
def issue_get_journals(inventories, source, destination):
journalsSource = dict()
journalsDestination = dict()
amount = 0
for item in inventories:
ledger = Product.by_id(item.product_id).purchase_ledger
amount += item.amount
if ledger.id in journalsSource:
journalsSource[ledger.id].amount += item.amount
journalsDestination[ledger.id].amount += item.amount
else:
journalsSource[ledger.id] = Journal(debit=-1, ledger_id=ledger.id, amount=item.amount,
cost_center_id=source)
journalsDestination[ledger.id] = Journal(debit=1, ledger_id=ledger.id, amount=item.amount,
cost_center_id=destination)
journals = list(journalsSource.values())
journals.extend(list(journalsDestination.values()))
return journals
def post_voucher(id, user):
voucher = Voucher.by_id(uuid.UUID(id))
voucher.posted = True
voucher.poster_id = user.id
transaction.commit()
return voucher_info(voucher)
@view_config(request_method='DELETE', route_name='voucher', renderer='json', xhr=True)
def delete(request):
id = request.matchdict.get('id', None)
if id is None:
response = Response("Voucher is Null")
response.status_int = 500
return response
else:
voucher = Voucher.by_id(uuid.UUID(id))
DBSession.delete(voucher)
transaction.commit()
return {}
@view_config(request_method='GET', route_name='voucher', renderer='json', xhr=True)
def get(request):
id = request.matchdict.get('id', None)
if id is None:
response = Response("Voucher is Null")
response.status_int = 500
return response
else:
voucher = Voucher.by_id(uuid.UUID(id))
return voucher_info(voucher)
def voucher_info(voucher):
json_voucher = {'VoucherID': voucher.id,
'Date': voucher.date.strftime('%d-%b-%Y'),
'Type': VoucherType.by_id(voucher.type).name,
'Code': voucher.code,
'Posted': voucher.posted,
'Narration': voucher.narration,
'Journals': [],
'Inventories': [],
'CreationDate': voucher.creation_date.strftime('%d-%b-%Y %H:%M'),
'LastEditDate': voucher.last_edit_date.strftime('%d-%b-%Y %H:%M'),
'User': voucher.user.name,
'Poster': voucher.poster.name if voucher.posted else ''}
for item in voucher.journals:
json_voucher['Journals'].append({'JournalID': item.id, 'Debit': item.debit, 'Amount': item.amount,
'Ledger': {'LedgerID': item.ledger.id, 'Name': item.ledger.name},
'CostCenter': {'CostCenterID': item.cost_center_id}})
for item in voucher.inventories:
json_voucher['Inventories'].append(
{'InventoryID': item.id, 'Quantity': item.quantity, 'Rate': item.rate,
'Tax': item.tax, 'Discount': item.discount, 'Amount': item.amount,
'Product': {'ProductID': item.product.id, 'Name': item.product.name, 'Units': item.product.units},
'Batch': {'BatchID': item.batch.id, 'QuantityRemaining': item.batch.quantity_remaining}})
return json_voucher

View File

@ -0,0 +1,191 @@
import json
import uuid
from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.view import view_config
import transaction
from brewman.models import DBSession
from brewman.models.auth import User
from brewman.models.master import LedgerBase, CostCenter
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Voucher, VoucherType
from brewman.views import DecimalEncoder
from brewman.views.services.voucher.issue import issue_create_voucher, issue_update_voucher
from brewman.views.services.voucher.journal import journal_update_voucher, journal_create_voucher
from brewman.views.services.voucher.purchase import purchase_create_voucher, purchase_update_voucher
__author__ = 'tanshu'
@view_config(request_method='POST', route_name='voucher_new', renderer='json', xhr=True)
@view_config(request_method='POST', route_name='voucher', renderer='json', xhr=True)
def voucher_post(request):
id = request.matchdict.get('id', None)
post_voucher = request.POST.get('post', None)
user = User.get_by_id(uuid.UUID(authenticated_userid(request)))
try:
if id and post_voucher:
return post_voucher(id, user)
elif id:
""" update voucher """
id = uuid.UUID(id)
if request.json_body['Type'] in ['Journal', 'Payment', 'Receipt']:
voucher = journal_update_voucher(id, request.json_body, user)
elif request.json_body['Type'] in ['Purchase']:
voucher = purchase_update_voucher(id, request.json_body, user)
elif request.json_body['Type'] in ['Issue']:
voucher = issue_update_voucher(id, request.json_body, user)
else:
""" new voucher """
if request.json_body['Type'] in ['Journal', 'Payment', 'Receipt']:
voucher = journal_create_voucher(request.json_body, user)
elif request.json_body['Type'] in ['Purchase']:
voucher = purchase_create_voucher(request.json_body, user)
elif request.json_body['Type'] in ['Issue']:
voucher = issue_create_voucher(request.json_body, user)
transaction.commit()
return voucher_info(Voucher.by_id(voucher.id))
except ValidationError as ex:
print('error')
print(ex.message)
transaction.abort()
response = Response("Failed validation: {0}".format(ex.message))
response.status_int = 500
return response
def post_voucher(id, user):
voucher = Voucher.by_id(uuid.UUID(id))
voucher.posted = True
voucher.poster_id = user.id
transaction.commit()
return voucher_info(voucher)
@view_config(request_method='DELETE', route_name='voucher', renderer='json', xhr=True)
def delete(request):
id = request.matchdict.get('id', None)
if id is None:
response = Response("Voucher is Null")
response.status_int = 500
return response
else:
voucher = Voucher.by_id(uuid.UUID(id))
json_voucher = voucher_info(voucher)
if voucher.type == 'Issue':
for item in voucher.journals:
if item.debit == 1:
destination = item.cost_center_id
else:
source = item.cost_center_id
batch_consumed = True if source == CostCenter.cost_center_purchase() else False if destination == CostCenter.cost_center_purchase() else None
if batch_consumed is None:
pass
elif batch_consumed:
for item in voucher.inventories:
item.batch.quantity_remaining += item.quantity
else:
for item in voucher.inventories:
if item.batch.quantity_remaining < item.batch.quantity_remaining:
raise ValueError(
'Quantity remaining for {0} is less than issued, hence cannot be deleted'.format(
item.product.name))
item.batch.quantity_remaining -= item.quantity
elif voucher.type == 'Purchase':
for item in voucher.inventories:
if item.batch.quantity_remaining < item.batch.quantity_remaining:
raise ValueError('Quantity remaining for {0} is less than issued, hence cannot be deleted'.format(
item.product.name))
item.batch.quantity_remaining -= item.quantity
elif voucher.type == 'Purchase Return':
pass
DBSession.delete(voucher)
transaction.commit()
return blank_voucher(additionalInfo=json_voucher)
@view_config(request_method='GET', route_name='voucher_new', renderer='json', xhr=True)
@view_config(request_method='GET', route_name='voucher', renderer='json', xhr=True)
def get(request):
id = request.matchdict.get('id', None)
voucher_type = request.GET.get('type', None)
if id is None:
response = Response("Voucher is Null")
response.status_int = 500
return response
else:
voucher = voucher_info(Voucher.by_id(uuid.UUID(id)))
if voucher_type is None:
return voucher
else:
# voucher = json.dumps(voucher, cls=DecimalEncoder)
return blank_voucher(type=voucher_type, additionalInfo=voucher)
def voucher_info(voucher):
json_voucher = {'VoucherID': voucher.id,
'Date': voucher.date.strftime('%d-%b-%Y'),
'Type': VoucherType.by_id(voucher.type).name,
'Code': voucher.code,
'Posted': voucher.posted,
'Narration': voucher.narration,
'Journals': [],
'Inventories': [],
'CreationDate': voucher.creation_date.strftime('%d-%b-%Y %H:%M'),
'LastEditDate': voucher.last_edit_date.strftime('%d-%b-%Y %H:%M'),
'User': voucher.user.name,
'Poster': voucher.poster.name if voucher.posted else ''}
for item in voucher.journals:
json_voucher['Journals'].append({'JournalID': item.id, 'Debit': item.debit, 'Amount': item.amount,
'Ledger': {'LedgerID': item.ledger.id, 'Name': item.ledger.name},
'CostCenter': {'CostCenterID': item.cost_center_id}})
for item in voucher.inventories:
json_voucher['Inventories'].append(
{'InventoryID': item.id, 'Quantity': item.quantity, 'Rate': item.rate,
'Tax': item.tax, 'Discount': item.discount, 'Amount': item.amount,
'Product': {'ProductID': item.product.id, 'Name': item.product.name, 'Units': item.product.units},
'Batch': {'BatchID': item.batch.id, 'QuantityRemaining': item.batch.quantity_remaining}})
return json_voucher
def blank_voucher(type=None, date=None, additionalInfo=None):
if type is None and 'Type' not in additionalInfo:
raise ValidationError('Voucher Type is null and no information is provided in additional information')
elif type is None:
type = additionalInfo['Type']
if date is None and additionalInfo is None:
raise ValidationError('Both Date and Additional Information cannot be null')
elif date is None:
date = additionalInfo['Date']
json_voucher = {'Code': '(Auto)', 'Type': type, 'Date': date, 'Posted': False,
'Narration': "", 'Journals': [], 'Inventories': []}
if type == 'Journal':
pass
elif type == 'Payment':
json_voucher['Journals'].append({'Ledger': LedgerBase.cash_in_hand(), 'Amount': 0, 'Debit': -1})
elif type == 'Receipt':
json_voucher['Journals'].append({'Ledger': LedgerBase.cash_in_hand(), 'Amount': 0, 'Debit': 1})
elif type == 'Purchase':
json_voucher['Journals'].append({'Ledger': LedgerBase.local_purchase(), 'Amount': 0, 'Debit': -1})
elif type == 'Issue':
if additionalInfo is None:
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
'Amount': 0,
'Debit': -1,
'CostCenter': {'CostCenterID': CostCenter.cost_center_purchase()}})
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
'Amount': 0,
'Debit': 1,
'CostCenter': {'CostCenterID': CostCenter.cost_center_kitchen()}})
else:
json_voucher['Date'] = additionalInfo['Date']
for item in additionalInfo['Journals']:
json_voucher['Journals'].append({'Ledger': {'LedgerID': item['Ledger']['LedgerID']},
'Amount': 0,
'Debit': item['Debit'],
'CostCenter': {'CostCenterID': item['CostCenter']['CostCenterID']}})
else:
raise ValidationError("Voucher of type \"{0}\" does not exist.".format(type))
return json_voucher

View File

@ -0,0 +1,159 @@
import datetime
from decimal import Decimal
import uuid
from brewman.models import DBSession
from brewman.models.master import Product, CostCenter, LedgerBase
from brewman.models.operations import create_basic
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journal
__author__ = 'tanshu'
def issue_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('Issue'),
posted=False)
create_basic(voucher)
for item in json['Journals']:
if int(item['Debit']) == 1:
destination = uuid.UUID(item['CostCenter']['CostCenterID'])
else:
source = uuid.UUID(item['CostCenter']['CostCenterID'])
if source == destination:
raise ValidationError("Source cannot be the same as destination")
batch_consumed = True if source == CostCenter.cost_center_purchase() else False if destination == CostCenter.cost_center_purchase() else None
for item in json['Inventories']:
issue_create_inventory(voucher, item, batch_consumed)
for item in issue_create_journals(voucher.inventories, source, destination):
DBSession.add(item)
voucher.journals.append(item)
DBSession.flush()
return voucher
def issue_create_inventory(voucher, item, batch_consumed):
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 batch_consumed == True and quantity > batch.quantity_remaining:
raise ValidationError("Quantity available is {0} only".format(item.batch.quantity_remaining))
if batch_consumed is None:
pass
elif batch_consumed:
batch.quantity_remaining -= quantity
else:
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 issue_create_journals(inventories, source, destination):
amount = 0
for item in inventories:
amount += item.amount
return [Journal(debit=-1, ledger_id=LedgerBase.all_purchases(), amount=item.amount,
cost_center_id=source),
Journal(debit=1, ledger_id=LedgerBase.all_purchases(), amount=item.amount,
cost_center_id=destination)]
def issue_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.last_edit_date = datetime.datetime.now()
for item in json['Journals']:
if int(item['Debit']) == 1:
destination = uuid.UUID(item['CostCenter']['CostCenterID'])
else:
source = uuid.UUID(item['CostCenter']['CostCenterID'])
if source == destination:
raise ValidationError("Source cannot be the same as destination")
new_batch_consumed = True if source == CostCenter.cost_center_purchase() else False if destination == CostCenter.cost_center_purchase() else None
for item in voucher.journals:
if item.debit == 1:
destination = item.cost_center_id
else:
source = item.cost_center_id
old_batch_consumed = True if source == CostCenter.cost_center_purchase() else False if destination == CostCenter.cost_center_purchase() else None
if new_batch_consumed != old_batch_consumed:
raise ValidationError("Purchase cost center cannot be changed")
issue_update_inventory(voucher, json['Inventories'], old_batch_consumed)
issue_update_journals(voucher, source, destination)
return voucher
def issue_update_inventory(voucher, newInventories, batch_consumed):
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 batch_consumed == True and quantity - item.quantity > item.batch.quantity_remaining:
raise ValidationError("Maximum quantity available is {0}".format(
item.quantity + item.batch.quantity_remaining))
if batch_consumed is None:
pass
elif batch_consumed:
item.batch.quantity_remaining -= (quantity - item.quantity)
else:
item.batch.quantity_remaining += (quantity - item.quantity)
item.quantity = quantity
newInventories.remove(i)
break
if not found:
if batch_consumed is None:
pass
elif batch_consumed:
item.batch.quantity_remaining += item.quantity
else:
if item.batch.quantity_remaining < item.quantity:
raise ValidationError(
"Product {0} cannot be removed, minimum quantity is {1}".format(item.product.name,
item.batch.quantity_remaining))
item.batch.quantity_remaining -= item.quantity
DBSession.delete(item)
voucher.inventories.remove(item)
for i in newInventories:
issue_create_inventory(voucher, i, batch_consumed)
def issue_update_journals(voucher, source, destination):
amount = 0
for item in voucher.inventories:
amount += item.amount
for i in range(len(voucher.journals), 0, -1):
item = voucher.journals[i - 1]
if item.debit == -1:
item.cost_center_id = source
item.amount = amount
else:
item.cost_center_id = destination
item.amount = amount

View File

@ -0,0 +1,60 @@
import datetime
from decimal import Decimal
import uuid
from brewman.models import DBSession
from brewman.models.master import LedgerBase
from brewman.models.operations import update_journal_voucher, create_journal_voucher
from brewman.models.voucher import Journal, Voucher, VoucherType
__author__ = 'tanshu'
def journal_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)
for item in json['Journals']:
ledger = LedgerBase.by_id(uuid.UUID(item['Ledger']['LedgerID']))
journal_id = uuid.UUID(item['JournalID']) if 'JournalID' in item else None
voucher.journals.append(
Journal(id=journal_id, amount=Decimal(item['Amount']), debit=int(item['Debit']), ledger_id=ledger.id,
cost_center_id=ledger.costcenter_id))
create_journal_voucher(voucher)
return voucher
def journal_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()
newJournals = json['Journals']
for i in range(len(voucher.journals), 0, -1):
item = voucher.journals[i - 1]
found = False
for i in range(len(newJournals), 0, -1):
j = newJournals[i - 1]
if 'JournalID' in j and item.id == uuid.UUID(j['JournalID']):
ledger = LedgerBase.by_id(uuid.UUID(j['Ledger']['LedgerID']))
found = True
item.debit = int(j['Debit'])
item.amount = Decimal(j['Amount'])
item.ledger_id = ledger.id
item.cost_center_id = ledger.costcenter_id
newJournals.remove(j)
break
if not found:
voucher.journals.remove(item)
for j in newJournals:
ledger = LedgerBase.by_id(uuid.UUID(j['Ledger']['LedgerID']))
journal = Journal(id=None, amount=Decimal(j['Amount']), debit=int(j['Debit']), ledger_id=ledger.id,
cost_center_id=ledger.costcenter_id)
DBSession.add(journal)
voucher.journals.append(journal)
update_journal_voucher(voucher)
# voucher.validate()
return voucher

View File

@ -0,0 +1,151 @@
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
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory, Journal
__author__ = 'tanshu'
def purchase_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)
for item in json['Inventories']:
voucher.inventories.append(purchase_create_inventory(item, json['Date']))
for item in purchase_create_journals(voucher.inventories, json['Journals'][0]['Ledger']['LedgerID']):
voucher.journals.append(item)
create_purchase_voucher(voucher)
return voucher
def purchase_create_inventory(item, date):
product = Product.by_id(uuid.UUID(item['Product']['ProductID']))
inventory_id = uuid.UUID(item['InventoryID']) if 'InventoryID' in item else 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 purchase_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).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 purchase_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()
purchase_update_inventory(voucher, json['Inventories'], json['Date'])
purchase_update_journals(voucher, json['Journals'])
return voucher
def purchase_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 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.voucher_id = voucher.id
DBSession.add(inventory.batch)
inventory.batch_id = inventory.batch.id
DBSession.add(inventory)
voucher.inventories.append(inventory)
def purchase_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).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 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:
print(item)
DBSession.add(item)
voucher.journals.append(item)

View File

@ -1,21 +1,14 @@
import datetime
from decimal import Decimal
import json
import uuid
from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.view import view_config
import transaction
from brewman.helpers import Literal
from brewman.models.master import Product, CostCenter
from brewman.models.master import CostCenter
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory, Batch
from brewman.models.voucher import Voucher
from brewman.models.auth import User
from brewman.views import DecimalEncoder
from brewman.views.services.voucher import voucher_info
from brewman.views.services.voucher import voucher_info, blank_voucher
from brewman.views.transactions import session_current_date
@view_config(request_method='GET', route_name='issue_id', renderer='brewman:templates/transaction/issue.mako',
@ -31,23 +24,7 @@ def issue_get(request):
cost_centers = Literal(json.dumps(cost_centers, cls=DecimalEncoder))
if id is None:
json_voucher = Literal(
json.dumps({'Code': '(Auto)',
'Type': 'Issue',
'Date': session_current_date(request),
'Narration': "",
'Journals': [
{'Ledger': {},
'Amount': 0,
'Debit': -1,
'CostCenter': {'CostCenterID': CostCenter.cost_center_purchase()}},
{'Ledger': {},
'Amount': 0,
'Debit': 1,
'CostCenter': {'CostCenterID': CostCenter.cost_center_kitchen()}}],
'Inventories': []}, cls=DecimalEncoder
)
)
json_voucher = Literal(json.dumps(blank_voucher('Issue', session_current_date(request)), cls=DecimalEncoder))
else:
voucher = Voucher.by_id(uuid.UUID(id))
json_voucher = Literal(json.dumps(voucher_info(voucher), cls=DecimalEncoder))
@ -57,25 +34,3 @@ def issue_get(request):
'perms': perms,
'cost_centers': cost_centers,
'json_voucher': json_voucher}
@view_config(request_method='POST', route_name='issue_id', renderer='json', xhr=True)
@view_config(request_method='POST', route_name='issue', renderer='json', xhr=True)
def issue_save(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, user)
else:
voucher = update_voucher(uuid.UUID(id), request.json_body, user)
transaction.commit()
return voucher_info(Voucher.by_id(voucher.id))
# 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

View File

@ -1,18 +1,13 @@
import json
import uuid
from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.view import view_config
import transaction
from brewman.helpers import Literal
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Voucher
from brewman.models.auth import User
from brewman.views import DecimalEncoder
from brewman.views.services.voucher import voucher_info
from brewman.views.services.voucher import voucher_info, blank_voucher
from brewman.views.transactions import session_current_date
@view_config(request_method='GET', route_name='journal_id', renderer='brewman:templates/transaction/journal.mako',
@ -23,37 +18,11 @@ def journal_get(request):
id = request.matchdict.get('id', None)
perms = Literal(json.dumps(request.session['perms']))
if id is None:
json_voucher = Literal(
json.dumps({'Code': '(Auto)', 'Type': 'Journal', 'Date': session_current_date(request), 'Posted': False,
'Narration': "", 'Journals': []}))
json_voucher = Literal(json.dumps(blank_voucher('Journal', session_current_date(request)), cls=DecimalEncoder))
else:
voucher = Voucher.by_id(uuid.UUID(id))
json_voucher = Literal(json.dumps(voucher_info(voucher), cls=DecimalEncoder))
return {'title': 'Hops n Grains - Journal Entry',
'id': id,
'perms': perms,
'json_voucher': json_voucher}
@view_config(request_method='POST', route_name='journal_id', renderer='json', xhr=True, permission='Journal Update')
@view_config(request_method='POST', route_name='journal', renderer='json', xhr=True, permission='Journal Create')
def journal_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, user)
else:
voucher = update_voucher(uuid.UUID(id), request.json_body, user)
transaction.commit()
return voucher_info(Voucher.by_id(voucher.id))
# 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
'json_voucher': json_voucher}

View File

@ -1,19 +1,14 @@
import json
import uuid
from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.view import view_config
import transaction
from brewman.helpers import Literal
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Voucher
from brewman.models.auth import User
from brewman.views import DecimalEncoder
from brewman.views.services.ledger import ledger_list
from brewman.views.services.voucher import voucher_info
from brewman.views.services.voucher import voucher_info, blank_voucher
from brewman.views.transactions import session_current_date
@ -26,11 +21,7 @@ def journal_get(request):
perms = Literal(json.dumps(request.session['perms']))
ledgers = Literal(json.dumps(ledger_list(type=1), cls=DecimalEncoder))
if id is None:
json_voucher = Literal(
json.dumps({'Code': '(Auto)', 'Type': 'Payment', 'Date': session_current_date(request), 'Posted': False, 'Narration': "",
'Journals': [{'Ledger': {'LedgerID': 'ed2341bb-80b8-9649-90db-f9aaca183bb3',
'Name': 'Cash in Hand'},
'Amount': 0, 'Debit': -1}]}))
json_voucher = Literal(json.dumps(blank_voucher('Payment', session_current_date(request)), cls=DecimalEncoder))
else:
voucher = Voucher.by_id(uuid.UUID(id))
json_voucher = Literal(json.dumps(voucher_info(voucher), cls=DecimalEncoder))

View File

@ -7,7 +7,7 @@ from brewman.helpers import Literal
from brewman.models.voucher import Voucher
from brewman.views import DecimalEncoder
from brewman.views.services.voucher import voucher_info
from brewman.views.services.voucher import voucher_info, blank_voucher
from brewman.views.transactions import session_current_date
@ -19,12 +19,7 @@ def purchase_get(request):
id = request.matchdict.get('id', None)
perms = Literal(json.dumps(request.session['perms']))
if id is None:
json_voucher = Literal(
json.dumps({'Code': '(Auto)', 'Type': 'Purchase', 'Date': session_current_date(request), 'Posted': False,
'Narration': "",
'Journals': [{
'Ledger': {'LedgerID': 'd2b75912-505f-2548-9093-466dfff6a0f9', 'Name': 'local purchase'},
'Amount': 0, 'Debit': -1}], 'Inventories': []}))
json_voucher = Literal(json.dumps(blank_voucher('Purchase', session_current_date(request)), cls=DecimalEncoder))
else:
voucher = Voucher.by_id(uuid.UUID(id))
json_voucher = Literal(json.dumps(voucher_info(voucher), cls=DecimalEncoder))

View File

@ -8,7 +8,7 @@ from brewman.models.voucher import Voucher
from brewman.views import DecimalEncoder
from brewman.views.services.ledger import ledger_list
from brewman.views.services.voucher import voucher_info
from brewman.views.services.voucher import voucher_info, blank_voucher
from brewman.views.transactions import session_current_date
@ -21,13 +21,7 @@ def journal_get(request):
perms = Literal(json.dumps(request.session['perms']))
ledgers = Literal(json.dumps(ledger_list(type=1)))
if id is None:
json_voucher = Literal(
json.dumps({'Code': '(Auto)', 'Type': 'Receipt', 'Date': session_current_date(request), 'Posted': False,
'Narration': "",
'Journals': [{'JournalID': '00000000-0000-0000-0000-000000000000',
'Ledger': {'LedgerID': 'ed2341bb-80b8-9649-90db-f9aaca183bb3',
'Name': 'Cash in Hand'},
'Amount': 0, 'Debit': 1}]}))
json_voucher = Literal(json.dumps(blank_voucher('Receipt', session_current_date(request)), cls=DecimalEncoder))
else:
voucher = Voucher.by_id(uuid.UUID(id))
json_voucher = Literal(json.dumps(voucher_info(voucher), cls=DecimalEncoder))