Voucher Service moved into its own directory.
Journal / Payment / Reciept / Purchase / Issue should be complete.
This commit is contained in:
@ -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'
|
||||
|
||||
@ -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});
|
||||
});
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
191
brewman/brewman/views/services/voucher/__init__.py
Normal file
191
brewman/brewman/views/services/voucher/__init__.py
Normal 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
|
||||
159
brewman/brewman/views/services/voucher/issue.py
Normal file
159
brewman/brewman/views/services/voucher/issue.py
Normal 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
|
||||
|
||||
|
||||
60
brewman/brewman/views/services/voucher/journal.py
Normal file
60
brewman/brewman/views/services/voucher/journal.py
Normal 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
|
||||
|
||||
|
||||
151
brewman/brewman/views/services/voucher/purchase.py
Normal file
151
brewman/brewman/views/services/voucher/purchase.py
Normal 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)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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}
|
||||
@ -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))
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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))
|
||||
|
||||
Reference in New Issue
Block a user