UX corrections + additional tests

This commit is contained in:
Charles-Henri Decultot
2018-12-14 16:22:19 +00:00
parent 89923b84b1
commit c56f771c81
7 changed files with 294 additions and 110 deletions

View File

@@ -1,8 +1,104 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.provide("erpnext.integrations")
frappe.ui.form.on('Plaid Settings', {
connect_btn: function() {
frappe.set_route('bank-reconciliation');
link_new_account: function(frm) {
new erpnext.integrations.plaidLink(frm)
}
});
});
erpnext.integrations.plaidLink = class plaidLink {
constructor(parent) {
this.frm = parent;
this.product = ["transactions", "auth"];
this.plaidUrl = 'https://cdn.plaid.com/link/v2/stable/link-initialize.js';
this.init_config();
}
init_config() {
const me = this;
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.plaid_configuration')
.then(result => {
if (result !== "disabled") {
me.plaid_env = result.plaid_env;
me.plaid_public_key = result.plaid_public_key;
me.client_name = result.client_name;
me.init_plaid()
} else {
frappe.throw(__("Please save your document before adding a new account"))
}
})
}
init_plaid() {
const me = this;
me.loadScript(me.plaidUrl)
.then(() => {
me.onScriptLoaded(me);
})
.then(() => {
if (me.linkHandler) {
me.linkHandler.open();
}
})
.catch((error) => {
me.onScriptError(error)
})
}
loadScript(src) {
return new Promise(function (resolve, reject) {
if (document.querySelector('script[src="' + src + '"]')) {
resolve()
return
}
const el = document.createElement('script')
el.type = 'text/javascript'
el.async = true
el.src = src
el.addEventListener('load', resolve)
el.addEventListener('error', reject)
el.addEventListener('abort', reject)
document.head.appendChild(el)
})
}
onScriptLoaded(me) {
me.linkHandler = window.Plaid.create({
clientName: me.client_name,
env: me.plaid_env,
key: me.plaid_public_key,
onSuccess: me.plaid_success,
product: me.product
})
}
onScriptError(error) {
console.error('There was an issue loading the link-initialize.js script');
console.log(error);
}
plaid_success(token, response) {
const me = this;
frappe.prompt({
fieldtype:"Link",
options: "Company",
label:__("Company"),
fieldname:"company",
reqd:1
}, (data) => {
me.company = data.company;
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_institution', {token: token, response: response})
.then((result) => {
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_bank_accounts', {response: response,
bank: result, company: me.company})
})
.then((result) => {
frappe.show_alert({message:__("Bank accounts added"), indicator:'green'});
})
}, __("Select a company"), __("Continue"));
}
}

View File

@@ -86,7 +86,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:(doc.enabled==1)&&(!doc.__islocal)",
"fieldname": "connect_btn",
"fieldname": "link_new_account",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -95,7 +95,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Connect with plaid",
"label": "Link a new bank account",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -122,7 +122,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2018-12-10 16:53:23.292974",
"modified": "2018-12-14 12:51:12.331395",
"modified_by": "Administrator",
"module": "ERPNext Integrations",
"name": "Plaid Settings",

View File

@@ -48,7 +48,7 @@ def add_institution(token, response):
@frappe.whitelist()
def add_bank_accounts(response, bank, company):
response = json.loads(response)
response = json.loads(response) if not "accounts" in response else response
bank = json.loads(bank)
result = []

View File

