Files
brewman/brewman/views/services/voucher/__init__.py

272 lines
14 KiB
Python

import uuid
from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.view import view_config
from sqlalchemy import func
import transaction
from brewman import groupfinder
from brewman.models import DBSession
from brewman.models.auth import User
from brewman.models.master import LedgerBase, CostCenter, DbSetting
from brewman.models.validation_exception import ValidationError, TryCatchFunction
from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory
from .issue import issue_create_voucher, issue_update_voucher
from .journal import journal_update_voucher, journal_create_voucher
from .purchase import purchase_create_voucher, purchase_update_voucher
__author__ = 'tanshu'
@view_config(request_method='GET', route_name='journal_id', renderer='brewman:templates/angular_base.mako',
permission='Journal')
@view_config(request_method='GET', route_name='journal', renderer='brewman:templates/angular_base.mako',
permission='Journal')
@view_config(request_method='GET', route_name='payment_id', renderer='brewman:templates/angular_base.mako',
permission='Payment')
@view_config(request_method='GET', route_name='payment', renderer='brewman:templates/angular_base.mako',
permission='Payment')
@view_config(request_method='GET', route_name='receipt_id', renderer='brewman:templates/angular_base.mako',
permission='Receipt')
@view_config(request_method='GET', route_name='receipt', renderer='brewman:templates/angular_base.mako',
permission='Receipt')
@view_config(request_method='GET', route_name='purchase_id', renderer='brewman:templates/angular_base.mako',
permission='Purchase')
@view_config(request_method='GET', route_name='purchase', renderer='brewman:templates/angular_base.mako',
permission='Purchase')
@view_config(request_method='GET', route_name='purchase_return_id', renderer='brewman:templates/angular_base.mako',
permission='Purchase Return')
@view_config(request_method='GET', route_name='purchase_return', renderer='brewman:templates/angular_base.mako',
permission='Purchase Return')
@view_config(request_method='GET', route_name='issue_id', renderer='brewman:templates/angular_base.mako',
permission='Issue')
@view_config(request_method='GET', route_name='issue', renderer='brewman:templates/angular_base.mako',
permission='Issue')
@view_config(request_method='GET', route_name='salary_deduction_id', renderer='brewman:templates/angular_base.mako',
permission='Issue')
@view_config(request_method='GET', route_name='salary_deduction', renderer='brewman:templates/angular_base.mako',
permission='Issue')
def journal_get(request):
return {}
@view_config(request_method='POST', route_name='api_voucher_id', request_param='post', renderer='json',
permission='Post Vouchers')
@TryCatchFunction
def voucher_post(request):
user = User.by_id(uuid.UUID(authenticated_userid(request)))
voucher = Voucher.by_id(uuid.UUID(request.matchdict['id']))
lock_date = get_lock_date()
if lock_date >= voucher.date:
raise ValidationError("Vouchers upto {0} have been locked.".format(lock_date.strftime('%d-%b-%Y')))
voucher.posted = True
voucher.poster_id = user.id
transaction.commit()
return voucher_info(Voucher.by_id(voucher.id))
def check_delete_permissions(request, voucher):
user = User.by_id(uuid.UUID(authenticated_userid(request)))
permissions = groupfinder(user.id, request)
if voucher.posted and not 'Edit Posted Vouchers' in permissions:
response = Response("You are not allowed to edit posted vouchers")
response.status_int = 403
return response
elif voucher.user_id != user.id and "Edit Other User's Vouchers" not in permissions:
response = Response("You are not allowed to edit other user's vouchers")
response.status_int = 403
return response
elif VoucherType.by_id(voucher.type).name not in permissions:
response = Response("You are not allowed (0) vouchers".format(VoucherType.by_id(voucher.type).name))
response.status_int = 403
return response
lock_date = get_lock_date()
if lock_date >= voucher.date:
response = Response("Vouchers upto {0} have been locked.".format(lock_date.strftime('%d-%b-%Y')))
response.status_int = 403
return response
@view_config(request_method='DELETE', route_name='api_voucher_id', renderer='json')
@TryCatchFunction
def delete(request):
voucher = Voucher.by_id(uuid.UUID(request.matchdict['id']))
permission = check_delete_permissions(request, voucher)
if permission is not None:
return permission
json_voucher = voucher_info(voucher)
batches_to_delete = []
if voucher.type == VoucherType.by_name('Issue').id:
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 == VoucherType.by_name('Purchase').id:
for item in voucher.inventories:
uses = DBSession.query(func.count(Inventory.id)) \
.filter(Inventory.batch_id == item.batch.id) \
.filter(Inventory.id != item.id).scalar()
if uses > 0:
raise ValueError('{0} has been issued and cannot be deleted'.format(item.product.name))
batches_to_delete.append(item.batch)
elif voucher.type == VoucherType.by_name('Purchase Return').id:
for item in voucher.inventories:
item.batch.quantity_remaining += item.quantity
for b in batches_to_delete:
DBSession.delete(b)
DBSession.delete(voucher)
transaction.commit()
return blank_voucher(info=json_voucher)
@view_config(request_method='GET', route_name='api_voucher_id', renderer='json')
@TryCatchFunction
def get_old(request):
id = request.matchdict.get('id', None)
return voucher_info(Voucher.by_id(uuid.UUID(id)))
def voucher_info(voucher):
json_voucher = {'VoucherID': voucher.id,
'Date': voucher.date.strftime('%d-%b-%Y'),
'Type': VoucherType.by_id(voucher.type).name,
'Posted': voucher.posted,
'Narration': voucher.narration,
'Journals': [],
'Inventories': [],
'SalaryDeductions': [],
'CreationDate': voucher.creation_date.strftime('%d-%b-%Y %H:%M'),
'LastEditDate': voucher.last_edit_date.strftime('%d-%b-%Y %H:%M'),
'User': {'UserID': voucher.user.id, 'Name': voucher.user.name},
'Poster': voucher.poster.name if voucher.posted else ''}
if voucher.reconcile_date is not None:
json_voucher['ReconcileDate'] = voucher.reconcile_date.strftime('%d-%b-%Y %H:%M')
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.salary_deductions:
json_voucher['SalaryDeductions'].append(
{'GrossSalary': item.gross_salary,
'DaysWorked': item.days_worked,
'EsiEmployee': item.esi_ee,
'PfEmployee': item.pf_ee,
'EsiEmployer': item.esi_er,
'PfEmployer': item.pf_er,
'Journal': {'JournalID': item.journal.id,
'Ledger': {'LedgerID': item.journal.ledger.id, 'Name': item.journal.ledger.name,
'Designation': item.journal.ledger.designation,
'CostCenter': {'CostCenterID': item.journal.ledger.costcenter.id,
'Name': item.journal.ledger.costcenter.name}}}})
for item in voucher.inventories:
text = "{0} ({1}) {2:.2f}@{3:.2f} from {4}".format(item.product.name, item.product.units,
item.batch.quantity_remaining, item.batch.rate, item.batch.name.strftime('%d-%b-%Y'))
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.full_name, 'Units': item.product.units,
'Price': item.rate},
'Batch': {'BatchID': item.batch.id, 'Name': text,
'QuantityRemaining': item.batch.quantity_remaining, 'Tax': item.batch.tax,
'Discount': item.batch.discount, 'Rate': item.batch.rate,
'Product': {'ProductID': item.batch.product.id, 'Name': item.batch.product.full_name}}})
return json_voucher
def blank_voucher(info):
if 'Type' not in info:
raise ValidationError('Voucher Type is null')
type = info['Type']
if 'Date' not in info:
raise ValidationError('Date cannot be null')
json_voucher = {'Type': type, 'Date': info['Date'], 'Posted': False, 'Narration': "", 'Journals': [], 'Inventories': []}
if type == 'Journal':
pass
elif type == 'Payment':
ledger = None
if info is not None and 'Account' in info and info['Account'] is not None:
ledger = LedgerBase.by_id(info['Account'])
if ledger is not None:
ledger = {'LedgerID': ledger.id, 'Name':ledger.name}
else:
ledger = LedgerBase.cash_in_hand()
json_voucher['Journals'].append({'Ledger': ledger, 'Amount': 0, 'Debit': -1})
elif type == 'Receipt':
ledger = None
if info is not None and 'Account' in info and info['Account'] is not None:
ledger = LedgerBase.by_id(info['Account'])
if ledger is not None:
ledger = {'LedgerID': ledger.id, 'Name':ledger.name}
else:
ledger = LedgerBase.cash_in_hand()
json_voucher['Journals'].append({'Ledger': ledger, 'Amount': 0, 'Debit': 1})
elif type == 'Purchase':
json_voucher['Journals'].append({'Ledger': LedgerBase.local_purchase(), 'Amount': 0, 'Debit': -1})
elif type == 'Purchase Return':
json_voucher['Journals'].append({'Ledger': LedgerBase.local_purchase(), 'Amount': 0, 'Debit': 1})
elif type == 'Issue':
if 'Source' in info and 'Destination' in info:
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
'Amount': 0,
'Debit': -1,
'CostCenter': {'CostCenterID': info['Source']}})
json_voucher['Journals'].append({'Ledger': {'LedgerID': LedgerBase.all_purchases()},
'Amount': 0,
'Debit': 1,
'CostCenter': {'CostCenterID': info['Destination']}})
elif 'Journals' not in info:
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'] = info['Date']
for item in info['Journals']:
json_voucher['Journals'].append({'Ledger': {'LedgerID': item['Ledger']['LedgerID']},
'Amount': 0,
'Debit': item['Debit'],
'CostCenter': {'CostCenterID': item['CostCenter']['CostCenterID']}})
elif type == 'Salary Deduction':
json_voucher['SalaryDeductions'] = []
else:
raise ValidationError("Voucher of type \"{0}\" does not exist.".format(type))
return json_voucher
def get_edit_url(request, voucher):
if voucher.type == 1:
return request.route_url('journal_id', id=voucher.id)
elif voucher.type == 2:
return request.route_url('purchase_id', id=voucher.id)
elif voucher.type == 3:
return request.route_url('issue_id', id=voucher.id)
elif voucher.type == 4:
return request.route_url('payment_id', id=voucher.id)
elif voucher.type == 5:
return request.route_url('receipt_id', id=voucher.id)
elif voucher.type == 6:
return request.route_url('purchase_return_id', id=voucher.id)
elif voucher.type == 12:
return request.route_url('salary_deduction_id', id=voucher.id)
else:
return '#'