[cleanup] [minor] deprecated budget control and rewritten budget related code
This commit is contained in:
parent
4212180804
commit
2b06aaa291
@ -1 +0,0 @@
|
|||||||
Backend scripts for Budget Management.
|
|
@ -1 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
@ -1,97 +0,0 @@
|
|||||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import webnotes
|
|
||||||
from webnotes.utils import cstr, flt, getdate
|
|
||||||
from webnotes import msgprint
|
|
||||||
|
|
||||||
class DocType:
|
|
||||||
def __init__(self,d,dl):
|
|
||||||
self.doc, self.doclist = d, dl
|
|
||||||
|
|
||||||
# Get monthly budget
|
|
||||||
#-------------------
|
|
||||||
def get_monthly_budget(self, distribution_id, cfy, st_date, post_dt, budget_allocated):
|
|
||||||
|
|
||||||
# get month_list
|
|
||||||
st_date, post_dt = getdate(st_date), getdate(post_dt)
|
|
||||||
|
|
||||||
if distribution_id:
|
|
||||||
if st_date.month <= post_dt.month:
|
|
||||||
tot_per_allocated = webnotes.conn.sql("select ifnull(sum(percentage_allocation),0) from `tabBudget Distribution Detail` where parent='%s' and idx between '%s' and '%s'" % (distribution_id, st_date.month, post_dt.month))[0][0]
|
|
||||||
|
|
||||||
if st_date.month > post_dt.month:
|
|
||||||
|
|
||||||
tot_per_allocated = flt(webnotes.conn.sql("select ifnull(sum(percentage_allocation),0) from `tabBudget Distribution Detail` where parent='%s' and idx between '%s' and '%s'" % (distribution_id, st_date.month, 12 ))[0][0])
|
|
||||||
tot_per_allocated = flt(tot_per_allocated) + flt(webnotes.conn.sql("select ifnull(sum(percentage_allocation),0) from `tabBudget Distribution Detail` where parent='%s' and idx between '%s' and '%s'" % (distribution_id, 1, post_dt.month))[0][0])
|
|
||||||
|
|
||||||
return (flt(budget_allocated) * flt(tot_per_allocated)) / 100
|
|
||||||
period_diff = webnotes.conn.sql("select PERIOD_DIFF('%s','%s')" % (post_dt.strftime('%Y%m'), st_date.strftime('%Y%m')))
|
|
||||||
|
|
||||||
return (flt(budget_allocated) * (flt(period_diff[0][0]) + 1)) / 12
|
|
||||||
|
|
||||||
def validate_budget(self, acct, cost_center, actual, budget, action):
|
|
||||||
# action if actual exceeds budget
|
|
||||||
if flt(actual) > flt(budget):
|
|
||||||
msgprint("Your monthly expense "+ cstr((action == 'stop') and "will exceed" or "has exceeded") +" budget for <b>Account - "+cstr(acct)+" </b> under <b>Cost Center - "+ cstr(cost_center) + "</b>"+cstr((action == 'Stop') and ", you can not have this transaction." or "."))
|
|
||||||
if action == 'Stop': raise Exception
|
|
||||||
|
|
||||||
def check_budget(self,gle,cancel):
|
|
||||||
# get allocated budget
|
|
||||||
|
|
||||||
bgt = webnotes.conn.sql("""select t1.budget_allocated, t1.actual, t2.distribution_id
|
|
||||||
from `tabBudget Detail` t1, `tabCost Center` t2
|
|
||||||
where t1.account='%s' and t1.parent=t2.name and t2.name = '%s'
|
|
||||||
and t1.fiscal_year='%s'""" %
|
|
||||||
(gle['account'], gle['cost_center'], gle['fiscal_year']), as_dict =1)
|
|
||||||
|
|
||||||
curr_amt = flt(gle['debit']) - flt(gle['credit'])
|
|
||||||
if cancel: curr_amt = -1 * curr_amt
|
|
||||||
|
|
||||||
if bgt and bgt[0]['budget_allocated']:
|
|
||||||
# check budget flag in Company
|
|
||||||
bgt_flag = webnotes.conn.sql("""select yearly_bgt_flag, monthly_bgt_flag
|
|
||||||
from `tabCompany` where name = '%s'""" % gle['company'], as_dict =1)
|
|
||||||
|
|
||||||
if bgt_flag and bgt_flag[0]['monthly_bgt_flag'] in ['Stop', 'Warn']:
|
|
||||||
# get start date and last date
|
|
||||||
start_date = webnotes.conn.get_value('Fiscal Year', gle['fiscal_year'], \
|
|
||||||
'year_start_date').strftime('%Y-%m-%d')
|
|
||||||
end_date = webnotes.conn.sql("select LAST_DAY('%s')" % gle['posting_date'])
|
|
||||||
|
|
||||||
# get Actual
|
|
||||||
actual = self.get_period_difference(gle['account'] +
|
|
||||||
'~~~' + cstr(start_date) + '~~~' + cstr(end_date[0][0]), gle['cost_center'])
|
|
||||||
|
|
||||||
# Get Monthly budget
|
|
||||||
budget = self.get_monthly_budget(bgt and bgt[0]['distribution_id'] or '' , \
|
|
||||||
gle['fiscal_year'], start_date, gle['posting_date'], bgt[0]['budget_allocated'])
|
|
||||||
|
|
||||||
# validate monthly budget
|
|
||||||
self.validate_budget(gle['account'], gle['cost_center'], \
|
|
||||||
flt(actual) + flt(curr_amt), budget, bgt_flag[0]['monthly_bgt_flag'])
|
|
||||||
|
|
||||||
# update actual against budget allocated in cost center
|
|
||||||
webnotes.conn.sql("""update `tabBudget Detail` set actual = ifnull(actual,0) + %s
|
|
||||||
where account = '%s' and fiscal_year = '%s' and parent = '%s'""" %
|
|
||||||
(curr_amt, gle['account'],gle['fiscal_year'], gle['cost_center']))
|
|
||||||
|
|
||||||
|
|
||||||
def get_period_difference(self, arg, cost_center =''):
|
|
||||||
# used in General Ledger Page Report
|
|
||||||
# used for Budget where cost center passed as extra argument
|
|
||||||
acc, f, t = arg.split('~~~')
|
|
||||||
c, fy = '', webnotes.conn.get_defaults()['fiscal_year']
|
|
||||||
|
|
||||||
det = webnotes.conn.sql("select debit_or_credit, lft, rgt, is_pl_account from tabAccount where name=%s", acc)
|
|
||||||
if f: c += (' and t1.posting_date >= "%s"' % f)
|
|
||||||
if t: c += (' and t1.posting_date <= "%s"' % t)
|
|
||||||
if cost_center: c += (' and t1.cost_center = "%s"' % cost_center)
|
|
||||||
bal = webnotes.conn.sql("select sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) from `tabGL Entry` t1 where t1.account='%s' %s" % (acc, c))
|
|
||||||
bal = bal and flt(bal[0][0]) or 0
|
|
||||||
|
|
||||||
if det[0][0] != 'Debit':
|
|
||||||
bal = (-1) * bal
|
|
||||||
|
|
||||||
return flt(bal)
|
|
@ -1,19 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"creation": "2012-03-27 14:35:41",
|
|
||||||
"docstatus": 0,
|
|
||||||
"modified": "2013-07-10 14:54:06",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"owner": "nabin@webnotestech.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "DocType",
|
|
||||||
"issingle": 1,
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "__common__"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "DocType",
|
|
||||||
"name": "Budget Control"
|
|
||||||
}
|
|
||||||
]
|
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-03-07 11:55:04",
|
"creation": "2013-03-07 11:55:04",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-07-10 14:54:06",
|
"modified": "2013-08-22 17:27:59",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -20,7 +20,8 @@
|
|||||||
"parent": "Budget Detail",
|
"parent": "Budget Detail",
|
||||||
"parentfield": "fields",
|
"parentfield": "fields",
|
||||||
"parenttype": "DocType",
|
"parenttype": "DocType",
|
||||||
"permlevel": 0
|
"permlevel": 0,
|
||||||
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -35,7 +36,6 @@
|
|||||||
"oldfieldname": "account",
|
"oldfieldname": "account",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -45,18 +45,7 @@
|
|||||||
"label": "Budget Allocated",
|
"label": "Budget Allocated",
|
||||||
"oldfieldname": "budget_allocated",
|
"oldfieldname": "budget_allocated",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency"
|
||||||
"reqd": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "actual",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Actual",
|
|
||||||
"oldfieldname": "actual",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@ -67,7 +56,6 @@
|
|||||||
"oldfieldname": "fiscal_year",
|
"oldfieldname": "fiscal_year",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "link:Fiscal Year",
|
"options": "link:Fiscal Year",
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -1,4 +1,70 @@
|
|||||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
test_records = []
|
test_records = [
|
||||||
|
[{
|
||||||
|
"doctype": "Budget Distribution",
|
||||||
|
"distribution_id": "_Test Distribution",
|
||||||
|
"fiscal_year": "_Test Fiscal Year 2013",
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "April",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "May",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "June",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "July",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "August",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "September",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "October",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "November",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "December",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "January",
|
||||||
|
"percentage_allocation": "8"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "February",
|
||||||
|
"percentage_allocation": "10"
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Distribution Detail",
|
||||||
|
"parentfield": "budget_distribution_details",
|
||||||
|
"month": "March",
|
||||||
|
"percentage_allocation": "10"
|
||||||
|
}]
|
||||||
|
]
|
@ -7,6 +7,13 @@ test_records = [
|
|||||||
"cost_center_name": "_Test Cost Center",
|
"cost_center_name": "_Test Cost Center",
|
||||||
"parent_cost_center": "_Test Company - _TC",
|
"parent_cost_center": "_Test Company - _TC",
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
"group_or_ledger": "Ledger"
|
"group_or_ledger": "Ledger",
|
||||||
|
"distribution_id": "_Test Distribution",
|
||||||
|
}, {
|
||||||
|
"doctype": "Budget Detail",
|
||||||
|
"parentfield": "budget_details",
|
||||||
|
"account": "_Test Account Cost for Goods Sold - _TC",
|
||||||
|
"budget_allocated": 100000,
|
||||||
|
"fiscal_year": "_Test Fiscal Year 2013"
|
||||||
}],
|
}],
|
||||||
]
|
]
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-01-10 16:34:06",
|
"creation": "2013-01-10 16:34:06",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-07-05 14:39:07",
|
"modified": "2013-08-22 17:12:13",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -171,17 +171,6 @@
|
|||||||
"oldfieldtype": "Text",
|
"oldfieldtype": "Text",
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "is_cancelled",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"in_filter": 1,
|
|
||||||
"label": "Is Cancelled",
|
|
||||||
"oldfieldname": "is_cancelled",
|
|
||||||
"oldfieldtype": "Select",
|
|
||||||
"options": "No\nYes",
|
|
||||||
"search_index": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "is_opening",
|
"fieldname": "is_opening",
|
||||||
|
@ -32,6 +32,21 @@ class TestJournalVoucher(unittest.TestCase):
|
|||||||
self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
|
self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
|
||||||
where against_jv=%s""", jv_invoice.doc.name))
|
where against_jv=%s""", jv_invoice.doc.name))
|
||||||
|
|
||||||
|
def test_budget(self):
|
||||||
|
from accounts.utils import BudgetError
|
||||||
|
webnotes.conn.set_value("Company", "_Test Company", "monthly_bgt_flag", "Stop")
|
||||||
|
|
||||||
|
jv1 = webnotes.bean(copy=test_records[0])
|
||||||
|
jv1.doc.posting_date = "2013-02-12"
|
||||||
|
jv1.doclist[2].account = "_Test Account Cost for Goods Sold - _TC"
|
||||||
|
jv1.doclist[2].cost_center = "_Test Cost Center - _TC"
|
||||||
|
jv1.doclist[2].debit = 20000.0
|
||||||
|
jv1.doclist[1].credit = 20000.0
|
||||||
|
jv1.insert()
|
||||||
|
|
||||||
|
self.assertRaises(BudgetError, jv1.submit)
|
||||||
|
|
||||||
|
|
||||||
test_records = [
|
test_records = [
|
||||||
[{
|
[{
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import webnotes
|
import webnotes
|
||||||
from webnotes.utils import flt, cstr, now
|
from webnotes.utils import flt, cstr, now
|
||||||
from webnotes.model.doc import Document
|
from webnotes.model.doc import Document
|
||||||
|
from accounts.utils import validate_expense_against_budget
|
||||||
|
|
||||||
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
|
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
|
||||||
update_outstanding='Yes'):
|
update_outstanding='Yes'):
|
||||||
@ -12,7 +13,6 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
|
|||||||
if merge_entries:
|
if merge_entries:
|
||||||
gl_map = merge_similar_entries(gl_map)
|
gl_map = merge_similar_entries(gl_map)
|
||||||
|
|
||||||
check_budget(gl_map, cancel)
|
|
||||||
save_entries(gl_map, adv_adj, update_outstanding)
|
save_entries(gl_map, adv_adj, update_outstanding)
|
||||||
else:
|
else:
|
||||||
delete_gl_entries(gl_map, adv_adj, update_outstanding)
|
delete_gl_entries(gl_map, adv_adj, update_outstanding)
|
||||||
@ -54,20 +54,21 @@ def check_budget(gl_map, cancel):
|
|||||||
|
|
||||||
def save_entries(gl_map, adv_adj, update_outstanding):
|
def save_entries(gl_map, adv_adj, update_outstanding):
|
||||||
total_debit = total_credit = 0.0
|
total_debit = total_credit = 0.0
|
||||||
def _swap(gle):
|
def _swap(entry):
|
||||||
gle.debit, gle.credit = abs(flt(gle.credit)), abs(flt(gle.debit))
|
entry["debit"], entry["credit"] = abs(flt(entry["credit"])), abs(flt(entry["debit"]))
|
||||||
|
|
||||||
for entry in gl_map:
|
for entry in gl_map:
|
||||||
gle = Document('GL Entry', fielddata=entry)
|
|
||||||
|
|
||||||
# round off upto 2 decimal
|
# round off upto 2 decimal
|
||||||
gle.debit = flt(gle.debit, 2)
|
entry["debit"] = flt(entry["debit"], 2)
|
||||||
gle.credit = flt(gle.credit, 2)
|
entry["credit"] = flt(entry["credit"], 2)
|
||||||
|
|
||||||
# toggle debit, credit if negative entry
|
# toggle debit, credit if negative entry
|
||||||
if flt(gle.debit) < 0 or flt(gle.credit) < 0:
|
if flt(entry["debit"]) < 0 or flt(entry["credit"]) < 0:
|
||||||
_swap(gle)
|
_swap(entry)
|
||||||
|
|
||||||
|
validate_expense_against_budget(entry)
|
||||||
|
|
||||||
|
gle = Document('GL Entry', fielddata=entry)
|
||||||
gle_obj = webnotes.get_obj(doc=gle)
|
gle_obj = webnotes.get_obj(doc=gle)
|
||||||
gle_obj.validate()
|
gle_obj.validate()
|
||||||
gle.save(1)
|
gle.save(1)
|
||||||
@ -96,10 +97,9 @@ def delete_gl_entries(gl_entries, adv_adj, update_outstanding):
|
|||||||
for entry in gl_entries:
|
for entry in gl_entries:
|
||||||
validate_freezed_account(entry["account"], adv_adj)
|
validate_freezed_account(entry["account"], adv_adj)
|
||||||
check_negative_balance(entry["account"], adv_adj)
|
check_negative_balance(entry["account"], adv_adj)
|
||||||
|
validate_expense_against_budget(entry)
|
||||||
|
|
||||||
if entry.get("against_voucher") and entry.get("against_voucher_type") != "POS" \
|
if entry.get("against_voucher") and entry.get("against_voucher_type") != "POS" \
|
||||||
and update_outstanding == 'Yes':
|
and update_outstanding == 'Yes':
|
||||||
update_outstanding_amt(entry["account"], entry.get("against_voucher_type"),
|
update_outstanding_amt(entry["account"], entry.get("against_voucher_type"),
|
||||||
entry.get("against_voucher"))
|
entry.get("against_voucher"))
|
||||||
|
|
||||||
# To-do
|
|
||||||
# Check and update budget for expense account
|
|
@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes.utils import nowdate, nowtime, cstr, flt, now
|
from webnotes.utils import nowdate, nowtime, cstr, flt, now, getdate, add_months
|
||||||
from webnotes.model.doc import addchild
|
from webnotes.model.doc import addchild
|
||||||
from webnotes import msgprint, _
|
from webnotes import msgprint, _
|
||||||
from webnotes.utils import formatdate
|
from webnotes.utils import formatdate
|
||||||
@ -12,6 +12,8 @@ from utilities import build_filter_conditions
|
|||||||
|
|
||||||
|
|
||||||
class FiscalYearError(webnotes.ValidationError): pass
|
class FiscalYearError(webnotes.ValidationError): pass
|
||||||
|
class BudgetError(webnotes.ValidationError): pass
|
||||||
|
|
||||||
|
|
||||||
def get_fiscal_year(date=None, fiscal_year=None, label="Date", verbose=1):
|
def get_fiscal_year(date=None, fiscal_year=None, label="Date", verbose=1):
|
||||||
return get_fiscal_years(date, fiscal_year, label, verbose=1)[0]
|
return get_fiscal_years(date, fiscal_year, label, verbose=1)[0]
|
||||||
@ -373,7 +375,6 @@ def get_stock_and_account_difference(warehouse_list=None):
|
|||||||
|
|
||||||
return difference
|
return difference
|
||||||
|
|
||||||
|
|
||||||
def validate_expense_against_budget(args):
|
def validate_expense_against_budget(args):
|
||||||
args = webnotes._dict(args)
|
args = webnotes._dict(args)
|
||||||
if webnotes.conn.get_value("Account", {"name": args.account, "is_pl_account": "Yes",
|
if webnotes.conn.get_value("Account", {"name": args.account, "is_pl_account": "Yes",
|
||||||
@ -385,18 +386,60 @@ def validate_expense_against_budget(args):
|
|||||||
""", (args.cost_center, args.account, args.fiscal_year), as_dict=True)
|
""", (args.cost_center, args.account, args.fiscal_year), as_dict=True)
|
||||||
|
|
||||||
if budget and budget[0].budget_allocated:
|
if budget and budget[0].budget_allocated:
|
||||||
action = webnotes.conn.get_value("Company", args.company,
|
yearly_action, monthly_action = webnotes.conn.get_value("Company", args.company,
|
||||||
["yearly_bgt_flag", "monthly_bgt_flag"])
|
["yearly_bgt_flag", "monthly_bgt_flag"])
|
||||||
|
action_for = action = ""
|
||||||
|
|
||||||
args["month_end_date"] = webnotes.conn.sql("select LAST_DAY(%s)", args.posting_date)
|
if monthly_action in ["Stop", "Warn"]:
|
||||||
|
budget_amount = get_allocated_budget(budget[0].distribution_id,
|
||||||
|
args.posting_date, args.fiscal_year, budget[0].budget_allocated)
|
||||||
|
|
||||||
expense_upto_date = get_actual_expense(args)
|
month_end_date = webnotes.conn.sql("select LAST_DAY(%s)", args.posting_date)
|
||||||
|
args["condition"] = " and posting_date<='%s'" % month_end_date
|
||||||
|
action_for, action = "Monthly", monthly_action
|
||||||
|
|
||||||
|
elif yearly_action in ["Stop", "Warn"]:
|
||||||
|
budget_amount = budget[0].budget_allocated
|
||||||
|
action_for, action = "Monthly", yearly_action
|
||||||
|
print budget_amount
|
||||||
|
if action_for:
|
||||||
|
actual_expense = get_actual_expense(args)
|
||||||
|
print actual_expense
|
||||||
|
if actual_expense > budget_amount:
|
||||||
|
webnotes.msgprint(action_for + _(" budget ") + cstr(budget_amount) +
|
||||||
|
_(" for account ") + args.account + _(" against cost center ") +
|
||||||
|
args.cost_center + _(" will exceed by ") +
|
||||||
|
cstr(actual_expense - budget_amount) + _(" after this transaction.")
|
||||||
|
, raise_exception=BudgetError if action=="Stop" else False)
|
||||||
|
|
||||||
|
def get_allocated_budget(distribution_id, posting_date, fiscal_year, yearly_budget):
|
||||||
|
if distribution_id:
|
||||||
|
distribution = {}
|
||||||
|
for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation
|
||||||
|
from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd
|
||||||
|
where bdd.parent=bd.name and bd.fiscal_year=%s""", fiscal_year, as_dict=1):
|
||||||
|
distribution.setdefault(d.month, d.percentage_allocation)
|
||||||
|
print distribution
|
||||||
|
dt = webnotes.conn.get_value("Fiscal Year", fiscal_year, "year_start_date")
|
||||||
|
budget_percentage = 0.0
|
||||||
|
|
||||||
|
while(dt <= getdate(posting_date)):
|
||||||
|
print dt, posting_date
|
||||||
|
if distribution_id:
|
||||||
|
print getdate(dt).month
|
||||||
|
print distribution.get(getdate(dt).month)
|
||||||
|
budget_percentage += distribution.get(getdate(dt).month, 0)
|
||||||
|
else:
|
||||||
|
budget_percentage += 100.0/12
|
||||||
|
|
||||||
|
dt = add_months(dt, 1)
|
||||||
|
|
||||||
|
return yearly_budget * budget_percentage / 100
|
||||||
|
|
||||||
def get_actual_expense(args):
|
def get_actual_expense(args):
|
||||||
return webnotes.conn.sql("""
|
return webnotes.conn.sql("""
|
||||||
select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
|
select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where account=%(account)s and cost_center=%(cost_center)s
|
where account=%(account)s and cost_center=%(cost_center)s
|
||||||
and posting_date<=%(month_end_date)s
|
and fiscal_year=%(fiscal_year)s and company=%(company)s %(condition)s
|
||||||
and fiscal_year=%(fiscal_year)s and company=%(company)s
|
|
||||||
""", (args))[0][0]
|
""", (args))[0][0]
|
@ -6,3 +6,6 @@ def execute():
|
|||||||
|
|
||||||
webnotes.conn.sql("""delete from `tabStock Ledger Entry`
|
webnotes.conn.sql("""delete from `tabStock Ledger Entry`
|
||||||
where ifnull(is_cancelled, 'No') = 'Yes'""")
|
where ifnull(is_cancelled, 'No') = 'Yes'""")
|
||||||
|
|
||||||
|
webnotes.reload_doc("stock", "doctype", "gl_entry")
|
||||||
|
webnotes.conn.sql("""delete from `tabGL Entry` where ifnull(is_cancelled, 'No') = 'Yes'""")
|
@ -260,4 +260,6 @@ patch_list = [
|
|||||||
"patches.august_2013.p06_deprecate_cancelled_sl_entry",
|
"patches.august_2013.p06_deprecate_cancelled_sl_entry",
|
||||||
"patches.august_2013.p06_fix_sle_against_stock_entry",
|
"patches.august_2013.p06_fix_sle_against_stock_entry",
|
||||||
"execute:webnotes.bean('Style Settings').save() #2013-08-20",
|
"execute:webnotes.bean('Style Settings').save() #2013-08-20",
|
||||||
|
"patches.august_2013.p06_deprecate_is_cancelled",
|
||||||
|
"execute:webnotes.delete_doc('DocType', 'Budget Control')",
|
||||||
]
|
]
|
Loading…
x
Reference in New Issue
Block a user