@@ -4,6 +4,159 @@
from __future__ import unicode_literals
import unittest
import frappe
from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings import plaid_configuration, add_account_type, add_account_subtype, new_bank_transaction, get_transactions, add_bank_accounts
import json
from frappe.utils.response import json_handler
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
class TestPlaidSettings(unittest.TestCase):
pass
def setUp(self):
pass
def tearDown(self):
for bt in frappe.get_all("Bank Transaction"):
doc = frappe.get_doc("Bank Transaction", bt.name)
doc.cancel()
doc.delete()
for ba in frappe.get_all("Bank Account"):
frappe.get_doc("Bank Account", ba.name).delete()
for at in frappe.get_all("Account Type"):
frappe.get_doc("Account Type", at.name).delete()
for ast in frappe.get_all("Account Subtype"):
frappe.get_doc("Account Subtype", ast.name).delete()
def test_plaid_disabled(self):
frappe.db.set_value("Plaid Settings", None, "enabled", 0)
self.assertTrue(plaid_configuration() == "disabled")
def test_add_account_type(self):
add_account_type("brokerage")
self.assertEqual(frappe.get_doc("Account Type", "brokerage").name, "brokerage")
def test_add_account_subtype(self):
add_account_subtype("loan")
self.assertEqual(frappe.get_doc("Account Subtype", "loan").name, "loan")
def test_default_bank_account(self):
if not frappe.db.exists("Bank", "Citi"):
frappe.get_doc({
"doctype": "Bank",
"bank_name": "Citi"
}).insert()
bank_accounts = {
'account': {
'subtype': 'checking',
'mask': '0000',
'type': 'depository',
'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
'name': 'Plaid Checking'
},
'account_id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
'link_session_id': 'db673d75-61aa-442a-864f-9b3f174f3725',
'accounts': [{
'type': 'depository',
'subtype': 'checking',
'mask': '0000',
'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
'name': 'Plaid Checking'
}],
'institution': {
'institution_id': 'ins_6',
'name': 'Citi'
}
}
bank = json.dumps(frappe.get_doc("Bank", "Citi").as_dict(), default=json_handler)
company = frappe.db.get_single_value('Global Defaults', 'default_company')
frappe.db.set_value("Company", company, "default_bank_account", None)
self.assertRaises(frappe.ValidationError, add_bank_accounts, response=bank_accounts, bank=bank, company=company)
def test_new_transaction(self):
if not frappe.db.exists("Bank", "Citi"):
frappe.get_doc({
"doctype": "Bank",
"bank_name": "Citi"
}).insert()
bank_accounts = {
'account': {
'subtype': 'checking',
'mask': '0000',
'type': 'depository',
'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
'name': 'Plaid Checking'
},
'account_id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
'link_session_id': 'db673d75-61aa-442a-864f-9b3f174f3725',
'accounts': [{
'type': 'depository',
'subtype': 'checking',
'mask': '0000',
'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
'name': 'Plaid Checking'
}],
'institution': {
'institution_id': 'ins_6',
'name': 'Citi'
}
}
bank = json.dumps(frappe.get_doc("Bank", "Citi").as_dict(), default=json_handler)
company = frappe.db.get_single_value('Global Defaults', 'default_company')
if frappe.db.get_value("Company", company, "default_bank_account") is None:
frappe.db.set_value("Company", company, "default_bank_account", get_default_bank_cash_account(company, "Cash").get("account"))
add_bank_accounts(bank_accounts, bank, company)
transactions = {
'account_owner': None,
'category': ['Food and Drink', 'Restaurants'],
'account_id': 'b4Jkp1LJDZiPgojpr1ansXJrj5Q6w9fVmv6ov',
'pending_transaction_id': None,
'transaction_id': 'x374xPa7DvUewqlR5mjNIeGK8r8rl3Sn647LM',
'unofficial_currency_code': None,
'name': 'INTRST PYMNT',
'transaction_type': 'place',
'amount': -4.22,
'location': {
'city': None,
'zip': None,
'store_number': None,
'lon': None,
'state': None,
'address': None,
'lat': None
},
'payment_meta': {
'reference_number': None,
'payer': None,
'payment_method': None,
'reason': None,
'payee': None,
'ppd_id': None,
'payment_processor': None,
'by_order_of': None
},
'date': '2017-12-22',
'category_id': '13005000',
'pending': False,
'iso_currency_code': 'USD'
}
new_bank_transaction(transactions)
self.assertTrue(len(frappe.get_all("Bank Transaction")) == 1)