2015-03-03 09:25:30 +00:00
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
2013-08-05 09:29:54 +00:00
# License: GNU General Public License v3. See license.txt
2013-01-29 06:02:38 +00:00
from __future__ import unicode_literals
2014-02-14 10:17:51 +00:00
import frappe
from frappe . utils import nowdate , cstr , flt , now , getdate , add_months
2014-04-14 13:50:45 +00:00
from frappe import throw , _
2014-02-14 10:17:51 +00:00
from frappe . utils import formatdate
2014-09-09 10:45:35 +00:00
import frappe . desk . reportview
2013-01-29 06:02:38 +00:00
2015-09-28 08:01:17 +00:00
# imported to enable erpnext.accounts.utils.get_account_currency
from erpnext . accounts . doctype . account . account import get_account_currency
2014-02-14 10:17:51 +00:00
class FiscalYearError ( frappe . ValidationError ) : pass
class BudgetError ( frappe . ValidationError ) : pass
2013-08-22 12:55:43 +00:00
2014-10-03 12:13:02 +00:00
@frappe.whitelist ( )
def get_fiscal_year ( date = None , fiscal_year = None , label = " Date " , verbose = 1 , company = None ) :
return get_fiscal_years ( date , fiscal_year , label , verbose , company ) [ 0 ]
2013-01-29 06:02:38 +00:00
2015-01-12 11:11:46 +00:00
def get_fiscal_years ( transaction_date = None , fiscal_year = None , label = " Date " , verbose = 1 , company = None ) :
2013-01-29 06:02:38 +00:00
# if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate)
2015-05-20 06:56:07 +00:00
cond = " ifnull(disabled, 0) = 0 "
2013-06-20 11:05:09 +00:00
if fiscal_year :
2015-05-20 07:23:04 +00:00
cond + = " and fy.name = %(fiscal_year)s "
2013-06-20 11:05:09 +00:00
else :
2015-05-20 07:23:04 +00:00
cond + = " and %(transaction_date)s >= fy.year_start_date and %(transaction_date)s <= fy.year_end_date "
2015-01-14 10:57:13 +00:00
2015-01-12 11:11:46 +00:00
if company :
cond + = """ and (not exists(select name from `tabFiscal Year Company` fyc where fyc.parent = fy.name)
or exists ( select company from ` tabFiscal Year Company ` fyc where fyc . parent = fy . name and fyc . company = % ( company ) s ) ) """
2015-01-14 10:57:13 +00:00
fy = frappe . db . sql ( """ select fy.name, fy.year_start_date, fy.year_end_date from `tabFiscal Year` fy
2015-05-20 06:56:07 +00:00
where % s order by fy . year_start_date desc """ % c ond, {
2015-01-12 11:11:46 +00:00
" fiscal_year " : fiscal_year ,
" transaction_date " : transaction_date ,
" company " : company
} )
2014-04-08 08:23:35 +00:00
2013-01-29 06:02:38 +00:00
if not fy :
2015-05-19 13:13:45 +00:00
error_msg = _ ( """ {0} {1} not in any active Fiscal Year. For more details check {2} . """ ) . format ( label , formatdate ( transaction_date ) , " https://erpnext.com/kb/accounts/fiscal-year-error " )
2014-10-03 12:13:02 +00:00
if verbose == 1 : frappe . msgprint ( error_msg )
2013-01-29 06:02:38 +00:00
raise FiscalYearError , error_msg
2013-02-05 17:55:37 +00:00
return fy
2014-04-08 08:23:35 +00:00
2015-02-19 09:21:58 +00:00
def validate_fiscal_year ( date , fiscal_year , label = _ ( " Date " ) , doc = None ) :
2013-07-11 12:19:18 +00:00
years = [ f [ 0 ] for f in get_fiscal_years ( date , label = label ) ]
2013-02-05 17:55:37 +00:00
if fiscal_year not in years :
2015-02-19 09:21:58 +00:00
if doc :
doc . fiscal_year = years [ 0 ]
else :
throw ( _ ( " {0} ' {1} ' not in Fiscal Year {2} " ) . format ( label , formatdate ( date ) , fiscal_year ) )
2013-01-29 06:02:38 +00:00
2014-02-14 10:17:51 +00:00
@frappe.whitelist ( )
2015-09-04 07:56:23 +00:00
def get_balance_on ( account = None , date = None , party_type = None , party = None , in_account_currency = True ) :
2014-02-14 10:17:51 +00:00
if not account and frappe . form_dict . get ( " account " ) :
account = frappe . form_dict . get ( " account " )
2014-09-17 08:41:22 +00:00
if not date and frappe . form_dict . get ( " date " ) :
2014-02-14 10:17:51 +00:00
date = frappe . form_dict . get ( " date " )
2014-09-17 08:41:22 +00:00
if not party_type and frappe . form_dict . get ( " party_type " ) :
party_type = frappe . form_dict . get ( " party_type " )
if not party and frappe . form_dict . get ( " party " ) :
party = frappe . form_dict . get ( " party " )
2014-04-21 07:12:21 +00:00
2013-01-29 06:02:38 +00:00
cond = [ ]
if date :
2015-11-17 12:57:50 +00:00
cond . append ( " posting_date <= ' %s ' " % frappe . db . escape ( date ) )
2013-01-29 06:02:38 +00:00
else :
# get balance of all entries that exist
date = nowdate ( )
2014-04-08 08:23:35 +00:00
2013-01-29 06:02:38 +00:00
try :
year_start_date = get_fiscal_year ( date , verbose = 0 ) [ 1 ]
2014-04-14 13:50:45 +00:00
except FiscalYearError :
2013-01-29 06:02:38 +00:00
if getdate ( date ) > getdate ( nowdate ( ) ) :
# if fiscal year not found and the date is greater than today
# get fiscal year for today's date and its corresponding year start date
year_start_date = get_fiscal_year ( nowdate ( ) , verbose = 1 ) [ 1 ]
else :
# this indicates that it is a date older than any existing fiscal year.
# hence, assuming balance as 0.0
return 0.0
2014-04-08 08:23:35 +00:00
2014-09-17 08:41:22 +00:00
if account :
acc = frappe . get_doc ( " Account " , account )
2015-10-15 11:01:16 +00:00
if not frappe . flags . ignore_account_permission :
acc . check_permission ( " read " )
2014-09-17 08:41:22 +00:00
# for pl accounts, get balance within a fiscal year
if acc . report_type == ' Profit and Loss ' :
cond . append ( " posting_date >= ' %s ' and voucher_type != ' Period Closing Voucher ' " \
% year_start_date )
# different filter for group and ledger - improved performance
2015-04-23 07:44:17 +00:00
if acc . is_group :
2014-09-17 08:41:22 +00:00
cond . append ( """ exists (
2015-06-14 12:19:29 +00:00
select name from ` tabAccount ` ac where ac . name = gle . account
2014-09-17 08:41:22 +00:00
and ac . lft > = % s and ac . rgt < = % s
) """ % (acc.lft, acc.rgt))
2015-09-28 08:01:17 +00:00
# If group and currency same as company,
2015-09-17 08:27:42 +00:00
# always return balance based on debit and credit in company currency
if acc . account_currency == frappe . db . get_value ( " Company " , acc . company , " default_currency " ) :
in_account_currency = False
2014-09-17 08:41:22 +00:00
else :
2015-11-17 12:57:50 +00:00
cond . append ( """ gle.account = " %s " """ % ( frappe . db . escape ( account ) , ) )
2014-09-17 08:41:22 +00:00
if party_type and party :
cond . append ( """ gle.party_type = " %s " and gle.party = " %s " """ %
2015-11-17 12:57:50 +00:00
( frappe . db . escape ( party_type ) , frappe . db . escape ( party ) ) )
2015-09-16 07:16:54 +00:00
2015-08-17 05:57:00 +00:00
if account or ( party_type and party ) :
2015-09-04 07:56:23 +00:00
if in_account_currency :
select_field = " sum(ifnull(debit_in_account_currency, 0)) - sum(ifnull(credit_in_account_currency, 0)) "
else :
select_field = " sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) "
2015-08-17 05:57:00 +00:00
bal = frappe . db . sql ( """
2015-09-04 07:56:23 +00:00
SELECT { 0 }
2015-08-17 05:57:00 +00:00
FROM ` tabGL Entry ` gle
2015-09-04 07:56:23 +00:00
WHERE { 1 } """ .format(select_field, " and " .join(cond)))[0][0]
2015-08-17 05:57:00 +00:00
# if bal is None, return 0
return flt ( bal )
2013-01-30 13:46:13 +00:00
2014-02-14 10:17:51 +00:00
@frappe.whitelist ( )
2013-01-30 13:46:13 +00:00
def add_ac ( args = None ) :
if not args :
2014-02-14 10:17:51 +00:00
args = frappe . local . form_dict
2013-01-30 13:46:13 +00:00
args . pop ( " cmd " )
2014-04-08 08:23:35 +00:00
2014-04-22 13:24:54 +00:00
ac = frappe . new_doc ( " Account " )
ac . update ( args )
2014-03-28 08:25:00 +00:00
ac . old_parent = " "
ac . freeze_account = " No "
2013-01-30 13:46:13 +00:00
ac . insert ( )
2014-04-22 13:24:54 +00:00
2014-03-28 08:25:00 +00:00
return ac . name
2013-01-30 13:46:13 +00:00
2014-02-14 10:17:51 +00:00
@frappe.whitelist ( )
2013-01-30 13:46:13 +00:00
def add_cc ( args = None ) :
if not args :
2014-02-14 10:17:51 +00:00
args = frappe . local . form_dict
2013-01-30 13:46:13 +00:00
args . pop ( " cmd " )
2014-04-08 08:23:35 +00:00
2014-04-22 13:24:54 +00:00
cc = frappe . new_doc ( " Cost Center " )
cc . update ( args )
2014-03-28 08:25:00 +00:00
cc . old_parent = " "
2013-01-30 13:46:13 +00:00
cc . insert ( )
2014-03-28 08:25:00 +00:00
return cc . name
2013-01-30 13:46:13 +00:00
def reconcile_against_document ( args ) :
"""
Cancel JV , Update aginst document , split if required and resubmit jv
"""
for d in args :
check_if_jv_modified ( d )
2014-04-30 14:00:50 +00:00
validate_allocated_amount ( d )
2013-01-30 13:46:13 +00:00
# cancel JV
2014-12-25 11:44:18 +00:00
jv_obj = frappe . get_doc ( ' Journal Entry ' , d [ ' voucher_no ' ] )
2014-04-08 08:23:35 +00:00
2013-01-30 13:46:13 +00:00
jv_obj . make_gl_entries ( cancel = 1 , adv_adj = 1 )
2014-04-08 08:23:35 +00:00
2013-01-30 13:46:13 +00:00
# update ref in JV Detail
update_against_doc ( d , jv_obj )
# re-submit JV
2014-12-25 11:44:18 +00:00
jv_obj = frappe . get_doc ( ' Journal Entry ' , d [ ' voucher_no ' ] )
2013-01-30 13:46:13 +00:00
jv_obj . make_gl_entries ( cancel = 0 , adv_adj = 1 )
def check_if_jv_modified ( args ) :
"""
check if there is already a voucher reference
check if amount is same
check if jv is submitted
"""
2014-02-26 07:05:33 +00:00
ret = frappe . db . sql ( """
2014-12-25 11:44:18 +00:00
select t2 . { dr_or_cr } from ` tabJournal Entry ` t1 , ` tabJournal Entry Account ` t2
2014-07-21 13:52:02 +00:00
where t1 . name = t2 . parent and t2 . account = % ( account ) s
2014-08-29 05:48:32 +00:00
and t2 . party_type = % ( party_type ) s and t2 . party = % ( party ) s
2015-08-10 11:34:07 +00:00
and ifnull ( t2 . reference_type , ' ' ) in ( " " , " Sales Order " , " Purchase Order " )
2014-07-21 13:52:02 +00:00
and t1 . name = % ( voucher_no ) s and t2 . name = % ( voucher_detail_no ) s
and t1 . docstatus = 1 """ .format(dr_or_cr = args.get( " dr_or_cr " )), args)
2014-04-08 08:23:35 +00:00
2013-01-30 13:46:13 +00:00
if not ret :
2014-01-29 11:01:38 +00:00
throw ( _ ( """ Payment Entry has been modified after you pulled it. Please pull it again. """ ) )
2013-01-30 13:46:13 +00:00
2014-04-30 14:00:50 +00:00
def validate_allocated_amount ( args ) :
if args . get ( " allocated_amt " ) < 0 :
throw ( _ ( " Allocated amount can not be negative " ) )
elif args . get ( " allocated_amt " ) > args . get ( " unadjusted_amt " ) :
throw ( _ ( " Allocated amount can not greater than unadusted amount " ) )
2013-01-30 13:46:13 +00:00
def update_against_doc ( d , jv_obj ) :
"""
Updates against document , if partial amount splits into rows
"""
2014-12-25 12:49:39 +00:00
jv_detail = jv_obj . get ( " accounts " , { " name " : d [ " voucher_detail_no " ] } ) [ 0 ]
2014-04-08 08:23:35 +00:00
jv_detail . set ( d [ " dr_or_cr " ] , d [ " allocated_amt " ] )
2015-10-15 11:01:16 +00:00
jv_detail . set ( ' debit ' if d [ ' dr_or_cr ' ] == ' debit_in_account_currency ' else ' credit ' ,
2015-10-02 06:35:55 +00:00
d [ " allocated_amt " ] * flt ( jv_detail . exchange_rate ) )
2015-08-10 11:34:07 +00:00
original_reference_type = jv_detail . reference_type
original_reference_name = jv_detail . reference_name
jv_detail . set ( " reference_type " , d [ " against_voucher_type " ] )
jv_detail . set ( " reference_name " , d [ " against_voucher " ] )
2013-01-30 13:46:13 +00:00
if d [ ' allocated_amt ' ] < d [ ' unadjusted_amt ' ] :
2015-09-09 13:13:12 +00:00
jvd = frappe . db . sql ( """
2015-11-12 11:35:29 +00:00
select cost_center , balance , against_account , is_advance ,
2015-10-16 07:38:33 +00:00
account_type , exchange_rate , account_currency
2015-09-09 13:13:12 +00:00
from ` tabJournal Entry Account ` where name = % s
""" , d[ ' voucher_detail_no ' ], as_dict=True)
2015-10-15 11:01:16 +00:00
2015-10-02 06:35:55 +00:00
amount_in_account_currency = flt ( d [ ' unadjusted_amt ' ] ) - flt ( d [ ' allocated_amt ' ] )
amount_in_company_currency = amount_in_account_currency * flt ( jvd [ 0 ] [ ' exchange_rate ' ] )
2015-09-16 07:16:54 +00:00
2013-01-30 13:46:13 +00:00
# new entry with balance amount
2014-12-25 12:49:39 +00:00
ch = jv_obj . append ( " accounts " )
2013-01-30 13:46:13 +00:00
ch . account = d [ ' account ' ]
2015-09-09 13:13:12 +00:00
ch . account_type = jvd [ 0 ] [ ' account_type ' ]
2015-10-16 07:38:33 +00:00
ch . account_currency = jvd [ 0 ] [ ' account_currency ' ]
2015-09-09 13:13:12 +00:00
ch . exchange_rate = jvd [ 0 ] [ ' exchange_rate ' ]
2014-08-29 05:48:32 +00:00
ch . party_type = d [ " party_type " ]
ch . party = d [ " party " ]
2015-09-09 13:13:12 +00:00
ch . cost_center = cstr ( jvd [ 0 ] [ " cost_center " ] )
ch . balance = flt ( jvd [ 0 ] [ " balance " ] )
2015-10-15 11:01:16 +00:00
2015-10-02 06:35:55 +00:00
ch . set ( d [ ' dr_or_cr ' ] , amount_in_account_currency )
ch . set ( ' debit ' if d [ ' dr_or_cr ' ] == ' debit_in_account_currency ' else ' credit ' , amount_in_company_currency )
2015-10-15 11:01:16 +00:00
ch . set ( ' credit_in_account_currency ' if d [ ' dr_or_cr ' ] == ' debit_in_account_currency '
2015-10-02 06:35:55 +00:00
else ' debit_in_account_currency ' , 0 )
ch . set ( ' credit ' if d [ ' dr_or_cr ' ] == ' debit_in_account_currency ' else ' debit ' , 0 )
2015-10-15 11:01:16 +00:00
2015-09-09 13:13:12 +00:00
ch . against_account = cstr ( jvd [ 0 ] [ " against_account " ] )
2015-08-10 11:34:07 +00:00
ch . reference_type = original_reference_type
ch . reference_name = original_reference_name
2015-09-09 13:13:12 +00:00
ch . is_advance = cstr ( jvd [ 0 ] [ " is_advance " ] )
2013-01-30 13:46:13 +00:00
ch . docstatus = 1
2014-04-08 08:23:35 +00:00
# will work as update after submit
2015-02-10 09:11:27 +00:00
jv_obj . flags . ignore_validate_update_after_submit = True
2014-04-08 08:23:35 +00:00
jv_obj . save ( )
2015-08-10 11:34:07 +00:00
def remove_against_link_from_jv ( ref_type , ref_no ) :
2014-12-25 10:31:55 +00:00
linked_jv = frappe . db . sql_list ( """ select parent from `tabJournal Entry Account`
2015-08-10 11:34:07 +00:00
where reference_type = % s and reference_name = % s and docstatus < 2 """ , (ref_type, ref_no))
2014-04-08 08:23:35 +00:00
if linked_jv :
2015-08-10 11:34:07 +00:00
frappe . db . sql ( """ update `tabJournal Entry Account`
set reference_type = null , reference_name = null ,
2014-01-03 09:42:16 +00:00
modified = % s , modified_by = % s
2015-08-10 11:34:07 +00:00
where reference_type = % s and reference_name = % s
and docstatus < 2 """ , (now(), frappe.session.user, ref_type, ref_no))
2014-04-08 08:23:35 +00:00
2014-02-26 07:05:33 +00:00
frappe . db . sql ( """ update `tabGL Entry`
2014-01-03 09:42:16 +00:00
set against_voucher_type = null , against_voucher = null ,
modified = % s , modified_by = % s
where against_voucher_type = % s and against_voucher = % s
and voucher_no != ifnull ( against_voucher , ' ' ) """ ,
2014-02-14 10:17:51 +00:00
( now ( ) , frappe . session . user , ref_type , ref_no ) )
2014-04-08 08:23:35 +00:00
2014-12-25 11:44:18 +00:00
frappe . msgprint ( _ ( " Journal Entries {0} are un-linked " . format ( " \n " . join ( linked_jv ) ) ) )
2014-04-08 08:23:35 +00:00
2013-03-25 05:36:00 +00:00
2014-02-14 10:17:51 +00:00
@frappe.whitelist ( )
2013-03-25 05:36:00 +00:00
def get_company_default ( company , fieldname ) :
2014-02-26 07:05:33 +00:00
value = frappe . db . get_value ( " Company " , company , fieldname )
2014-04-08 08:23:35 +00:00
2013-03-25 05:36:00 +00:00
if not value :
2014-11-26 10:05:08 +00:00
throw ( _ ( " Please set default value {0} in Company {1} " ) . format ( frappe . get_meta ( " Company " ) . get_label ( fieldname ) , company ) )
2014-04-08 08:23:35 +00:00
2013-03-25 05:36:00 +00:00
return value
2013-05-28 11:22:30 +00:00
def fix_total_debit_credit ( ) :
2014-04-08 08:23:35 +00:00
vouchers = frappe . db . sql ( """ select voucher_type, voucher_no,
sum ( debit ) - sum ( credit ) as diff
from ` tabGL Entry `
2013-05-28 11:22:30 +00:00
group by voucher_type , voucher_no
having sum ( ifnull ( debit , 0 ) ) != sum ( ifnull ( credit , 0 ) ) """ , as_dict=1)
2014-04-08 08:23:35 +00:00
2013-05-28 11:22:30 +00:00
for d in vouchers :
if abs ( d . diff ) > 0 :
dr_or_cr = d . voucher_type == " Sales Invoice " and " credit " or " debit "
2014-04-08 08:23:35 +00:00
2014-02-26 07:05:33 +00:00
frappe . db . sql ( """ update `tabGL Entry` set %s = %s + %s
2013-05-28 11:22:30 +00:00
where voucher_type = % s and voucher_no = % s and % s > 0 limit 1 """ %
2014-04-08 08:23:35 +00:00
( dr_or_cr , dr_or_cr , ' %s ' , ' %s ' , ' %s ' , dr_or_cr ) ,
2013-08-02 06:14:29 +00:00
( d . diff , d . voucher_type , d . voucher_no ) )
2014-04-08 08:23:35 +00:00
2013-08-26 11:23:30 +00:00
def get_stock_and_account_difference ( account_list = None , posting_date = None ) :
2014-10-08 06:49:55 +00:00
from erpnext . stock . utils import get_stock_value_on
2014-04-08 08:23:35 +00:00
2013-08-26 11:23:30 +00:00
if not posting_date : posting_date = nowdate ( )
2014-04-08 08:23:35 +00:00
2013-08-02 06:14:29 +00:00
difference = { }
2014-04-08 08:23:35 +00:00
2014-08-27 06:35:48 +00:00
account_warehouse = dict ( frappe . db . sql ( """ select name, warehouse from tabAccount
where account_type = ' Warehouse ' and ifnull ( warehouse , ' ' ) != ' '
2013-09-25 05:02:51 +00:00
and name in ( % s ) """ % ' , ' .join([ ' %s ' ]*len(account_list)), account_list))
2014-04-08 08:23:35 +00:00
2013-09-25 05:02:51 +00:00
for account , warehouse in account_warehouse . items ( ) :
2015-09-04 07:56:23 +00:00
account_balance = get_balance_on ( account , posting_date , in_account_currency = False )
2014-10-08 06:49:55 +00:00
stock_value = get_stock_value_on ( warehouse , posting_date )
2013-08-07 08:51:04 +00:00
if abs ( flt ( stock_value ) - flt ( account_balance ) ) > 0.005 :
2013-08-07 07:03:37 +00:00
difference . setdefault ( account , flt ( stock_value ) - flt ( account_balance ) )
2013-08-07 08:51:04 +00:00
2013-08-06 10:49:18 +00:00
return difference
2013-08-22 09:08:46 +00:00
def validate_expense_against_budget ( args ) :
2014-02-14 10:17:51 +00:00
args = frappe . _dict ( args )
2015-10-13 09:24:26 +00:00
if frappe . db . get_value ( " Account " , { " name " : args . account , " root_type " : " Expense " } ) :
2014-02-26 07:05:33 +00:00
budget = frappe . db . sql ( """
2014-04-08 08:23:35 +00:00
select bd . budget_allocated , cc . distribution_id
2013-08-22 09:08:46 +00:00
from ` tabCost Center ` cc , ` tabBudget Detail ` bd
where cc . name = bd . parent and cc . name = % s and account = % s and bd . fiscal_year = % s
""" , (args.cost_center, args.account, args.fiscal_year), as_dict=True)
2014-04-08 08:23:35 +00:00
2013-08-22 09:08:46 +00:00
if budget and budget [ 0 ] . budget_allocated :
2014-04-08 08:23:35 +00:00
yearly_action , monthly_action = frappe . db . get_value ( " Company " , args . company ,
2013-08-22 09:08:46 +00:00
[ " yearly_bgt_flag " , " monthly_bgt_flag " ] )
2013-08-22 12:55:43 +00:00
action_for = action = " "
if monthly_action in [ " Stop " , " Warn " ] :
2014-04-08 08:23:35 +00:00
budget_amount = get_allocated_budget ( budget [ 0 ] . distribution_id ,
2013-08-22 12:55:43 +00:00
args . posting_date , args . fiscal_year , budget [ 0 ] . budget_allocated )
2014-04-08 08:23:35 +00:00
args [ " month_end_date " ] = frappe . db . sql ( " select LAST_DAY( %s ) " ,
2013-08-23 05:16:41 +00:00
args . posting_date ) [ 0 ] [ 0 ]
2014-04-15 11:00:55 +00:00
action_for , action = _ ( " Monthly " ) , monthly_action
2014-04-08 08:23:35 +00:00
2013-08-22 12:55:43 +00:00
elif yearly_action in [ " Stop " , " Warn " ] :
budget_amount = budget [ 0 ] . budget_allocated
2014-04-15 11:00:55 +00:00
action_for , action = _ ( " Annual " ) , yearly_action
2013-08-23 05:16:41 +00:00
2013-08-22 12:55:43 +00:00
if action_for :
actual_expense = get_actual_expense ( args )
if actual_expense > budget_amount :
2014-04-15 11:00:55 +00:00
frappe . msgprint ( _ ( " {0} budget for Account {1} against Cost Center {2} will exceed by {3} " ) . format (
_ ( action_for ) , args . account , args . cost_center , cstr ( actual_expense - budget_amount ) ) )
if action == " Stop " :
raise BudgetError
2014-04-08 08:23:35 +00:00
2013-08-22 12:55:43 +00:00
def get_allocated_budget ( distribution_id , posting_date , fiscal_year , yearly_budget ) :
if distribution_id :
distribution = { }
2015-01-10 10:33:49 +00:00
for d in frappe . db . sql ( """ select mdp.month, mdp.percentage_allocation
from ` tabMonthly Distribution Percentage ` mdp , ` tabMonthly Distribution ` md
where mdp . parent = md . name and md . fiscal_year = % s """ , fiscal_year, as_dict=1):
2013-08-22 12:55:43 +00:00
distribution . setdefault ( d . month , d . percentage_allocation )
2013-08-23 05:16:41 +00:00
2014-02-26 07:05:33 +00:00
dt = frappe . db . get_value ( " Fiscal Year " , fiscal_year , " year_start_date " )
2013-08-22 12:55:43 +00:00
budget_percentage = 0.0
2014-04-08 08:23:35 +00:00
2013-08-22 12:55:43 +00:00
while ( dt < = getdate ( posting_date ) ) :
if distribution_id :
2013-08-23 05:16:41 +00:00
budget_percentage + = distribution . get ( getdate ( dt ) . strftime ( " % B " ) , 0 )
2013-08-22 12:55:43 +00:00
else :
budget_percentage + = 100.0 / 12
2014-04-08 08:23:35 +00:00
2013-08-22 12:55:43 +00:00
dt = add_months ( dt , 1 )
2014-04-08 08:23:35 +00:00
2013-08-22 12:55:43 +00:00
return yearly_budget * budget_percentage / 100
2014-04-08 08:23:35 +00:00
2013-08-22 09:08:46 +00:00
def get_actual_expense ( args ) :
2013-08-23 05:16:41 +00:00
args [ " condition " ] = " and posting_date<= ' %s ' " % args . month_end_date \
if args . get ( " month_end_date " ) else " "
2014-04-08 08:23:35 +00:00
2015-03-17 04:44:59 +00:00
return flt ( frappe . db . sql ( """
2013-08-22 09:08:46 +00:00
select sum ( ifnull ( debit , 0 ) ) - sum ( ifnull ( credit , 0 ) )
from ` tabGL Entry `
2014-04-08 08:23:35 +00:00
where account = ' %(account)s ' and cost_center = ' %(cost_center)s '
2013-08-23 05:16:41 +00:00
and fiscal_year = ' %(fiscal_year)s ' and company = ' %(company)s ' % ( condition ) s
2015-03-17 04:44:59 +00:00
""" % (args))[0][0])
2014-04-08 08:23:35 +00:00
2014-01-22 10:06:44 +00:00
def get_currency_precision ( currency = None ) :
if not currency :
2014-04-08 08:23:35 +00:00
currency = frappe . db . get_value ( " Company " ,
2015-04-27 07:43:38 +00:00
frappe . db . get_default ( " company " ) , " default_currency " , cache = True )
currency_format = frappe . db . get_value ( " Currency " , currency , " number_format " , cache = True )
2014-04-08 08:23:35 +00:00
2014-02-14 10:17:51 +00:00
from frappe . utils import get_number_format_info
2014-01-24 16:14:36 +00:00
return get_number_format_info ( currency_format ) [ 2 ]
2014-08-07 09:40:05 +00:00
def get_stock_rbnb_difference ( posting_date , company ) :
stock_items = frappe . db . sql_list ( """ select distinct item_code
2014-08-07 09:43:52 +00:00
from ` tabStock Ledger Entry ` where company = % s """ , company)
2014-08-07 09:40:05 +00:00
pr_valuation_amount = frappe . db . sql ( """
select sum ( ifnull ( pr_item . valuation_rate , 0 ) * ifnull ( pr_item . qty , 0 ) * ifnull ( pr_item . conversion_factor , 0 ) )
from ` tabPurchase Receipt Item ` pr_item , ` tabPurchase Receipt ` pr
where pr . name = pr_item . parent and pr . docstatus = 1 and pr . company = % s
and pr . posting_date < = % s and pr_item . item_code in ( % s ) """ %
( ' %s ' , ' %s ' , ' , ' . join ( [ ' %s ' ] * len ( stock_items ) ) ) , tuple ( [ company , posting_date ] + stock_items ) ) [ 0 ] [ 0 ]
pi_valuation_amount = frappe . db . sql ( """
select sum ( ifnull ( pi_item . valuation_rate , 0 ) * ifnull ( pi_item . qty , 0 ) * ifnull ( pi_item . conversion_factor , 0 ) )
from ` tabPurchase Invoice Item ` pi_item , ` tabPurchase Invoice ` pi
where pi . name = pi_item . parent and pi . docstatus = 1 and pi . company = % s
and pi . posting_date < = % s and pi_item . item_code in ( % s ) """ %
( ' %s ' , ' %s ' , ' , ' . join ( [ ' %s ' ] * len ( stock_items ) ) ) , tuple ( [ company , posting_date ] + stock_items ) ) [ 0 ] [ 0 ]
# Balance should be
stock_rbnb = flt ( pr_valuation_amount , 2 ) - flt ( pi_valuation_amount , 2 )
# Balance as per system
2014-08-07 09:43:52 +00:00
stock_rbnb_account = " Stock Received But Not Billed - " + frappe . db . get_value ( " Company " , company , " abbr " )
2015-09-04 07:56:23 +00:00
sys_bal = get_balance_on ( stock_rbnb_account , posting_date , in_account_currency = False )
2014-08-07 09:40:05 +00:00
# Amount should be credited
return flt ( stock_rbnb ) + flt ( sys_bal )
2014-09-12 09:48:53 +00:00
2015-11-12 11:35:29 +00:00
def get_outstanding_invoices ( party_type , party , account , condition = None ) :
outstanding_invoices = [ ]
precision = frappe . get_precision ( " Sales Invoice " , " outstanding_amount " )
if party_type == " Customer " :
dr_or_cr = " ifnull(debit_in_account_currency, 0) - ifnull(credit_in_account_currency, 0) "
payment_dr_or_cr = " ifnull(payment_gl_entry.credit_in_account_currency, 0) - ifnull(payment_gl_entry.debit_in_account_currency, 0) "
else :
dr_or_cr = " ifnull(credit_in_account_currency, 0) - ifnull(debit_in_account_currency, 0) "
payment_dr_or_cr = " ifnull(payment_gl_entry.debit_in_account_currency, 0) - ifnull(payment_gl_entry.credit_in_account_currency, 0) "
invoice_list = frappe . db . sql ( """ select
voucher_no , voucher_type , posting_date ,
ifnull ( sum ( { dr_or_cr } ) , 0 ) as invoice_amount ,
(
select
ifnull ( sum ( ifnull ( { payment_dr_or_cr } , 0 ) ) , 0 )
from ` tabGL Entry ` payment_gl_entry
where
payment_gl_entry . against_voucher_type = invoice_gl_entry . voucher_type
and payment_gl_entry . against_voucher = invoice_gl_entry . voucher_no
and payment_gl_entry . party_type = invoice_gl_entry . party_type
and payment_gl_entry . party = invoice_gl_entry . party
and payment_gl_entry . account = invoice_gl_entry . account
and { payment_dr_or_cr } > 0
) as payment_amount
2014-09-12 09:48:53 +00:00
from
2015-11-12 11:35:29 +00:00
` tabGL Entry ` invoice_gl_entry
2014-09-12 09:48:53 +00:00
where
2015-11-12 11:35:29 +00:00
party_type = % ( party_type ) s
and party = % ( party ) s
and account = % ( account ) s
and { dr_or_cr } > 0
{ condition }
and ( ( voucher_type = ' Journal Entry '
and ( against_voucher = ' '
or against_voucher is null ) )
or ( voucher_type != ' Journal Entry ' ) )
2014-09-12 09:48:53 +00:00
group by voucher_type , voucher_no
2015-11-12 11:35:29 +00:00
having ( invoice_amount - payment_amount ) > 0.005 """ .format(
dr_or_cr = dr_or_cr ,
payment_dr_or_cr = payment_dr_or_cr ,
condition = condition or " "
) , {
" party_type " : party_type ,
" party " : party ,
" account " : account ,
} , as_dict = True )
for d in invoice_list :
outstanding_invoices . append ( {
' voucher_no ' : d . voucher_no ,
' voucher_type ' : d . voucher_type ,
' posting_date ' : d . posting_date ,
' invoice_amount ' : flt ( d . invoice_amount ) ,
' payment_amount ' : flt ( d . payment_amount ) ,
' outstanding_amount ' : flt ( d . invoice_amount - d . payment_amount , precision )
} )
return outstanding_invoices