mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-31 15:32:27 +00:00
Merge branch 'develop' into remove-nonprofit
This commit is contained in:
@@ -213,6 +213,9 @@ erpnext.company.setup_queries = function(frm) {
|
||||
["default_payroll_payable_account", {"root_type": "Liability"}],
|
||||
["round_off_account", {"root_type": "Expense"}],
|
||||
["write_off_account", {"root_type": "Expense"}],
|
||||
["default_deferred_expense_account", {}],
|
||||
["default_deferred_revenue_account", {}],
|
||||
["default_expense_claim_payable_account", {}],
|
||||
["default_discount_account", {}],
|
||||
["discount_allowed_account", {"root_type": "Expense"}],
|
||||
["discount_received_account", {"root_type": "Income"}],
|
||||
|
||||
@@ -62,8 +62,13 @@ def patched_requests_get(*args, **kwargs):
|
||||
if kwargs['params'].get('date') and kwargs['params'].get('from') and kwargs['params'].get('to'):
|
||||
if test_exchange_values.get(kwargs['params']['date']):
|
||||
return PatchResponse({'result': test_exchange_values[kwargs['params']['date']]}, 200)
|
||||
elif args[0].startswith("https://frankfurter.app") and kwargs.get('params'):
|
||||
if kwargs['params'].get('base') and kwargs['params'].get('symbols'):
|
||||
date = args[0].replace("https://frankfurter.app/", "")
|
||||
if test_exchange_values.get(date):
|
||||
return PatchResponse({'rates': {kwargs['params'].get('symbols'): test_exchange_values.get(date)}}, 200)
|
||||
|
||||
return PatchResponse({'result': None}, 404)
|
||||
return PatchResponse({'rates': None}, 404)
|
||||
|
||||
@mock.patch('requests.get', side_effect=patched_requests_get)
|
||||
class TestCurrencyExchange(unittest.TestCase):
|
||||
@@ -102,6 +107,41 @@ class TestCurrencyExchange(unittest.TestCase):
|
||||
self.assertFalse(exchange_rate == 60)
|
||||
self.assertEqual(flt(exchange_rate, 3), 65.1)
|
||||
|
||||
def test_exchange_rate_via_exchangerate_host(self, mock_get):
|
||||
save_new_records(test_records)
|
||||
|
||||
# Update Currency Exchange Rate
|
||||
settings = frappe.get_single("Currency Exchange Settings")
|
||||
settings.service_provider = 'exchangerate.host'
|
||||
settings.save()
|
||||
|
||||
# Update exchange
|
||||
frappe.db.set_value("Accounts Settings", None, "allow_stale", 1)
|
||||
|
||||
# Start with allow_stale is True
|
||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-01", "for_buying")
|
||||
self.assertEqual(flt(exchange_rate, 3), 60.0)
|
||||
|
||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15", "for_buying")
|
||||
self.assertEqual(exchange_rate, 65.1)
|
||||
|
||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-30", "for_selling")
|
||||
self.assertEqual(exchange_rate, 62.9)
|
||||
|
||||
# Exchange rate as on 15th Dec, 2015
|
||||
self.clear_cache()
|
||||
exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15", "for_selling")
|
||||
self.assertFalse(exchange_rate == 60)
|
||||
self.assertEqual(flt(exchange_rate, 3), 66.999)
|
||||
|
||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-20", "for_buying")
|
||||
self.assertFalse(exchange_rate == 60)
|
||||
self.assertEqual(flt(exchange_rate, 3), 65.1)
|
||||
|
||||
settings = frappe.get_single("Currency Exchange Settings")
|
||||
settings.service_provider = 'frankfurter.app'
|
||||
settings.save()
|
||||
|
||||
def test_exchange_rate_strict(self, mock_get):
|
||||
# strict currency settings
|
||||
frappe.db.set_value("Accounts Settings", None, "allow_stale", 0)
|
||||
|
||||
@@ -60,6 +60,22 @@ def set_single_defaults():
|
||||
|
||||
frappe.db.set_default("date_format", "dd-mm-yyyy")
|
||||
|
||||
setup_currency_exchange()
|
||||
|
||||
def setup_currency_exchange():
|
||||
ces = frappe.get_single('Currency Exchange Settings')
|
||||
try:
|
||||
ces.set('result_key', [])
|
||||
ces.set('req_params', [])
|
||||
|
||||
ces.api_endpoint = "https://frankfurter.app/{transaction_date}"
|
||||
ces.append('result_key', {'key': 'rates'})
|
||||
ces.append('result_key', {'key': '{to_currency}'})
|
||||
ces.append('req_params', {'key': 'base', 'value': '{from_currency}'})
|
||||
ces.append('req_params', {'key': 'symbols', 'value': '{to_currency}'})
|
||||
ces.save()
|
||||
except frappe.ValidationError:
|
||||
pass
|
||||
|
||||
def create_compact_item_print_custom_field():
|
||||
create_custom_field('Print Settings', {
|
||||
|
||||
@@ -351,7 +351,8 @@ def add_uom_data():
|
||||
"doctype": "UOM",
|
||||
"uom_name": _(d.get("uom_name")),
|
||||
"name": _(d.get("uom_name")),
|
||||
"must_be_whole_number": d.get("must_be_whole_number")
|
||||
"must_be_whole_number": d.get("must_be_whole_number"),
|
||||
"enabled": 1,
|
||||
}).db_insert()
|
||||
|
||||
# bootstrap uom conversion factors
|
||||
|
||||
@@ -100,15 +100,21 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No
|
||||
|
||||
if not value:
|
||||
import requests
|
||||
api_url = "https://api.exchangerate.host/convert"
|
||||
response = requests.get(api_url, params={
|
||||
"date": transaction_date,
|
||||
"from": from_currency,
|
||||
"to": to_currency
|
||||
})
|
||||
settings = frappe.get_cached_doc('Currency Exchange Settings')
|
||||
req_params = {
|
||||
"transaction_date": transaction_date,
|
||||
"from_currency": from_currency,
|
||||
"to_currency": to_currency
|
||||
}
|
||||
params = {}
|
||||
for row in settings.req_params:
|
||||
params[row.key] = format_ces_api(row.value, req_params)
|
||||
response = requests.get(format_ces_api(settings.api_endpoint, req_params), params=params)
|
||||
# expire in 6 hours
|
||||
response.raise_for_status()
|
||||
value = response.json()["result"]
|
||||
value = response.json()
|
||||
for res_key in settings.result_key:
|
||||
value = value[format_ces_api(str(res_key.key), req_params)]
|
||||
cache.setex(name=key, time=21600, value=flt(value))
|
||||
return flt(value)
|
||||
except Exception:
|
||||
@@ -116,6 +122,13 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No
|
||||
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))
|
||||
return 0.0
|
||||
|
||||
def format_ces_api(data, param):
|
||||
return data.format(
|
||||
transaction_date=param.get("transaction_date"),
|
||||
to_currency=param.get("to_currency"),
|
||||
from_currency=param.get("from_currency")
|
||||
)
|
||||
|
||||
def enable_all_roles_and_domains():
|
||||
""" enable all roles and domain for testing """
|
||||
# add all roles to users
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"charts": [],
|
||||
"content": "[{\"type\":\"header\",\"data\":{\"text\":\"Your Shortcuts\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\",\"level\":4,\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Projects Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"HR Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Selling Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Buying Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Support Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Shopping Cart Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Portal Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Domain Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Products Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Naming Series\",\"col\":4}}]",
|
||||
"content": "[{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t</b></span>\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Projects Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"HR Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Selling Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Buying Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Support Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Shopping Cart Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Portal Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Domain Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Products Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Naming Series\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Manufacturing Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Education Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Hotel Settings\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"CRM Settings\",\"col\":3}}]",
|
||||
"creation": "2020-03-12 14:47:51.166455",
|
||||
"docstatus": 0,
|
||||
"doctype": "Workspace",
|
||||
@@ -10,7 +10,7 @@
|
||||
"idx": 0,
|
||||
"label": "ERPNext Settings",
|
||||
"links": [],
|
||||
"modified": "2021-11-05 21:32:55.323591",
|
||||
"modified": "2022-01-13 19:18:59.362820",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "ERPNext Settings",
|
||||
@@ -19,7 +19,7 @@
|
||||
"public": 1,
|
||||
"restrict_to_domain": "",
|
||||
"roles": [],
|
||||
"sequence_id": 12,
|
||||
"sequence_id": 12.0,
|
||||
"shortcuts": [
|
||||
{
|
||||
"icon": "project",
|
||||
@@ -104,13 +104,6 @@
|
||||
"restrict_to_domain": "Hospitality",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"icon": "non-profit",
|
||||
"label": "Healthcare Settings",
|
||||
"link_to": "Healthcare Settings",
|
||||
"restrict_to_domain": "Healthcare",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"icon": "setting",
|
||||
"label": "Domain Settings",
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
{
|
||||
"charts": [],
|
||||
"content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Home\",\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Your Shortcuts\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\",\"level\":4,\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Customer\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Supplier\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Leaderboard\",\"col\":4}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\",\"level\":4,\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Accounting\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Human Resources\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"CRM\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Data Import and Settings\",\"col\":4}}]",
|
||||
"content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Home\",\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts</b></span>\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Customer\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Supplier\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Leaderboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports & Masters</b></span>\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Accounting\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Human Resources\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"CRM\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Data Import and Settings\",\"col\":4}}]",
|
||||
"creation": "2020-01-23 13:46:38.833076",
|
||||
"developer_mode_only": 0,
|
||||
"disable_user_customization": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Workspace",
|
||||
"extends_another_page": 0,
|
||||
"for_user": "",
|
||||
"hide_custom": 0,
|
||||
"icon": "getting-started",
|
||||
"idx": 0,
|
||||
"is_default": 0,
|
||||
"is_standard": 0,
|
||||
"label": "Home",
|
||||
"links": [
|
||||
{
|
||||
@@ -276,18 +271,16 @@
|
||||
"type": "Link"
|
||||
}
|
||||
],
|
||||
"modified": "2021-11-22 12:50:15.771366",
|
||||
"modified": "2022-01-13 17:24:17.002665",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Home",
|
||||
"owner": "Administrator",
|
||||
"parent_page": "",
|
||||
"pin_to_bottom": 0,
|
||||
"pin_to_top": 0,
|
||||
"public": 1,
|
||||
"restrict_to_domain": "",
|
||||
"roles": [],
|
||||
"sequence_id": 1,
|
||||
"sequence_id": 1.0,
|
||||
"shortcuts": [
|
||||
{
|
||||
"label": "Item",
|
||||
|
||||
Reference in New Issue
Block a user