@railzai/railz-visualizations
Version:
Railz.ai Visualizations
331 lines (325 loc) • 20.4 kB
JavaScript
/*!
* Accounting Data as a Service™ is the solution that makes sense of your business customers' financial data.
* Built with Stencil
* Copyright (c) FIS.
*/
import { h, proxyCustomElement, HTMLElement } from '@stencil/core/internal/client';
import { T as Translations } from './en.js';
import { j as format, l as parseISO, m as RAILZ_DATE_FORMAT, e as errorLog, p as pick, R as RequestServiceInstance, g as getConfiguration, C as ConfigurationInstance, a as getFilter, b as getOptions, v as validateRequiredParams, n as isBankReconciliation, o as handleError, q as getBankReconciliationOptionsStyle, r as isNil, s as formatCurrencyValue } from './chart.utils.js';
import { g as RVReportTypesUrlMapping } from './financial-ratios.js';
import { d as defineCustomElement$4 } from './error-image.js';
import { d as defineCustomElement$3 } from './gauge-chart.js';
import { d as defineCustomElement$2 } from './progress-bar.js';
import { d as defineCustomElement$1 } from './tooltip.js';
import { i as isEqual } from './isEqual.js';
import { i as isEmpty } from './isEmpty.js';
/* eslint-disable @typescript-eslint/no-unused-vars */
const CheckCircleIcon = () => {
return (h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
h("path", { d: "M8 0C3.584 0 0 3.584 0 8C0 12.416 3.584 16 8 16C12.416 16 16 12.416 16 8C16 3.584 12.416 0 8 0ZM6.4 12L2.4 8L3.528 6.872L6.4 9.736L12.472 3.664L13.6 4.8L6.4 12Z", fill: "#30A665" })));
};
const ErrorIcon = () => {
return (h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
h("path", { d: "M8 0C3.584 0 0 3.584 0 8C0 12.416 3.584 16 8 16C12.416 16 16 12.416 16 8C16 3.584 12.416 0 8 0ZM8.8 12H7.2V10.4H8.8V12ZM8.8 8.8H7.2V4H8.8V8.8Z", fill: "#F2A74C" })));
};
const formatReconciliatedData = (data) => {
let matchedItems = 0;
let unmatchedItems = 0;
let bankTransactionsValue = 0;
let accountingTransactionsValue = 0;
let reconciledTransactionsAbsValue = 0;
if (data === null || data === void 0 ? void 0 : data.reports) {
for (const reportItem of data.reports) {
for (const dataItem of reportItem.data) {
bankTransactionsValue += dataItem.bankTransactionsTotalValue
? dataItem.bankTransactionsTotalValue
: 0;
accountingTransactionsValue += dataItem.accountingTransactionsTotalValue
? dataItem.accountingTransactionsTotalValue
: 0;
if (dataItem['unreconciledBankTransactions']) {
unmatchedItems += dataItem['unreconciledBankTransactions'].length;
}
if (dataItem['reconciledBankTransactions']) {
for (const transaction of dataItem['reconciledBankTransactions']) {
matchedItems++;
reconciledTransactionsAbsValue += Math.abs(transaction.amount);
}
}
}
}
}
return {
accuracyScore: Math.round((reconciledTransactionsAbsValue / bankTransactionsValue) * 100),
bankBalance: bankTransactionsValue,
accountingBalance: accountingTransactionsValue,
matchedTransactions: matchedItems,
totalTransations: unmatchedItems + matchedItems,
};
};
/**
* Make API call based on expected parameters for score data type
*/
const getReportData = async ({ filter, }) => {
let reportData;
try {
let startDate;
let endDate;
try {
startDate = format(parseISO(filter.startDate), RAILZ_DATE_FORMAT);
}
catch (error) {
errorLog(Translations.RV_ERROR_START_DATE);
}
try {
endDate = format(parseISO(filter.endDate), RAILZ_DATE_FORMAT);
}
catch (error) {
errorLog(Translations.RV_ERROR_END_DATE);
}
const allParameters = pick(Object.assign(Object.assign({}, filter), { startDate, endDate }), [
'startDate',
'endDate',
'connectionUuid',
]);
allParameters.offset = 0;
allParameters.limit = 100;
allParameters.orderBy = '-date';
reportData = await RequestServiceInstance.getReportData({
path: RVReportTypesUrlMapping[filter.reportType],
filter: allParameters,
});
}
catch (error) {
errorLog(Translations.RV_NOT_ABLE_TO_RETRIEVE_REPORT_DATA, error);
reportData = { error };
}
return reportData;
};
const bankReconciliationCss = "@font-face{font-family:Inter;src:url(\"../assets/fonts/Inter-italic-var.woff2\");font-family:Inter;src:url(\"../assets/fonts/Inter-upright-var.woff2\")}body,div[class^=railz-],div[class*=\" railz-\"]{font-family:Inter, Roboto, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}.rv-container{display:flex;gap:24px;position:relative;flex-direction:row}@media screen and (max-width: 600px){.rv-container{flex-direction:column}}.rv-container p{margin-block:0}.rv-container *{font-family:Inter, Roboto, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}.rv-grid{padding:16px;min-height:102px;box-shadow:0 2px 1px -1px rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 3px 0 rgba(0, 0, 0, 0.12);border-radius:4px;display:flex;flex-direction:column;gap:24px;width:100%}@media screen and (max-width: 600px){.rv-grid{width:\"auto\"}}.rv-grid-accuracy-score{padding:16px;min-height:102px;box-shadow:0 2px 1px -1px rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 3px 0 rgba(0, 0, 0, 0.12);border-radius:4px;display:flex;flex-direction:column;gap:24px;width:100%;max-width:264px}@media screen and (max-width: 600px){.rv-grid-accuracy-score{max-width:100%}}.rv-title{font-size:18px;font-weight:600;color:#616161;line-height:1.235}.rv-subtitle{font-size:12px;font-weight:500;overflow-wrap:break-word;color:rgba(0, 0, 0, 0.87);line-height:1.235}.rv-section-container{display:flex;flex-direction:row;align-items:center;gap:16px}.rv-matched-insight-section-container{align-items:unset}@media screen and (max-width: 600px){.rv-matched-insight-section-container{flex-direction:column}}.rv-section-child-container{display:flex;flex-direction:column;justify-content:space-between;text-align:center;gap:8px;width:calc(100% + 8px);margin:-4px}.rv-bar-text{font-size:12px;font-weight:500;color:rgba(0, 0, 0, 0.87);text-align:center}.rv-section-item{padding:4px;width:100%;max-width:100%}.rv-section-number{font-size:18px;font-weight:600;flex:1}.rv-section-equals{margin-top:-8px;align-self:center}.rv-section-number-icon{font-size:18px;font-weight:600;flex:0}.rv-section-icon{flex:1;gap:8px;display:flex;flex-direction:row;justify-content:center}.rv-icon{margin-top:4px}@media screen and (max-width: 900px){.rv-icon{display:none}}.rv-matched-insight-subtitle{font-weight:600;letter-spacing:0.06em;color:#616161;text-transform:uppercase}@media screen and (max-width: 600px){.rv-matched-insight-subtitle{text-align:center;margin-left:0}}";
const BankReconciliation = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
constructor() {
super();
this.__registerHost();
this.__attachShadow();
this.loading = '';
this.updateBankReconciliationParams = (summary) => {
const params = formatReconciliatedData(summary);
if (params) {
this.loading = '';
this.accuracyScore = params.accuracyScore;
this.bankBalance = params.bankBalance;
this.accountingBalance = params.accountingBalance;
this.matchedTransactions = params.matchedTransactions;
this.totalTransations = params.totalTransations;
}
};
/**
* Validates if configuration was passed correctly before setting filter
* @param configuration - Config for authentication
* @param filter - filter to decide chart type to show
* @param options: Whitelabeling options
* @param triggerRequest - indicate if api request should be made
*/
this.validateParams = async (configuration, filter, options, triggerRequest = true) => {
this._configuration = getConfiguration(configuration);
if (this._configuration) {
ConfigurationInstance.configuration = this._configuration;
try {
this._filter = getFilter(filter);
this._options = getOptions(options);
if (validateRequiredParams(this._filter)) {
if (isBankReconciliation(this._filter.reportType)) {
if (triggerRequest) {
await this.requestReportData();
}
}
else {
this.errorStatusCode = 500;
errorLog(Translations.RV_ERROR_INVALID_REPORT_TYPE);
}
}
else {
this.errorStatusCode = 204;
}
}
catch (e) {
this.errorStatusCode = 500;
errorLog(e);
}
}
else {
this.errorStatusCode = 0;
}
};
this.propsUpdated = async (triggerRequest = true) => {
await this.validateParams(this.configuration, this.filter, this.options, triggerRequest);
};
/**
* Request report data based on filter and configuration param
* Formats retrieved data into Highcharts format using formatData
*/
this.requestReportData = async () => {
var _a;
this.errorStatusCode = undefined;
this.loading = Translations.RV_LOADING_REPORT;
try {
const reportData = (await getReportData({
filter: this._filter,
}));
if (reportData === null || reportData === void 0 ? void 0 : reportData.reports) {
this.updateBankReconciliationParams(reportData);
}
else if (((_a = reportData === null || reportData === void 0 ? void 0 : reportData.error) === null || _a === void 0 ? void 0 : _a.message[0]) === 'Business has no bank data') {
errorLog(Translations.RV_ERROR_422_TITLE);
this.errorStatusCode = 422;
}
else {
this.errorStatusCode = handleError(reportData);
}
}
catch (error) {
errorLog(Translations.RV_NOT_ABLE_TO_PARSE_REPORT_DATA, error);
}
finally {
this.loading = '';
}
};
}
async watchConfiguration(newValue, oldValue) {
if (newValue && oldValue && !isEqual(oldValue, newValue)) {
await this.validateParams(newValue, this.filter, this.options);
}
}
async watchFilter(newValue, oldValue) {
if (newValue && oldValue && !isEqual(oldValue, newValue)) {
await this.validateParams(this.configuration, newValue, this.options);
}
}
async watchOptions(newValue, oldValue) {
if (newValue && oldValue && !isEqual(oldValue, newValue)) {
await this.validateParams(this.configuration, this.filter, newValue);
}
}
componentWillLoad() {
this._options = getBankReconciliationOptionsStyle(this.options);
this.propsUpdated && this.propsUpdated();
}
render() {
var _a, _b, _c;
if (this.errorStatusCode !== undefined) {
return (h("railz-error-image", Object.assign({ statusCode: this.errorStatusCode || 500 }, (_a = this._options) === null || _a === void 0 ? void 0 : _a.errorIndicator)));
}
if (isNil(this.accuracyScore) ||
isNil(this.bankBalance) ||
isNil(this.accountingBalance) ||
isNil(this.matchedTransactions) ||
isNil(this.totalTransations) ||
!isEmpty(this.loading)) {
return h("span", null);
}
const getColor = (score) => {
if (score < 50) {
return '#FFD738';
}
if (score < 75) {
return '#009BBD';
}
return '#00884F';
};
const getData = (score) => {
return [score];
};
const accuracyScoreChartOptions = {
chart: {
height: '64px',
width: '64px',
type: 'circle',
gauge: {
startAngle: 0,
endAngle: 360,
size: '100%',
innerRadius: '80%',
getColor: getColor,
getData: getData,
maxScore: 100,
},
},
};
const AccuracyScore = () => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
return (h("div", { class: "rv-grid-accuracy-score", style: (_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.reconciliation) === null || _b === void 0 ? void 0 : _b.gridAccuracyScore }, h("div", { class: "rv-section-container", style: (_d = (_c = this._options) === null || _c === void 0 ? void 0 : _c.reconciliation) === null || _d === void 0 ? void 0 : _d.sectionContainer }, h("p", { class: "rv-title", style: (_f = (_e = this._options) === null || _e === void 0 ? void 0 : _e.reconciliation) === null || _f === void 0 ? void 0 : _f.title }, Translations.RV_BANK_RECONCILIATION_ACCURACY_SCORE), h("railz-tooltip", { tooltipStyle: Object.assign(Object.assign({ position: 'bottom-center' }, (_g = this._options) === null || _g === void 0 ? void 0 : _g.tooltipIndicator), { style: Object.assign({ marginLeft: '5px' }, (_j = (_h = this._options) === null || _h === void 0 ? void 0 : _h.tooltipIndicator) === null || _j === void 0 ? void 0 : _j.style) }), tooltipText: ((_o = (_m = (_l = (_k = this._options) === null || _k === void 0 ? void 0 : _k.reconciliation) === null || _l === void 0 ? void 0 : _l.accuracyScoreContent) === null || _m === void 0 ? void 0 : _m.tooltip) === null || _o === void 0 ? void 0 : _o.description) ||
Translations[`RV_TOOLTIP_ACCURACY_SCORE`] })), h("div", { class: "rv-section-container", style: (_q = (_p = this._options) === null || _p === void 0 ? void 0 : _p.reconciliation) === null || _q === void 0 ? void 0 : _q.sectionContainer }, h("railz-gauge-chart", { options: accuracyScoreChartOptions, data: {
score: this.accuracyScore,
rating: '',
lastUpdated: '',
percentage: true,
} }), h("p", { class: "rv-subtitle", style: (_s = (_r = this._options) === null || _r === void 0 ? void 0 : _r.reconciliation) === null || _s === void 0 ? void 0 : _s.subtitle }, Translations.RV_BANK_RECONCILIATION_ACCURACY_SCORE_TRANSACTIONS))));
};
const diff = Math.abs(this.accountingBalance - this.bankBalance);
const MatchedInsight = () => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9;
return (h("div", { class: "rv-grid", style: (_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.reconciliation) === null || _b === void 0 ? void 0 : _b.grid }, h("p", { class: "rv-title", style: (_d = (_c = this._options) === null || _c === void 0 ? void 0 : _c.reconciliation) === null || _d === void 0 ? void 0 : _d.title }, Translations.RV_BANK_RECONCILIATION_MATCHED_INSIGHTS), h("div", { class: "rv-section-container rv-matched-insight-section-container", style: (_f = (_e = this._options) === null || _e === void 0 ? void 0 : _e.reconciliation) === null || _f === void 0 ? void 0 : _f.sectionParentContainer }, h("div", { class: "rv-section-child-container", style: (_h = (_g = this._options) === null || _g === void 0 ? void 0 : _g.reconciliation) === null || _h === void 0 ? void 0 : _h.sectionChildContainer }, h("p", { class: "rv-subtitle rv-matched-insight-subtitle", style: (_k = (_j = this.options) === null || _j === void 0 ? void 0 : _j.reconciliation) === null || _k === void 0 ? void 0 : _k.subtitle }, Translations.RV_BANK_RECONCILIATION_MATCHED_INSIGHTS_SUBHEADING), h("div", { class: "rv-section-item" }, h("railz-progress-bar", { paidAmount: this.matchedTransactions, overdueAmount: 0, unpaidAmount: this.totalTransations - this.matchedTransactions, options: {
hideLabels: true,
} })), h("p", { class: "rv-bar-text", style: (_m = (_l = this.options) === null || _l === void 0 ? void 0 : _l.reconciliation) === null || _m === void 0 ? void 0 : _m.subtitle }, `${(_o = this.matchedTransactions) === null || _o === void 0 ? void 0 : _o.toString()}
${Translations.RV_BANK_RECONCILIATION_MATCHED_INSIGHTS_OF}
${(_p = this.totalTransations) === null || _p === void 0 ? void 0 : _p.toString()}`)), h("div", { class: "rv-section-child-container", style: (_r = (_q = this._options) === null || _q === void 0 ? void 0 : _q.reconciliation) === null || _r === void 0 ? void 0 : _r.sectionChildContainer }, h("p", { class: "rv-subtitle rv-matched-insight-subtitle", style: (_t = (_s = this.options) === null || _s === void 0 ? void 0 : _s.reconciliation) === null || _t === void 0 ? void 0 : _t.subtitle }, Translations.RV_BANK_RECONCILIATION_MATCHED_INSIGHTS_ACCOUNTING_BALANCE), h("p", { class: "rv-section-number", style: (_v = (_u = this.options) === null || _u === void 0 ? void 0 : _u.reconciliation) === null || _v === void 0 ? void 0 : _v.sectionNumber }, formatCurrencyValue(this.accountingBalance))), h("div", { class: "rv-section-child-container", style: (_x = (_w = this._options) === null || _w === void 0 ? void 0 : _w.reconciliation) === null || _x === void 0 ? void 0 : _x.sectionChildContainer }, h("p", { class: "rv-subtitle rv-matched-insight-subtitle", style: (_z = (_y = this.options) === null || _y === void 0 ? void 0 : _y.reconciliation) === null || _z === void 0 ? void 0 : _z.subtitle }, Translations.RV_BANK_RECONCILIATION_MATCHED_INSIGHTS_BANK_BALANCE), h("p", { class: "rv-section-number", style: (_1 = (_0 = this._options) === null || _0 === void 0 ? void 0 : _0.reconciliation) === null || _1 === void 0 ? void 0 : _1.sectionNumber }, formatCurrencyValue(this.bankBalance))), h("p", { class: "rv-section-number rv-section-equals", style: (_3 = (_2 = this._options) === null || _2 === void 0 ? void 0 : _2.reconciliation) === null || _3 === void 0 ? void 0 : _3.sectionNumber }, '='), h("div", { class: "rv-section-child-container", style: (_5 = (_4 = this._options) === null || _4 === void 0 ? void 0 : _4.reconciliation) === null || _5 === void 0 ? void 0 : _5.sectionChildContainer }, h("p", { class: "rv-subtitle rv-matched-insight-subtitle", style: (_7 = (_6 = this._options) === null || _6 === void 0 ? void 0 : _6.reconciliation) === null || _7 === void 0 ? void 0 : _7.subtitle }, Translations.RV_BANK_RECONCILIATION_MATCHED_INSIGHTS_CALCULATION), h("div", { class: "rv-section-icon" }, h("div", { class: "rv-icon" }, diff !== 0 ? h(ErrorIcon, null) : h(CheckCircleIcon, null)), h("p", { class: "rv-section-number rv-section-number-icon", style: (_9 = (_8 = this._options) === null || _8 === void 0 ? void 0 : _8.reconciliation) === null || _9 === void 0 ? void 0 : _9.sectionNumber }, formatCurrencyValue(diff)))))));
};
return (h("div", { class: "rv-container", style: (_c = (_b = this._options) === null || _b === void 0 ? void 0 : _b.container) === null || _c === void 0 ? void 0 : _c.style }, h(AccuracyScore, null), h(MatchedInsight, null)));
}
static get watchers() { return {
"configuration": ["watchConfiguration"],
"filter": ["watchFilter"],
"options": ["watchOptions"]
}; }
static get style() { return bankReconciliationCss; }
}, [1, "railz-bank-reconciliation", {
"configuration": [16],
"filter": [16],
"options": [16],
"_options": [32],
"loading": [32],
"_configuration": [32],
"_filter": [32],
"errorStatusCode": [32],
"accuracyScore": [32],
"bankBalance": [32],
"accountingBalance": [32],
"matchedTransactions": [32],
"totalTransations": [32]
}]);
function defineCustomElement() {
if (typeof customElements === "undefined") {
return;
}
const components = ["railz-bank-reconciliation", "railz-error-image", "railz-gauge-chart", "railz-progress-bar", "railz-tooltip"];
components.forEach(tagName => { switch (tagName) {
case "railz-bank-reconciliation":
if (!customElements.get(tagName)) {
customElements.define(tagName, BankReconciliation);
}
break;
case "railz-error-image":
if (!customElements.get(tagName)) {
defineCustomElement$4();
}
break;
case "railz-gauge-chart":
if (!customElements.get(tagName)) {
defineCustomElement$3();
}
break;
case "railz-progress-bar":
if (!customElements.get(tagName)) {
defineCustomElement$2();
}
break;
case "railz-tooltip":
if (!customElements.get(tagName)) {
defineCustomElement$1();
}
break;
} });
}
export { BankReconciliation as B, defineCustomElement as d };
//# sourceMappingURL=bank-reconciliation.js.map