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-17 10:14:57 +00:00
2021-09-02 11:14:59 +00:00
2014-02-14 10:17:51 +00:00
import frappe
2017-03-31 07:14:29 +00:00
from frappe import _
2016-12-09 06:44:47 +00:00
from frappe . utils import add_days , flt , get_datetime_str , nowdate
2021-09-02 11:14:59 +00:00
2018-08-24 09:45:56 +00:00
from erpnext import get_default_company
2017-02-09 12:36:11 +00:00
2021-09-02 11:14:59 +00:00
2013-06-21 12:25:31 +00:00
def get_root_of ( doctype ) :
2016-12-08 09:13:11 +00:00
""" Get root element of a DocType with a tree structure """
result = frappe . db . sql_list ( """ select name from `tab %s `
where lft = 1 and rgt = ( select max ( rgt ) from ` tab % s ` where docstatus < 2 ) """ %
( doctype , doctype ) )
return result [ 0 ] if result else None
2014-04-14 13:50:45 +00:00
2013-06-21 12:25:31 +00:00
def get_ancestors_of ( doctype , name ) :
2016-12-08 09:13:11 +00:00
""" Get ancestor elements of a DocType with a tree structure """
lft , rgt = frappe . db . get_value ( doctype , name , [ " lft " , " rgt " ] )
result = frappe . db . sql_list ( """ select name from `tab %s `
where lft < % s and rgt > % s order by lft desc """ % (doctype, " %s " , " %s " ), (lft, rgt))
return result or [ ]
2013-06-21 12:25:31 +00:00
2014-04-30 14:08:28 +00:00
def before_tests ( ) :
2016-12-08 09:13:11 +00:00
frappe . clear_cache ( )
# complete setup if missing
from frappe . desk . page . setup_wizard . setup_wizard import setup_complete
if not frappe . get_list ( " Company " ) :
setup_complete ( {
2021-07-02 18:02:33 +00:00
" currency " : " USD " ,
" full_name " : " Test User " ,
" company_name " : " Wind Power LLC " ,
" timezone " : " America/New_York " ,
" company_abbr " : " WP " ,
" industry " : " Manufacturing " ,
" country " : " United States " ,
" fy_start_date " : " 2021-01-01 " ,
" fy_end_date " : " 2021-12-31 " ,
" language " : " english " ,
" company_tagline " : " Testing " ,
" email " : " test@erpnext.com " ,
" password " : " test " ,
2017-11-16 12:18:59 +00:00
" chart_of_accounts " : " Standard " ,
2021-07-02 18:02:33 +00:00
" domains " : [ " Manufacturing " ] ,
2016-12-08 09:13:11 +00:00
} )
2014-04-30 14:08:28 +00:00
2016-12-08 09:13:11 +00:00
frappe . db . sql ( " delete from `tabLeave Allocation` " )
frappe . db . sql ( " delete from `tabLeave Application` " )
frappe . db . sql ( " delete from `tabSalary Slip` " )
frappe . db . sql ( " delete from `tabItem Price` " )
2015-08-03 09:39:48 +00:00
2016-12-08 09:13:11 +00:00
frappe . db . set_value ( " Stock Settings " , None , " auto_insert_price_list_rate_if_missing " , 0 )
2017-07-26 10:59:22 +00:00
enable_all_roles_and_domains ( )
2021-12-05 16:37:14 +00:00
set_defaults_for_tests ( )
2015-08-03 09:39:48 +00:00
2016-12-08 09:13:11 +00:00
frappe . db . commit ( )
2014-07-01 12:15:15 +00:00
2015-05-07 06:55:33 +00:00
@frappe.whitelist ( )
2018-05-15 05:55:46 +00:00
def get_exchange_rate ( from_currency , to_currency , transaction_date = None , args = None ) :
2016-12-09 06:44:47 +00:00
if not ( from_currency and to_currency ) :
2016-12-08 09:13:11 +00:00
# manqala 19/09/2016: Should this be an empty return or should it throw and exception?
return
if from_currency == to_currency :
return 1
2017-02-09 12:36:11 +00:00
2017-09-21 09:20:39 +00:00
if not transaction_date :
transaction_date = nowdate ( )
currency_settings = frappe . get_doc ( " Accounts Settings " ) . as_dict ( )
allow_stale_rates = currency_settings . get ( " allow_stale " )
filters = [
[ " date " , " <= " , get_datetime_str ( transaction_date ) ] ,
[ " from_currency " , " = " , from_currency ] ,
[ " to_currency " , " = " , to_currency ]
]
2018-05-15 11:28:45 +00:00
2018-05-15 05:55:46 +00:00
if args == " for_buying " :
filters . append ( [ " for_buying " , " = " , " 1 " ] )
elif args == " for_selling " :
2018-05-15 11:28:45 +00:00
filters . append ( [ " for_selling " , " = " , " 1 " ] )
2017-09-21 09:20:39 +00:00
if not allow_stale_rates :
stale_days = currency_settings . get ( " stale_days " )
checkpoint_date = add_days ( transaction_date , - stale_days )
filters . append ( [ " date " , " > " , get_datetime_str ( checkpoint_date ) ] )
2016-12-08 10:06:23 +00:00
# cksgb 19/09/2016: get last entry in Currency Exchange with from_currency and to_currency.
2017-09-21 09:20:39 +00:00
entries = frappe . get_all (
" Currency Exchange " , fields = [ " exchange_rate " ] , filters = filters , order_by = " date desc " ,
limit = 1 )
2016-12-08 09:13:11 +00:00
if entries :
return flt ( entries [ 0 ] . exchange_rate )
2015-10-15 06:20:38 +00:00
2016-12-08 09:13:11 +00:00
try :
cache = frappe . cache ( )
2021-06-28 13:31:52 +00:00
key = " currency_exchange_rate_ {0} : {1} : {2} " . format ( transaction_date , from_currency , to_currency )
2016-12-08 09:13:11 +00:00
value = cache . get ( key )
2015-10-15 06:27:46 +00:00
2016-12-08 09:13:11 +00:00
if not value :
import requests
2021-06-28 13:31:52 +00:00
api_url = " https://api.exchangerate.host/convert "
2017-08-31 09:00:15 +00:00
response = requests . get ( api_url , params = {
2021-06-28 13:31:52 +00:00
" date " : transaction_date ,
" from " : from_currency ,
" to " : to_currency
2016-12-08 09:13:11 +00:00
} )
# expire in 6 hours
response . raise_for_status ( )
2021-06-28 13:31:52 +00:00
value = response . json ( ) [ " result " ]
2021-07-29 10:28:27 +00:00
cache . setex ( name = key , time = 21600 , value = flt ( value ) )
2016-12-08 09:13:11 +00:00
return flt ( value )
2021-09-01 09:10:56 +00:00
except Exception :
2019-01-24 10:58:53 +00:00
frappe . log_error ( title = " Get Exchange Rate " )
2017-05-24 10:48:27 +00:00
frappe . msgprint ( _ ( " Unable to find exchange rate for {0} to {1} for key date {2} . Please create a Currency Exchange record manually " ) . format ( from_currency , to_currency , transaction_date ) )
2017-07-06 05:39:34 +00:00
return 0.0
2017-07-26 10:59:22 +00:00
def enable_all_roles_and_domains ( ) :
""" enable all roles and domain for testing """
# add all roles to users
2017-10-17 07:00:34 +00:00
domains = frappe . get_all ( " Domain " )
2017-07-26 10:59:22 +00:00
if not domains :
return
2017-10-17 07:00:34 +00:00
from frappe . desk . page . setup_wizard . setup_wizard import add_all_roles_to
frappe . get_single ( ' Domain Settings ' ) . set_active_domains ( \
[ d . name for d in domains ] )
add_all_roles_to ( ' Administrator ' )
2017-11-23 09:52:10 +00:00
2021-12-05 16:37:14 +00:00
def set_defaults_for_tests ( ) :
from frappe . utils . nestedset import get_root_of
selling_settings = frappe . get_single ( " Selling Settings " )
selling_settings . customer_group = get_root_of ( " Customer Group " )
selling_settings . territory = get_root_of ( " Territory " )
selling_settings . save ( )
2017-11-23 09:52:10 +00:00
def insert_record ( records ) :
for r in records :
doc = frappe . new_doc ( r . get ( " doctype " ) )
doc . update ( r )
try :
doc . insert ( ignore_permissions = True )
2018-01-30 08:17:18 +00:00
except frappe . DuplicateEntryError as e :
2017-11-23 09:52:10 +00:00
# pass DuplicateEntryError and continue
if e . args and e . args [ 0 ] == doc . doctype and e . args [ 1 ] == doc . name :
# make sure DuplicateEntryError is for the exact same doc and not a related doc
pass
else :
raise
2018-08-24 09:45:56 +00:00
def welcome_email ( ) :
2020-03-05 04:38:43 +00:00
site_name = get_default_company ( ) or " ERPNext "
2020-01-29 09:36:18 +00:00
title = _ ( " Welcome to {0} " ) . format ( site_name )
2019-03-06 00:44:02 +00:00
return title