mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-25 16:04:46 +00:00
fix: Missing commits from hotfix branch (#17997)
* fix: merge conflict * fix: restored missing set_gst_state_and_state_number function * fix: style linting as per codacy * fix: Fixes related to customer/lead merging * fix: merge conflict * fix: Fixes related to customer/lead merging * fix: Assign isue/opportunity to user * fix: Assign isue/opportunity to user * fix: Replaced Invoice type by GST Category * fix: merge conflict * fix: merge conflict * fix: test cases * fix: test cases
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
import requests
|
||||
from plaid import Client
|
||||
from plaid.errors import APIError, ItemError
|
||||
|
||||
class PlaidConnector():
|
||||
def __init__(self, access_token=None):
|
||||
|
||||
if not(frappe.conf.get("plaid_client_id") and frappe.conf.get("plaid_secret") and frappe.conf.get("plaid_public_key")):
|
||||
frappe.throw(_("Please complete your Plaid API configuration before synchronizing your account"))
|
||||
|
||||
self.config = {
|
||||
"plaid_client_id": frappe.conf.get("plaid_client_id"),
|
||||
"plaid_secret": frappe.conf.get("plaid_secret"),
|
||||
"plaid_public_key": frappe.conf.get("plaid_public_key"),
|
||||
"plaid_env": frappe.conf.get("plaid_env")
|
||||
}
|
||||
|
||||
self.client = Client(client_id=self.config["plaid_client_id"],
|
||||
secret=self.config["plaid_secret"],
|
||||
public_key=self.config["plaid_public_key"],
|
||||
environment=self.config["plaid_env"]
|
||||
)
|
||||
|
||||
self.access_token = access_token
|
||||
|
||||
def get_access_token(self, public_token):
|
||||
if public_token is None:
|
||||
frappe.log_error(_("Public token is missing for this bank"), _("Plaid public token error"))
|
||||
|
||||
response = self.client.Item.public_token.exchange(public_token)
|
||||
access_token = response['access_token']
|
||||
|
||||
return access_token
|
||||
|
||||
def auth(self):
|
||||
try:
|
||||
self.client.Auth.get(self.access_token)
|
||||
print("Authentication successful.....")
|
||||
except ItemError as e:
|
||||
if e.code == 'ITEM_LOGIN_REQUIRED':
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
except APIError as e:
|
||||
if e.code == 'PLANNED_MAINTENANCE':
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
except requests.Timeout:
|
||||
pass
|
||||
except Exception as e:
|
||||
print(e)
|
||||
frappe.log_error(frappe.get_traceback(), _("Plaid authentication error"))
|
||||
frappe.msgprint({"title": _("Authentication Failed"), "message":e, "raise_exception":1, "indicator":'red'})
|
||||
|
||||
def get_transactions(self, start_date, end_date, account_id=None):
|
||||
try:
|
||||
self.auth()
|
||||
if account_id:
|
||||
account_ids = [account_id]
|
||||
|
||||
response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, account_ids=account_ids)
|
||||
|
||||
else:
|
||||
response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date)
|
||||
|
||||
transactions = response['transactions']
|
||||
|
||||
while len(transactions) < response['total_transactions']:
|
||||
response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, offset=len(transactions))
|
||||
transactions.extend(response['transactions'])
|
||||
return transactions
|
||||
except Exception:
|
||||
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
||||
@@ -0,0 +1,107 @@
|
||||
// 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', {
|
||||
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") {
|
||||
if (result.plaid_env == undefined || result.plaid_public_key == undefined) {
|
||||
frappe.throw(__("Please add valid Plaid api keys in site_config.json first"));
|
||||
}
|
||||
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) {
|
||||
frappe.msgprint('There was an issue loading the link-initialize.js script');
|
||||
frappe.msgprint(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(() => {
|
||||
frappe.show_alert({message:__("Bank accounts added"), indicator:'green'});
|
||||
});
|
||||
}, __("Select a company"), __("Continue"));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,161 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2018-10-25 10:02:48.656165",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "enabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Enabled",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.enabled==1",
|
||||
"fieldname": "automatic_sync",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Synchronize all accounts every hour",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:(doc.enabled==1)&&(!doc.__islocal)",
|
||||
"fieldname": "link_new_account",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Link a new bank account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-12-14 12:51:12.331395",
|
||||
"modified_by": "Administrator",
|
||||
"module": "ERPNext Integrations",
|
||||
"name": "Plaid Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import json
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
|
||||
from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_connector import PlaidConnector
|
||||
from frappe.utils import getdate, formatdate, today, add_months
|
||||
|
||||
class PlaidSettings(Document):
|
||||
pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def plaid_configuration():
|
||||
if frappe.db.get_value("Plaid Settings", None, "enabled") == "1":
|
||||
return {"plaid_public_key": frappe.conf.get("plaid_public_key") or None, "plaid_env": frappe.conf.get("plaid_env") or None, "client_name": frappe.local.site }
|
||||
else:
|
||||
return "disabled"
|
||||
|
||||
@frappe.whitelist()
|
||||
def add_institution(token, response):
|
||||
response = json.loads(response)
|
||||
|
||||
plaid = PlaidConnector()
|
||||
access_token = plaid.get_access_token(token)
|
||||
|
||||
if not frappe.db.exists("Bank", response["institution"]["name"]):
|
||||
try:
|
||||
bank = frappe.get_doc({
|
||||
"doctype": "Bank",
|
||||
"bank_name": response["institution"]["name"],
|
||||
"plaid_access_token": access_token
|
||||
})
|
||||
bank.insert()
|
||||
except Exception:
|
||||
frappe.throw(frappe.get_traceback())
|
||||
|
||||
else:
|
||||
bank = frappe.get_doc("Bank", response["institution"]["name"])
|
||||
bank.plaid_access_token = access_token
|
||||
bank.save()
|
||||
|
||||
return bank
|
||||
|
||||
@frappe.whitelist()
|
||||
def add_bank_accounts(response, bank, company):
|
||||
response = json.loads(response) if not "accounts" in response else response
|
||||
bank = json.loads(bank)
|
||||
result = []
|
||||
|
||||
default_gl_account = get_default_bank_cash_account(company, "Bank")
|
||||
if not default_gl_account:
|
||||
frappe.throw(_("Please setup a default bank account for company {0}".format(company)))
|
||||
|
||||
for account in response["accounts"]:
|
||||
acc_type = frappe.db.get_value("Account Type", account["type"])
|
||||
if not acc_type:
|
||||
add_account_type(account["type"])
|
||||
|
||||
acc_subtype = frappe.db.get_value("Account Subtype", account["subtype"])
|
||||
if not acc_subtype:
|
||||
add_account_subtype(account["subtype"])
|
||||
|
||||
if not frappe.db.exists("Bank Account", dict(integration_id=account["id"])):
|
||||
try:
|
||||
new_account = frappe.get_doc({
|
||||
"doctype": "Bank Account",
|
||||
"bank": bank["bank_name"],
|
||||
"account": default_gl_account.account,
|
||||
"account_name": account["name"],
|
||||
"account_type": account["type"] or "",
|
||||
"account_subtype": account["subtype"] or "",
|
||||
"mask": account["mask"] or "",
|
||||
"integration_id": account["id"],
|
||||
"is_company_account": 1,
|
||||
"company": company
|
||||
})
|
||||
new_account.insert()
|
||||
|
||||
result.append(new_account.name)
|
||||
|
||||
except frappe.UniqueValidationError:
|
||||
frappe.msgprint(_("Bank account {0} already exists and could not be created again").format(new_account.account_name))
|
||||
except Exception:
|
||||
frappe.throw(frappe.get_traceback())
|
||||
|
||||
else:
|
||||
result.append(frappe.db.get_value("Bank Account", dict(integration_id=account["id"]), "name"))
|
||||
|
||||
return result
|
||||
|
||||
def add_account_type(account_type):
|
||||
try:
|
||||
frappe.get_doc({
|
||||
"doctype": "Account Type",
|
||||
"account_type": account_type
|
||||
}).insert()
|
||||
except Exception:
|
||||
frappe.throw(frappe.get_traceback())
|
||||
|
||||
|
||||
def add_account_subtype(account_subtype):
|
||||
try:
|
||||
frappe.get_doc({
|
||||
"doctype": "Account Subtype",
|
||||
"account_subtype": account_subtype
|
||||
}).insert()
|
||||
except Exception:
|
||||
frappe.throw(frappe.get_traceback())
|
||||
|
||||
@frappe.whitelist()
|
||||
def sync_transactions(bank, bank_account):
|
||||
|
||||
last_sync_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
|
||||
if last_sync_date:
|
||||
start_date = formatdate(last_sync_date, "YYYY-MM-dd")
|
||||
else:
|
||||
start_date = formatdate(add_months(today(), -12), "YYYY-MM-dd")
|
||||
end_date = formatdate(today(), "YYYY-MM-dd")
|
||||
|
||||
try:
|
||||
transactions = get_transactions(bank=bank, bank_account=bank_account, start_date=start_date, end_date=end_date)
|
||||
result = []
|
||||
if transactions:
|
||||
for transaction in transactions:
|
||||
result.append(new_bank_transaction(transaction))
|
||||
|
||||
frappe.db.set_value("Bank Account", bank_account, "last_integration_date", getdate(end_date))
|
||||
|
||||
return result
|
||||
except Exception:
|
||||
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
||||
|
||||
def get_transactions(bank, bank_account=None, start_date=None, end_date=None):
|
||||
access_token = None
|
||||
|
||||
if bank_account:
|
||||
related_bank = frappe.db.get_values("Bank Account", bank_account, ["bank", "integration_id"], as_dict=True)
|
||||
access_token = frappe.db.get_value("Bank", related_bank[0].bank, "plaid_access_token")
|
||||
account_id = related_bank[0].integration_id
|
||||
|
||||
else:
|
||||
access_token = frappe.db.get_value("Bank", bank, "plaid_access_token")
|
||||
account_id = None
|
||||
|
||||
plaid = PlaidConnector(access_token)
|
||||
transactions = plaid.get_transactions(start_date=start_date, end_date=end_date, account_id=account_id)
|
||||
|
||||
return transactions
|
||||
|
||||
def new_bank_transaction(transaction):
|
||||
result = []
|
||||
|
||||
bank_account = frappe.db.get_value("Bank Account", dict(integration_id=transaction["account_id"]))
|
||||
|
||||
if float(transaction["amount"]) >= 0:
|
||||
debit = float(transaction["amount"])
|
||||
credit = 0
|
||||
else:
|
||||
debit = 0
|
||||
credit = abs(float(transaction["amount"]))
|
||||
|
||||
status = "Pending" if transaction["pending"] == "True" else "Settled"
|
||||
|
||||
if not frappe.db.exists("Bank Transaction", dict(transaction_id=transaction["transaction_id"])):
|
||||
try:
|
||||
new_transaction = frappe.get_doc({
|
||||
"doctype": "Bank Transaction",
|
||||
"date": getdate(transaction["date"]),
|
||||
"status": status,
|
||||
"bank_account": bank_account,
|
||||
"debit": debit,
|
||||
"credit": credit,
|
||||
"currency": transaction["iso_currency_code"],
|
||||
"description": transaction["name"]
|
||||
})
|
||||
new_transaction.insert()
|
||||
new_transaction.submit()
|
||||
|
||||
result.append(new_transaction.name)
|
||||
|
||||
except Exception:
|
||||
frappe.throw(frappe.get_traceback())
|
||||
|
||||
return result
|
||||
|
||||
def automatic_synchronization():
|
||||
settings = frappe.get_doc("Plaid Settings", "Plaid Settings")
|
||||
|
||||
if settings.enabled == 1 and settings.automatic_sync == 1:
|
||||
plaid_accounts = frappe.get_all("Bank Account", filter={"integration_id": ["!=", ""]}, fields=["name", "bank"])
|
||||
|
||||
for plaid_account in plaid_accounts:
|
||||
frappe.enqueue("erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions", bank=plaid_account.bank, bank_account=plaid_account.name)
|
||||
@@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Plaid Settings", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Plaid Settings
|
||||
() => frappe.tests.make('Plaid Settings', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,155 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
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, 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):
|
||||
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)
|
||||
Reference in New Issue
Block a user