UNPKG

@railzai/railz-visualizations

Version:
331 lines (325 loc) 20.4 kB
/*! * 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