Feature: Stock reset built. It resets last batch for the closing stock value.
This commit is contained in:
@ -45,7 +45,7 @@
|
|||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input class="form-control" id="txtResetDate" type="text" datepicker-popup="dd-MMM-yyyy"
|
<input class="form-control" id="txtResetDate" type="text" datepicker-popup="dd-MMM-yyyy"
|
||||||
ng-model="resetDate"/>
|
ng-model="resetDate" placeholder="Reset date"/>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
|
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
|
||||||
</span>
|
</span>
|
||||||
@ -54,7 +54,7 @@
|
|||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input class="form-control" type="text" datepicker-popup="dd-MMM-yyyy" ng-model="stockDate"/>
|
<input class="form-control" type="text" datepicker-popup="dd-MMM-yyyy" ng-model="stockDate"/>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn" placeholder="Stock date">
|
||||||
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
|
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,79 +3,92 @@ from decimal import Decimal
|
|||||||
import uuid
|
import uuid
|
||||||
from pyramid.security import authenticated_userid
|
from pyramid.security import authenticated_userid
|
||||||
from pyramid.view import view_config
|
from pyramid.view import view_config
|
||||||
from sqlalchemy import func, and_
|
from sqlalchemy import func
|
||||||
from sqlalchemy.orm import aliased, joinedload
|
|
||||||
import transaction
|
import transaction
|
||||||
from brewman.models import DBSession
|
from brewman.models import DBSession
|
||||||
from brewman.models.master import LedgerBase, CostCenter, Product, Ledger
|
from brewman.models.master import LedgerBase, CostCenter, Product
|
||||||
from brewman.models.validation_exception import TryCatchFunction
|
from brewman.models.validation_exception import TryCatchFunction, ValidationError
|
||||||
from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory, SalaryDeduction, Fingerprint, Attendance
|
from brewman.models.voucher import Journal, Voucher, VoucherType, Batch, Inventory
|
||||||
|
|
||||||
__author__ = 'tanshu'
|
__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
|
@TryCatchFunction
|
||||||
def rebase(request):
|
def rebase(request):
|
||||||
|
user_id = uuid.UUID(authenticated_userid(request))
|
||||||
product = Product.by_id(uuid.UUID(request.matchdict['id']))
|
product = Product.by_id(uuid.UUID(request.matchdict['id']))
|
||||||
|
|
||||||
quantity = round(Decimal(request.GET['Quantity']), 2)
|
quantity = round(Decimal(request.GET['Quantity']), 2)
|
||||||
stock_date = datetime.datetime.strptime(request.GET['StockDate'], '%d-%b-%Y')
|
stock_date = datetime.datetime.strptime(request.GET['StockDate'], '%d-%b-%Y')
|
||||||
reset_date = datetime.datetime.strptime(request.GET['ResetDate'], '%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)
|
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()
|
transaction.commit()
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def build_report(product, start_date):
|
def get_closing_stock(product, finish_date=None):
|
||||||
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):
|
|
||||||
query = DBSession.query(func.sum(Inventory.quantity * Journal.debit)) \
|
query = DBSession.query(func.sum(Inventory.quantity * Journal.debit)) \
|
||||||
.join(Voucher) \
|
.join(Voucher) \
|
||||||
.filter(Voucher.id == Inventory.voucher_id) \
|
.filter(Voucher.id == Inventory.voucher_id) \
|
||||||
.filter(Voucher.id == Journal.voucher_id) \
|
.filter(Voucher.id == Journal.voucher_id) \
|
||||||
.filter(Inventory.product_id == product.id) \
|
.filter(Inventory.product_id == product.id) \
|
||||||
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \
|
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase())
|
||||||
.filter(Voucher.date <= finish_date) \
|
if finish_date is not None:
|
||||||
.one()
|
query = query.filter(Voucher.date <= finish_date)
|
||||||
|
query = query.one()
|
||||||
return 0 if query is None else query[0]
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user