fix(plaid): cannot reset plaid link for a bank account
This commit is contained in:
parent
17736afab5
commit
d24eccd623
@ -25,6 +25,10 @@ frappe.ui.form.on('Bank', {
|
|||||||
frm.add_custom_button(__('Refresh Plaid Link'), () => {
|
frm.add_custom_button(__('Refresh Plaid Link'), () => {
|
||||||
new erpnext.integrations.refreshPlaidLink(frm.doc.plaid_access_token);
|
new erpnext.integrations.refreshPlaidLink(frm.doc.plaid_access_token);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.add_custom_button(__('Reset Plaid Link'), () => {
|
||||||
|
new erpnext.integrations.plaidLink(frm);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -121,3 +125,101 @@ erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
|
|||||||
frappe.show_alert({ message: __('Plaid Link Updated'), indicator: 'green' });
|
frappe.show_alert({ message: __('Plaid Link Updated'), indicator: 'green' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
erpnext.integrations.plaidLink = class plaidLink {
|
||||||
|
constructor(parent) {
|
||||||
|
this.frm = parent;
|
||||||
|
this.plaidUrl = 'https://cdn.plaid.com/link/v2/stable/link-initialize.js';
|
||||||
|
this.init_config();
|
||||||
|
}
|
||||||
|
|
||||||
|
async init_config() {
|
||||||
|
this.product = ["auth", "transactions"];
|
||||||
|
this.plaid_env = this.frm.doc.plaid_env;
|
||||||
|
this.client_name = frappe.boot.sitename;
|
||||||
|
this.token = await this.get_link_token();
|
||||||
|
this.init_plaid();
|
||||||
|
}
|
||||||
|
|
||||||
|
async get_link_token() {
|
||||||
|
const token = await this.frm.call("get_link_token").then(resp => resp.message);
|
||||||
|
if (!token) {
|
||||||
|
frappe.throw(__('Cannot retrieve link token. Check Error Log for more information'));
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = Plaid.create({
|
||||||
|
clientName: me.client_name,
|
||||||
|
product: me.product,
|
||||||
|
env: me.plaid_env,
|
||||||
|
token: me.token,
|
||||||
|
onSuccess: me.plaid_success
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onScriptError(error) {
|
||||||
|
frappe.msgprint(__("There was an issue connecting to Plaid's authentication server. Check browser console for more information"));
|
||||||
|
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(() => {
|
||||||
|
frappe.show_alert({ message: __("Bank accounts added"), indicator: 'green' });
|
||||||
|
});
|
||||||
|
}, __("Select a company"), __("Continue"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -99,5 +99,7 @@ class PlaidConnector():
|
|||||||
response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, offset=len(transactions))
|
response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, offset=len(transactions))
|
||||||
transactions.extend(response["transactions"])
|
transactions.extend(response["transactions"])
|
||||||
return transactions
|
return transactions
|
||||||
|
except ItemError as e:
|
||||||
|
raise e
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
||||||
|
@ -12,6 +12,7 @@ from frappe.desk.doctype.tag.tag import add_tag
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import add_months, formatdate, getdate, today
|
from frappe.utils import add_months, formatdate, getdate, today
|
||||||
|
|
||||||
|
from plaid.errors import ItemError
|
||||||
|
|
||||||
class PlaidSettings(Document):
|
class PlaidSettings(Document):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -51,7 +52,7 @@ def add_institution(token, response):
|
|||||||
})
|
})
|
||||||
bank.insert()
|
bank.insert()
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.throw(frappe.get_traceback())
|
frappe.log_error(frappe.get_traceback(), title=_('Plaid Link Error'))
|
||||||
else:
|
else:
|
||||||
bank = frappe.get_doc("Bank", response["institution"]["name"])
|
bank = frappe.get_doc("Bank", response["institution"]["name"])
|
||||||
bank.plaid_access_token = access_token
|
bank.plaid_access_token = access_token
|
||||||
@ -83,7 +84,12 @@ def add_bank_accounts(response, bank, company):
|
|||||||
if not acc_subtype:
|
if not acc_subtype:
|
||||||
add_account_subtype(account["subtype"])
|
add_account_subtype(account["subtype"])
|
||||||
|
|
||||||
if not frappe.db.exists("Bank Account", dict(integration_id=account["id"])):
|
existing_bank_account = frappe.db.exists("Bank Account", {
|
||||||
|
'account_name': account["name"],
|
||||||
|
'bank': bank["bank_name"]
|
||||||
|
})
|
||||||
|
|
||||||
|
if not existing_bank_account:
|
||||||
try:
|
try:
|
||||||
new_account = frappe.get_doc({
|
new_account = frappe.get_doc({
|
||||||
"doctype": "Bank Account",
|
"doctype": "Bank Account",
|
||||||
@ -103,10 +109,27 @@ def add_bank_accounts(response, bank, company):
|
|||||||
except frappe.UniqueValidationError:
|
except frappe.UniqueValidationError:
|
||||||
frappe.msgprint(_("Bank account {0} already exists and could not be created again").format(account["name"]))
|
frappe.msgprint(_("Bank account {0} already exists and could not be created again").format(account["name"]))
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.throw(frappe.get_traceback())
|
frappe.log_error(frappe.get_traceback(), title=_("Plaid Link Error"))
|
||||||
|
frappe.throw(_("There was an error creating Bank Account while linking with Plaid."),
|
||||||
|
title=_("Plaid Link Failed"))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
result.append(frappe.db.get_value("Bank Account", dict(integration_id=account["id"]), "name"))
|
try:
|
||||||
|
existing_account = frappe.get_doc('Bank Account', existing_bank_account)
|
||||||
|
existing_account.update({
|
||||||
|
"bank": bank["bank_name"],
|
||||||
|
"account_name": account["name"],
|
||||||
|
"account_type": account.get("type", ""),
|
||||||
|
"account_subtype": account.get("subtype", ""),
|
||||||
|
"mask": account.get("mask", ""),
|
||||||
|
"integration_id": account["id"]
|
||||||
|
})
|
||||||
|
existing_account.save()
|
||||||
|
result.append(existing_bank_account)
|
||||||
|
except Exception:
|
||||||
|
frappe.log_error(frappe.get_traceback(), title=_("Plaid Link Error"))
|
||||||
|
frappe.throw(_("There was an error updating Bank Account {} while linking with Plaid.").format(
|
||||||
|
existing_bank_account), title=_("Plaid Link Failed"))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -172,9 +195,16 @@ def get_transactions(bank, bank_account=None, start_date=None, end_date=None):
|
|||||||
account_id = None
|
account_id = None
|
||||||
|
|
||||||
plaid = PlaidConnector(access_token)
|
plaid = PlaidConnector(access_token)
|
||||||
transactions = plaid.get_transactions(start_date=start_date, end_date=end_date, account_id=account_id)
|
|
||||||
|
|
||||||
return transactions
|
try:
|
||||||
|
transactions = plaid.get_transactions(start_date=start_date, end_date=end_date, account_id=account_id)
|
||||||
|
except ItemError as e:
|
||||||
|
if e.code == "ITEM_LOGIN_REQUIRED":
|
||||||
|
msg = _("There was an error syncing transactions.") + " "
|
||||||
|
msg += _("Please refresh or reset the Plaid linking of the Bank {}.").format(bank) + " "
|
||||||
|
frappe.log_error(msg, title=_("Plaid Link Refresh Required"))
|
||||||
|
|
||||||
|
return transactions or []
|
||||||
|
|
||||||
|
|
||||||
def new_bank_transaction(transaction):
|
def new_bank_transaction(transaction):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user