diff --git a/brewman/brewman/static/partial/settings.html b/brewman/brewman/static/partial/settings.html index acab59b4..42573731 100644 --- a/brewman/brewman/static/partial/settings.html +++ b/brewman/brewman/static/partial/settings.html @@ -45,7 +45,7 @@
+ ng-model="resetDate" placeholder="Reset date"/> @@ -54,7 +54,7 @@
- +
diff --git a/brewman/brewman/views/Management/stock.py b/brewman/brewman/views/Management/stock.py index c5c342af..27475e7e 100644 --- a/brewman/brewman/views/Management/stock.py +++ b/brewman/brewman/views/Management/stock.py @@ -3,79 +3,92 @@ from decimal import Decimal import uuid from pyramid.security import authenticated_userid from pyramid.view import view_config -from sqlalchemy import func, and_ -from sqlalchemy.orm import aliased, joinedload +from sqlalchemy import func import transaction from brewman.models import DBSession -from brewman.models.master import LedgerBase, CostCenter, Product, Ledger -from brewman.models.validation_exception import TryCatchFunction -from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory, SalaryDeduction, Fingerprint, Attendance +from brewman.models.master import LedgerBase, CostCenter, Product +from brewman.models.validation_exception import TryCatchFunction, ValidationError +from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory __author__ = 'tanshu' -@view_config(request_method='POST', route_name='api_reset_stock', renderer='json', permission='Authenticated') -#@view_config(request_method='POST', route_name='api_reset_stock', renderer='json', permission='Reset Stock') +@view_config(request_method='POST', route_name='api_reset_stock', renderer='json', permission='Reset Stock') @TryCatchFunction def rebase(request): + user_id = uuid.UUID(authenticated_userid(request)) product = Product.by_id(uuid.UUID(request.matchdict['id'])) quantity = round(Decimal(request.GET['Quantity']), 2) stock_date = datetime.datetime.strptime(request.GET['StockDate'], '%d-%b-%Y') reset_date = datetime.datetime.strptime(request.GET['ResetDate'], '%d-%b-%Y') + if reset_date > stock_date: + raise ValidationError('Reset cannot be after the stock date') + change = quantity - get_closing_stock(product, stock_date) - report = build_report(product, reset_date) + if change == 0: + return {'No Change Needed'} + final = get_closing_stock(product) + if final + change < 0: + raise ValidationError('Current Quantity will get negative. Cannot proceed') + + batch = get_last_batch(product) + set_batches(batch, final + change) + + create_voucher(batch, change, reset_date, user_id) transaction.commit() return {} -def build_report(product, start_date): - query = DBSession.query(Voucher, Batch, Journal).options( - joinedload(Voucher.journals, innerjoin=True), - joinedload(Voucher.inventories, innerjoin=True), - joinedload(Inventory.batch, innerjoin=True)) \ - .filter(Voucher.id == Inventory.voucher_id) \ - .filter(Voucher.id == Journal.voucher_id) \ - .filter(Inventory.product_id == product.id) \ - .filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ - .filter(Voucher.date >= start_date).order_by(Voucher.date.desc()).all() - - for voucher, inventory, batch, journal in query: - pass - #journalDebit = journal.debit * -1 - #name = journal.costcenter.name if voucher.type == VoucherType.by_name( - # 'Issue').id else journal.ledger.name - #debitQ = "{0:.2f}".format(inventory.quantity) if journalDebit == 1 else "" - #debitA = "\u20B9 {0:.2f}".format(inventory.amount) if journalDebit == 1 else "" - #creditQ = "{0:.2f}".format(inventory.quantity) if journalDebit != 1 else "" - #creditA = "\u20B9 {0:.2f}".format(inventory.amount) if journalDebit != 1 else "" - # - #runningTotalQ += (inventory.quantity * journalDebit) - #runningTotalA += (inventory.amount * journalDebit) - # - #if journalDebit == 1: - # totalDebitQ += inventory.quantity - # totalDebitA += inventory.amount - #else: - # totalCreditQ += inventory.quantity - # totalCreditA += inventory.amount - # - #info['Body'].append( - # {'Date': row.Voucher.date.strftime('%d-%b-%Y'), 'Name': name, 'Url': get_edit_url(request, row.Voucher), - # 'Type': VoucherType.by_id(row.Voucher.type).name, 'Narration': row.Voucher.narration, 'DebitQ': debitQ, - # 'DebitA': debitA, - # 'CreditQ': creditQ, 'CreditA': creditA, 'RunningQ': "{0:.2f}".format(runningTotalQ), - # 'RunningA': "\u20B9 {0:.2f}".format(runningTotalA)}) - - -def get_closing_stock(product, finish_date): +def get_closing_stock(product, finish_date=None): query = DBSession.query(func.sum(Inventory.quantity * Journal.debit)) \ .join(Voucher) \ .filter(Voucher.id == Inventory.voucher_id) \ .filter(Voucher.id == Journal.voucher_id) \ .filter(Inventory.product_id == product.id) \ - .filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \ - .filter(Voucher.date <= finish_date) \ - .one() + .filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) + if finish_date is not None: + query = query.filter(Voucher.date <= finish_date) + query = query.one() return 0 if query is None else query[0] + + +def get_last_batch(product): + batch = DBSession.query(Batch).filter(Batch.product_id == product.id).order_by(Batch.name.desc()).first() + if batch is None: + raise ValidationError('Details for the product exist. Just add a purchase entry') + return batch + + +def set_batches(batch, quantity): + batch.quantity_remaining = quantity + batches = DBSession.query(Batch).filter(Batch.id != batch.id).filter(Batch.product_id == batch.product_id) + for item in batches: + item.quantity_remaining = 0 + pass + + +def create_voucher(batch, quantity, date, user_id): + voucher = Voucher(date=date, narration='Product Reset', user_id=user_id, type=VoucherType.by_name('Issue')) + DBSession.add(voucher) + + if quantity > 0: + source = CostCenter.cost_center_overall() + destination = CostCenter.cost_center_purchase() + else: + destination = CostCenter.cost_center_overall() + source = CostCenter.cost_center_purchase() + + inventory = Inventory(product_id=batch.product.id, quantity=abs(quantity), rate=batch.rate, tax=batch.tax, + discount=batch.discount, batch=batch) + voucher.inventories.append(inventory) + DBSession.add(inventory) + + amount = round(inventory.amount, 2) + source = Journal(debit=-1, ledger_id=LedgerBase.all_purchases(), amount=amount, cost_center_id=source) + voucher.journals.append(source) + DBSession.add(source) + destination = Journal(debit=1, ledger_id=LedgerBase.all_purchases(), amount=amount, cost_center_id=destination) + voucher.journals.append(destination) + DBSession.add(destination)