Commit 715f0d94 authored by Benjamin Bouvier's avatar Benjamin Bouvier
Browse files

Rename {Accesses,Accounts}.bank to vendorId;

parent 7e3d8b08
......@@ -53,7 +53,7 @@ class BankListItemComponent extends React.Component {
<li
key={`bank-details bank-list-item-${this.props.access.id}`}
className={this.props.active ? 'active' : ''}>
<div className={`icon icon-${this.props.access.bank}`} />
<div className={`icon icon-${this.props.access.vendorId}`} />
<div className="bank-name">
<div className="clickable" onClick={this.handleClick}>
<span>{displayLabel(this.props.access)}</span>
......
......@@ -97,7 +97,7 @@ const AddOperationModal = connect(
});
let maybeWarning = null;
if (this.props.account.bank !== 'manual') {
if (this.props.account.vendorId !== 'manual') {
maybeWarning = (
<p className="alerts warning">{$t('client.addoperationmodal.warning')}</p>
);
......
......@@ -8,7 +8,7 @@ import { actions, get } from '../../store';
const Export = connect(
(state, props) => {
let access = get.accessById(state, props.account.bankAccess);
let canBeSynced = !get.bankByUuid(state, access.bank).deprecated && access.enabled;
let canBeSynced = !get.bankByUuid(state, access.vendorId).deprecated && access.enabled;
return {
canBeSynced
};
......
......@@ -70,7 +70,7 @@ export default class AccessForm extends React.Component {
key={index}
onChange={this.handleChangeCustomField}
name={field.name}
bank={bankUuid}
vendorId={bankUuid}
value={initialValue}
/>
);
......
......@@ -97,7 +97,7 @@ class CustomBankField extends React.Component {
}
const Export = connect((state, props) => {
let staticCustomFields = get.bankByUuid(state, props.bank).customFields;
let staticCustomFields = get.bankByUuid(state, props.vendorId).customFields;
let customFieldDesc = staticCustomFields.find(field => field.name === props.name);
return {
type: customFieldDesc.type,
......@@ -116,7 +116,7 @@ Export.propTypes /* remove-proptypes */ = {
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
// Bank uuid for which the custom field is set.
bank: PropTypes.string.isRequired,
vendorId: PropTypes.string.isRequired,
// A function to be called when the user changes the input. The function
// has the following signature: function(name, value)
......
......@@ -20,7 +20,7 @@ const EditAccessModal = connect(
let access = get.accessById(state, accessId);
return {
access,
staticCustomFields: get.bankByUuid(state, access.bank).customFields || []
staticCustomFields: get.bankByUuid(state, access.vendorId).customFields || []
};
},
......@@ -89,7 +89,10 @@ const EditAccessModal = connect(
render() {
let { access, staticCustomFields } = this.props;
let customFieldsComponents = this.renderCustomFields(staticCustomFields, access.bank);
let customFieldsComponents = this.renderCustomFields(
staticCustomFields,
access.vendorId
);
let body = (
<React.Fragment>
......
......@@ -90,7 +90,6 @@ ShowEditAccessModalButton.propTypes = {
export default connect(
(state, props) => {
return {
bank: get.bank,
access: get.accessById(state, props.accessId)
};
},
......
......@@ -15,27 +15,24 @@ export class Access {
constructor(arg, banks) {
this.id = assertHas(arg, 'id') && arg.id;
// The bank unique identifier to which the access is attached.
this.bank = assertHas(arg, 'bank') && arg.bank;
this.enabled = assertHas(arg, 'enabled') && arg.enabled;
this.vendorId = assertHas(arg, 'vendorId') && arg.vendorId;
this.login = assertHas(arg, 'login') && arg.login;
// Retrieve bank access' name and custom fields from the static bank information.
let staticBank = banks.find(b => b.uuid === this.bank);
assert(typeof staticBank !== 'undefined', `Unknown bank linked to access: ${this.bank}`);
this.title = staticBank.name;
this.enabled = assertHas(arg, 'enabled') && arg.enabled;
this.customLabel = (maybeHas(arg, 'customLabel') && arg.customLabel) || null;
this.isBankVendorDeprecated = staticBank.deprecated;
assert(!maybeHas(arg, 'customFields') || arg.customFields instanceof Array);
let customFields =
maybeHas(arg, 'customFields') && arg.customFields.length ? arg.customFields : [];
// Retrieve bank access' name and custom fields from the static bank information.
let staticBank = banks.find(b => b.uuid === this.vendorId);
assert(
typeof staticBank !== 'undefined',
`Unknown bank linked to access: ${this.vendorId}`
);
this.title = staticBank.name;
this.isBankVendorDeprecated = staticBank.deprecated;
this.customFields = customFields.map(field => {
let customField = staticBank.customFields.find(f => f.name === field.name);
return {
......@@ -47,6 +44,10 @@ export class Access {
// This field will be updated when accounts are attached to the access.
this.accountIds = [];
}
get bank() {
alert(`trying to get deprecated Access.bank property from ${new Error().stack}`);
}
}
export class Bank {
......@@ -65,7 +66,7 @@ export class Account {
constructor(arg, defaultCurrency) {
assert(typeof defaultCurrency === 'string', 'defaultCurrency must be a string');
this.bank = assertHas(arg, 'bank') && arg.bank;
this.vendorId = assertHas(arg, 'vendorId') && arg.vendorId;
this.bankAccess = assertHas(arg, 'bankAccess') && arg.bankAccess;
this.title = assertHas(arg, 'title') && arg.title;
this.accountNumber = assertHas(arg, 'accountNumber') && arg.accountNumber;
......@@ -91,6 +92,10 @@ export class Account {
this.outstandingSum = 0;
}
get bank() {
alert(`trying to get deprecated Account.bank property from ${new Error().stack}`);
}
static updateFrom(arg, defaultCurrency, previousAccount) {
let newAccount = new Account(arg, defaultCurrency);
......
......@@ -252,9 +252,9 @@ export function sendTestEmail(email) {
});
}
export function createAccess(bank, login, password, customFields, customLabel) {
export function createAccess(vendorId, login, password, customFields, customLabel) {
let data = {
bank,
vendorId,
login,
password,
customLabel
......
......@@ -1120,7 +1120,7 @@ function reduceCreateAccess(state, action) {
let access = {
id: results.accessId,
bank: uuid,
vendorId: uuid,
login,
customLabel,
enabled: true
......
......@@ -32,7 +32,7 @@ export async function destroy(req, res) {
try {
let { id: userId } = req.user;
let access = req.preloaded.access;
log.info(`Removing access ${access.id} for bank ${access.bank}...`);
log.info(`Removing access ${access.id} for bank ${access.vendorId}...`);
// TODO arguably, this should be done in the access model.
let accounts = await Accounts.byAccess(userId, access);
......@@ -68,8 +68,8 @@ function sanitizeCustomFields(access) {
return access;
}
// Creates a new bank access (expecting at least (bank / login / password)), and
// retrieves its accounts and operations.
// Creates a new bank access (expecting at least (vendorId / login /
// password)), and retrieves its accounts and operations.
export async function create(req, res) {
let access;
let createdAccess = false;
......@@ -80,9 +80,9 @@ export async function create(req, res) {
let params = req.body;
let error =
checkHasAllFields(params, ['bank', 'login', 'password']) ||
checkHasAllFields(params, ['vendorId', 'login', 'password']) ||
checkAllowedFields(params, [
'bank',
'vendorId',
'login',
'password',
'customFields',
......@@ -135,7 +135,7 @@ export async function fetchOperations(req, res) {
try {
let { id: userId } = req.user;
let access = req.preloaded.access;
let bankVendor = bankVendorByUuid(access.bank);
let bankVendor = bankVendorByUuid(access.vendorId);
if (!access.isEnabled() || bankVendor.deprecated) {
let errcode = getErrorCode('DISABLED_ACCESS');
......@@ -162,7 +162,7 @@ export async function fetchAccounts(req, res) {
try {
let { id: userId } = req.user;
let access = req.preloaded.access;
let bankVendor = bankVendorByUuid(access.bank);
let bankVendor = bankVendorByUuid(access.vendorId);
if (!access.isEnabled() || bankVendor.deprecated) {
let errcode = getErrorCode('DISABLED_ACCESS');
......
......@@ -66,7 +66,7 @@ for (let bank of ALL_BANKS) {
}
function handler(access) {
return BANK_HANDLERS[access.bank];
return BANK_HANDLERS[access.vendorId];
}
const MAX_DIFFERENCE_BETWEEN_DUP_DATES_IN_DAYS = 2;
......@@ -95,7 +95,7 @@ async function retrieveAllAccountsByAccess(userId, access, forceUpdate = false)
throw new KError("Access' password is not set", 500, errcode);
}
log.info(`Retrieve all accounts from access ${access.bank} with login ${access.login}`);
log.info(`Retrieve all accounts from access ${access.vendorId} with login ${access.login}`);
let isDebugEnabled = await Settings.findOrCreateDefaultBooleanValue(
userId,
......@@ -111,7 +111,7 @@ async function retrieveAllAccountsByAccess(userId, access, forceUpdate = false)
for (let accountWeboob of sourceAccounts) {
let account = {
accountNumber: accountWeboob.accountNumber,
bank: access.bank,
vendorId: access.vendorId,
bankAccess: access.id,
iban: accountWeboob.iban,
title: accountWeboob.title,
......@@ -151,7 +151,7 @@ async function notifyNewOperations(access, newOperations, accountMap) {
}
}
let bank = bankVendorByUuid(access.bank);
let bank = bankVendorByUuid(access.vendorId);
assert(bank, 'The bank must be known');
for (let [accountId, ops] of newOpsPerAccount.entries()) {
......
......@@ -3,7 +3,7 @@ import makeDiff from './diff-list';
import { SOURCE_NAME as MANUAL_BANK_NAME } from './sources/manual';
function isPerfectMatch(known, provided) {
assert(known.bank === provided.bank, 'data inconsistency');
assert(known.vendorId === provided.vendorId, 'data inconsistency');
let newTitle = known.title.replace(/ /g, '').toLowerCase();
let oldTitle = provided.title.replace(/ /g, '').toLowerCase();
return (
......@@ -36,9 +36,9 @@ function computePairScore(known, provided) {
// is identical if the access is the same and rely on the account number.
if (
oldTitle === newTitle ||
(known.bank === provided.bank &&
(known.vendorId === provided.vendorId &&
known.bankAccess === provided.bankAccess &&
known.bank === MANUAL_BANK_NAME)
known.vendorId === MANUAL_BANK_NAME)
) {
titleScore = HEURISTICS.SAME_TITLE;
}
......
......@@ -30,7 +30,7 @@ async function manageCredentialsErrors(userId, access, err) {
// are not fetched on next poll instance.
await Accesses.update(userId, access.id, { fetchStatus: err.errCode });
let bank = bankVendorByUuid(access.bank);
let bank = bankVendorByUuid(access.vendorId);
assert(bank, 'The bank must be known');
bank = access.customLabel || bank.name;
......@@ -69,12 +69,14 @@ export async function fullPoll(userId) {
let accesses = await Accesses.all(userId);
for (let access of accesses) {
try {
let { bank, login } = access;
let { vendorId, login } = access;
// Don't try to fetch accesses for deprecated modules.
let staticBank = bankVendorByUuid(bank);
let staticBank = bankVendorByUuid(vendorId);
if (!staticBank || staticBank.deprecated) {
log.info(`Won't poll, module for bank ${bank} with login ${login} is deprecated.`);
log.info(
`Won't poll, module for bank ${vendorId} with login ${login} is deprecated.`
);
continue;
}
......@@ -85,11 +87,13 @@ export async function fullPoll(userId) {
needUpdate = false;
await accountManager.retrieveOperationsByAccess(userId, access);
} else if (!access.isEnabled()) {
log.info(`Won't poll, access from bank ${bank} with login ${login} is disabled.`);
log.info(
`Won't poll, access from bank ${vendorId} with login ${login} is disabled.`
);
} else {
let error = access.fetchStatus;
log.info(
`Won't poll, access from bank ${bank} with login ${login} last fetch raised: ${error}.`
`Won't poll, access from bank ${vendorId} with login ${login} last fetch raised: ${error}.`
);
}
} catch (err) {
......
......@@ -25,7 +25,7 @@ let randomType = () => randInt(0, 10);
// Generates a map of the accounts belonging to the given access.
let hashAccount = access => {
let login = access.login;
let uuid = access.bank;
let uuid = access.vendorId;
let hash = uuid.charCodeAt(0) + login + uuid.charCodeAt(3) + uuid.charCodeAt(uuid.length - 1);
......
// This module retrieves real values from the weboob backend, by using the given
// bankuuid / login / password (maybe customFields) combination.
import { spawn } from 'child_process';
import * as path from 'path';
......@@ -31,7 +29,7 @@ const RESET_SESSION_ERRORS = [INVALID_PARAMETERS, INVALID_PASSWORD, EXPIRED_PASS
// - test: test whether weboob is accessible from the current kresus user.
// - version: get weboob's version number.
// - update: updates weboob modules.
// All the following commands require $bank $login $password $customFields:
// All the following commands require $vendorId $login $password $customFields:
// - accounts
// - operations
// To enable Weboob debug, one should pass an extra `--debug` argument.
......@@ -66,7 +64,7 @@ function callWeboob(command, access, debug = false, forceUpdate = false) {
}
if (command === 'accounts' || command === 'operations') {
weboobArgs.push('--module', access.bank, '--login', access.login);
weboobArgs.push('--module', access.vendorId, '--login', access.login);
// Pass the password via an environment variable to hide it.
env.KRESUS_WEBOOB_PWD = access.password;
......@@ -162,7 +160,7 @@ function callWeboob(command, access, debug = false, forceUpdate = false) {
SessionsMap.has(access.id)
) {
log.warn(
`Resetting session for access from bank ${access.bank} with login ${
`Resetting session for access from bank ${access.vendorId} with login ${
access.login
}`
);
......@@ -183,7 +181,9 @@ function callWeboob(command, access, debug = false, forceUpdate = false) {
if (access && stdout.session) {
log.info(
`Saving session for access from bank ${access.bank} with login ${access.login}`
`Saving session for access from bank ${access.vendorId} with login ${
access.login
}`
);
SessionsMap.set(access.id, stdout.session);
}
......
......@@ -6,7 +6,7 @@ let log = makeLogger('models/accesses');
let Access = cozydb.getModel('bankaccess', {
// External (backend) unique identifier.
bank: String,
vendorId: String,
// Credentials to connect to the bank's website.
login: String,
......@@ -34,7 +34,10 @@ let Access = cozydb.getModel('bankaccess', {
// DEPRECATED.
// ************************************************************************
website: String,
enabled: Boolean
enabled: Boolean,
// External (backend) unique identifier. Renamed to vendorId.
bank: String
});
Access = promisifyModel(Access);
......
......@@ -24,7 +24,7 @@ let Account = cozydb.getModel('bankaccount', {
// External (backend) bank module identifier, determining which source to use.
// TODO could be removed, since this is in the linked access?
bank: String,
vendorId: String,
// Id of the bankaccess instance.
bankAccess: String,
......@@ -69,7 +69,11 @@ let Account = cozydb.getModel('bankaccount', {
// DEPRECATED FIELDS
// Former name of initialBalance.
initialAmount: Number
initialAmount: Number,
// External (backend) bank module identifier, determining which source to
// use. Replaced with vendorId.
bank: String
});
Account = promisifyModel(Account);
......
......@@ -824,7 +824,13 @@ let migrations = [
},
// m24: rename Categories.title to Categories.label.
makeRenameField(Categories, 'title', 'label')
makeRenameField(Categories, 'title', 'label'),
// m25: rename Accesses.bank to Accesses.vendorId.
makeRenameField(Accesses, 'bank', 'vendorId'),
// m26: rename Accounts.bank to Accounts.vendorId.
makeRenameField(Accounts, 'bank', 'vendorId')
];
export const testing = { migrations };
......
......@@ -30,7 +30,7 @@ const dummyState = {
const dummyAccess = {
id: '1',
bank: 'fakebank1',
vendorId: 'fakebank1',
enabled: true,
login: 'login',
customFields: []
......@@ -43,7 +43,7 @@ const dummyAccount = {
lastChecked: new Date(),
initialBalance: 1000,
title: 'My Account',
bank: 'fakebank1'
vendorId: 'fakebank1'
};
const dummyAccount2 = {
......@@ -53,7 +53,7 @@ const dummyAccount2 = {
lastChecked: new Date(),
initialBalance: 500,
title: 'My Other Account',
bank: 'fakebank1'
vendorId: 'fakebank1'
};
const dummyOperation = {
......@@ -242,7 +242,7 @@ describe('Account management', () => {
accessesMap: {
'1': {
id: '1',
bank: 'fakebank1',
vendorId: 'fakebank1',
enabled: true,
login: 'login',
customFields: [],
......@@ -443,7 +443,7 @@ describe('Access management', () => {
should.deepEqual(access.customFields, []);
should.deepEqual(access.accountIds, []);
should.equal(access.id, dummyAccess.id);
should.equal(access.bank, dummyAccess.bank);
should.equal(access.vendorId, dummyAccess.vendorId);
should.equal(access.enabled, dummyAccess.enabled);
should.equal(access.login, dummyAccess.login);
});
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment