UNPKG

@accounter/server

Version:
649 lines • 24.1 kB
import { __decorate, __metadata } from "tslib"; import { Injectable, Scope } from 'graphql-modules'; import { sql } from '@pgtyped/runtime'; import { dateToTimelessDateString } from '../../../shared/helpers/index.js'; import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js'; import { AuthContextProvider } from '../../auth/providers/auth-context.provider.js'; import { formatValue } from '../helpers/utils.helper.js'; const fetchOtsarHahayalIlsByKeys = sql ` SELECT id, account_number, branch_number, date_of_registration, action_code, bfb_source, closing_balance, correspondent_account, correspondent_account_type, correspondent_bank, correspondent_branch, credit_amount, customer_name, date_of_business_day, debit_amount, depositor_id, description, drill_down_url, drill_down_data, first_transaction_of_day, last_transaction_of_day, name, opening_balance, operation_source, reference, salary_ind, transaction_source, transaction_reason, origin_reference FROM accounter_schema.otsar_hahayal_ils_account_transactions WHERE account_number = ANY($accountNumbers!) AND branch_number = ANY($branchNumbers!) AND date_of_registration = ANY($dateOfRegistrations!) `; const uploadOtsarHahayalIlsTransactions = sql ` INSERT INTO accounter_schema.otsar_hahayal_ils_account_transactions ( account_number, account_type, branch_number, action_code, bfb_source, closing_balance, correspondent_account, correspondent_account_type, correspondent_bank, correspondent_branch, credit_amount, customer_name, date_of_business_day, date_of_registration, debit_amount, depositor_id, description, drill_down_url, drill_down_data, first_transaction_of_day, last_transaction_of_day, name, opening_balance, operation_source, reference, salary_ind, transaction_source, transaction_reason, origin_reference, owner_id ) VALUES $$transactions( accountNumber, accountType, branchNumber, actionCode, bfbSource, closingBalance, correspondentAccount, correspondentAccountType, correspondentBank, correspondentBranch, creditAmount, customerName, dateOfBusinessDay, dateOfRegistration, debitAmount, depositorId, description, drillDownUrl, drillDownData, firstTransactionOfDay, lastTransactionOfDay, name, openingBalance, operationSource, reference, salaryInd, transactionSource, transactionReason, originReference, ownerId ) ON CONFLICT (account_number, branch_number, date_of_registration, date_of_business_day, reference, origin_reference, credit_amount, debit_amount) DO NOTHING RETURNING id, account_number, branch_number, date_of_registration, description, credit_amount, debit_amount; `; const fetchOtsarHahayalForeignByKeys = sql ` SELECT id, account, branch, account_type, currency, opening_balance, balance, value_date, credit, debit, description, sp, reference, date, sub_transactions FROM accounter_schema.otsar_hahayal_foreign_account_transactions WHERE account = ANY($accounts!) AND branch = ANY($branches!) AND date = ANY($dates!) AND reference = ANY($references!) `; const uploadOtsarHahayalForeignTransactions = sql ` INSERT INTO accounter_schema.otsar_hahayal_foreign_account_transactions ( account, branch, account_type, currency, opening_balance, balance, value_date, credit, debit, description, sp, reference, date, sub_transactions, owner_id ) VALUES $$transactions( account, branch, accountType, currency, openingBalance, balance, valueDate, credit, debit, description, sp, reference, date, subTransactions, ownerId ) ON CONFLICT (account, branch, date, value_date, reference, description) DO NOTHING RETURNING id, account, branch, currency, date, description, credit, debit; `; const fetchOtsarHahayalCreditCardByKeys = sql ` SELECT id, resource_id, masked_pan, card_type, billing_period, date, charge_date, name, deal_amount, charge_amount, notes, wallet_type, charge_currency, deal_currency, counter FROM accounter_schema.otsar_hahayal_creditcard_transactions WHERE resource_id = ANY($resourceIds!) AND card_type = ANY($cardTypes!) AND date = ANY($dates!) `; const uploadOtsarHahayalCreditCardTransactions = sql ` INSERT INTO accounter_schema.otsar_hahayal_creditcard_transactions ( resource_id, masked_pan, card_type, billing_period, date, charge_date, name, deal_amount, charge_amount, notes, wallet_type, charge_currency, deal_currency, counter, owner_id ) VALUES $$transactions( resourceId, maskedPan, cardType, dealGroup, date, chargeDate, name, dealAmount, chargeAmount, notes, walletType, chargeCurrency, dealCurrency, counter, ownerId ) ON CONFLICT (resource_id, card_type, date, charge_date, deal_amount, deal_currency, name, notes, counter) DO NOTHING RETURNING id, resource_id, date, name, charge_amount, charge_currency; `; const OTSAR_HAHAYAL_CREDITCARD_DIFF_FIELDS = [ { key: 'masked_pan', incoming: t => t.maskedPan }, { key: 'billing_period', incoming: t => t.dealGroup }, { key: 'charge_date', incoming: t => t.chargeDate }, { key: 'charge_amount', incoming: t => t.chargeAmount }, { key: 'wallet_type', incoming: t => t.walletType }, { key: 'charge_currency', incoming: t => t.chargeCurrency }, ]; const OTSAR_HAHAYAL_CREDITCARD_NUMERIC_FIELDS = ['deal_amount', 'charge_amount']; function diffOtsarHahayalCreditCardRow(existing, incoming) { const changed = []; for (const { key, incoming: getIncoming } of OTSAR_HAHAYAL_CREDITCARD_DIFF_FIELDS) { const isNumberField = OTSAR_HAHAYAL_CREDITCARD_NUMERIC_FIELDS.includes(key); const oldValue = formatValue(existing[key], isNumberField); const newValue = formatValue(getIncoming(incoming), isNumberField); if (oldValue !== newValue) { changed.push({ field: key, oldValue, newValue }); } } return changed; } const OTSAR_HAHAYAL_ILS_DIFF_FIELDS = [ { key: 'action_code', incoming: t => t.actionCode }, { key: 'bfb_source', incoming: t => t.bfbSource }, { key: 'closing_balance', incoming: t => t.closingBalance }, { key: 'correspondent_account', incoming: t => t.correspondentAccount }, { key: 'correspondent_account_type', incoming: t => t.correspondentAccountType }, { key: 'correspondent_bank', incoming: t => t.correspondentBank }, { key: 'correspondent_branch', incoming: t => t.correspondentBranch }, { key: 'credit_amount', incoming: t => t.creditAmount }, { key: 'customer_name', incoming: t => t.customerName }, { key: 'debit_amount', incoming: t => t.debitAmount }, { key: 'description', incoming: t => t.description }, { key: 'drill_down_url', incoming: t => t.drillDownUrl }, { key: 'first_transaction_of_day', incoming: t => t.firstTransactionOfDay }, { key: 'last_transaction_of_day', incoming: t => t.lastTransactionOfDay }, { key: 'name', incoming: t => t.name }, { key: 'opening_balance', incoming: t => t.openingBalance }, { key: 'operation_source', incoming: t => t.operationSource }, { key: 'salary_ind', incoming: t => t.salaryInd }, { key: 'transaction_source', incoming: t => t.transactionSource }, { key: 'transaction_reason', incoming: t => t.transactionReason }, ]; const OTSAR_HAHAYAL_ILS_NUMERIC_FIELDS = [ 'closing_balance', 'credit_amount', 'debit_amount', 'opening_balance', ]; function diffOtsarHahayalIlsRow(existing, incoming) { const changed = []; for (const { key, incoming: getIncoming } of OTSAR_HAHAYAL_ILS_DIFF_FIELDS) { const isNumberField = OTSAR_HAHAYAL_ILS_NUMERIC_FIELDS.includes(key); const oldValue = formatValue(existing[key], isNumberField); const newValue = formatValue(getIncoming(incoming), isNumberField); if (oldValue !== newValue) { changed.push({ field: key, oldValue, newValue }); } } return changed; } const OTSAR_HAHAYAL_FOREIGN_DIFF_FIELDS = [ { key: 'account_type', incoming: t => t.accountType }, { key: 'currency', incoming: t => t.currency }, { key: 'opening_balance', incoming: t => t.openingBalance }, { key: 'balance', incoming: t => t.balance ?? null }, { key: 'credit', incoming: t => t.credit }, { key: 'debit', incoming: t => t.debit }, { key: 'description', incoming: t => t.description }, { key: 'sp', incoming: t => t.sp ?? null }, ]; const OTSAR_HAHAYAL_FOREIGN_NUMERIC_FIELDS = [ 'opening_balance', 'balance', 'credit', 'debit', ]; function diffOtsarHahayalForeignRow(existing, incoming) { const changed = []; for (const { key, incoming: getIncoming } of OTSAR_HAHAYAL_FOREIGN_DIFF_FIELDS) { const isNumberField = OTSAR_HAHAYAL_FOREIGN_NUMERIC_FIELDS.includes(key); const oldValue = formatValue(existing[key], isNumberField); const newValue = formatValue(getIncoming(incoming), isNumberField); if (oldValue !== newValue) { changed.push({ field: key, oldValue, newValue }); } } return changed; } let OtsarHahayalScraperIngestionProvider = class OtsarHahayalScraperIngestionProvider { db; authContextProvider; businessIdCache = null; constructor(db, authContextProvider) { this.db = db; this.authContextProvider = authContextProvider; } async getBusinessId() { if (this.businessIdCache !== null) { return this.businessIdCache; } const authContext = await this.authContextProvider.getAuthContext(); this.businessIdCache = authContext?.tenant.businessId ?? null; return this.businessIdCache; } async uploadOtsarHahayalIlsTransactions(transactions) { try { if (transactions.length === 0) return { inserted: 0, skipped: 0, insertedIds: [], insertedTransactions: [], changedTransactions: [], }; const dateOfRegistrations = transactions .map(t => (t.dateOfRegistration ? new Date(t.dateOfRegistration) : null)) .filter((d) => d !== null); const accountNumbers = transactions .map(t => t.accountNumber ?? null) .filter((n) => n !== null); const branchNumbers = transactions .map(t => t.branchNumber ?? null) .filter((n) => n !== null); const existing = await fetchOtsarHahayalIlsByKeys.run({ accountNumbers, branchNumbers, dateOfRegistrations }, this.db); const existingByKey = new Map(); for (const row of existing) { const key = [ row.account_number, row.branch_number, row.date_of_registration ? dateToTimelessDateString(row.date_of_registration) : '', row.date_of_business_day ? dateToTimelessDateString(row.date_of_business_day) : '', row.reference, row.origin_reference, formatValue(row.credit_amount, true), formatValue(row.debit_amount, true), ].join('_'); existingByKey.set(key, row); } const businessId = await this.getBusinessId(); const params = transactions.map(t => ({ accountNumber: t.accountNumber, accountType: t.accountType, branchNumber: t.branchNumber, actionCode: t.actionCode, bfbSource: t.bfbSource, closingBalance: t.closingBalance, correspondentAccount: t.correspondentAccount, correspondentAccountType: t.correspondentAccountType, correspondentBank: t.correspondentBank, correspondentBranch: t.correspondentBranch, creditAmount: t.creditAmount, customerName: t.customerName, dateOfBusinessDay: t.dateOfBusinessDay, dateOfRegistration: t.dateOfRegistration, debitAmount: t.debitAmount, depositorId: t.depositorId, description: t.description, drillDownUrl: t.drillDownUrl, drillDownData: t.drillDownData ?? null, firstTransactionOfDay: t.firstTransactionOfDay, lastTransactionOfDay: t.lastTransactionOfDay, name: t.name, openingBalance: t.openingBalance, operationSource: t.operationSource, reference: t.reference, salaryInd: t.salaryInd, transactionSource: t.transactionSource, transactionReason: t.transactionReason, originReference: t.originReference ?? '', ownerId: businessId, })); const result = await uploadOtsarHahayalIlsTransactions.run({ transactions: params }, this.db); const insertedIds = result .map(r => r.id) .filter((id) => typeof id === 'string'); const insertedIdSet = new Set(insertedIds); const insertedTransactions = result.map(r => ({ id: r.id, date: r.date_of_registration ? dateToTimelessDateString(r.date_of_registration) : null, description: r.description ?? null, amount: Number(r.debit_amount) === 0 ? String(r.credit_amount) : String(-Number(r.debit_amount)), account: String(r.account_number), })); const changedTransactions = []; for (const t of transactions) { const key = [ t.accountNumber, t.branchNumber, t.dateOfRegistration ? dateToTimelessDateString(new Date(t.dateOfRegistration)) : '', t.dateOfBusinessDay ? dateToTimelessDateString(new Date(t.dateOfBusinessDay)) : '', t.reference, t.originReference ?? '', formatValue(t.creditAmount, true), formatValue(t.debitAmount, true), ].join('_'); const existingRow = existingByKey.get(key); if (existingRow && !insertedIdSet.has(existingRow.id)) { const changedFields = diffOtsarHahayalIlsRow(existingRow, t); if (changedFields.length > 0) { changedTransactions.push({ id: existingRow.id, changedFields }); } } } return { inserted: insertedIds.length, skipped: transactions.length - insertedIds.length, insertedIds, insertedTransactions, changedTransactions, }; } catch (error) { console.error('Error uploading Otsar HaHayal ILS transactions:', error); throw error; } } async uploadOtsarHahayalForeignTransactions(transactions) { try { if (transactions.length === 0) return { inserted: 0, skipped: 0, insertedIds: [], insertedTransactions: [], changedTransactions: [], }; const accounts = transactions .map(t => t.account ?? null) .filter((n) => n !== null); const branches = transactions .map(t => t.branch ?? null) .filter((n) => n !== null); const dates = transactions .map(t => (t.date ? new Date(t.date) : null)) .filter((d) => d !== null); const references = transactions .map(t => t.reference ?? null) .filter((r) => r !== null); const existing = await fetchOtsarHahayalForeignByKeys.run({ accounts, branches, dates, references }, this.db); const existingByKey = new Map(); for (const row of existing) { const key = [ row.account, row.branch, row.date ? dateToTimelessDateString(row.date) : '', row.value_date ? dateToTimelessDateString(row.value_date) : '', row.reference, row.description, ].join('_'); existingByKey.set(key, row); } const businessId = await this.getBusinessId(); const params = transactions.map(t => ({ account: t.account, branch: t.branch, accountType: t.accountType, currency: t.currency, openingBalance: t.openingBalance, balance: t.balance ?? null, valueDate: t.valueDate, credit: t.credit, debit: t.debit, description: t.description, sp: t.sp ?? null, reference: t.reference, date: t.date, subTransactions: t.subTransactions, ownerId: businessId, })); const result = await uploadOtsarHahayalForeignTransactions.run({ transactions: params }, this.db); const insertedIds = result .map(r => r.id) .filter((id) => typeof id === 'string'); const insertedIdSet = new Set(insertedIds); const insertedTransactions = result.map(r => ({ id: r.id, date: r.date ? dateToTimelessDateString(r.date) : null, description: r.description ?? null, amount: Number(r.debit) === 0 ? String(r.credit) : String(-Number(r.debit)), account: String(r.account), })); const changedTransactions = []; for (const t of transactions) { const key = [ t.account, t.branch, t.date ? dateToTimelessDateString(new Date(t.date)) : '', t.valueDate ? dateToTimelessDateString(new Date(t.valueDate)) : '', t.reference, t.description, ].join('_'); const existingRow = existingByKey.get(key); if (existingRow && !insertedIdSet.has(existingRow.id)) { const changedFields = diffOtsarHahayalForeignRow(existingRow, t); if (changedFields.length > 0) { changedTransactions.push({ id: existingRow.id, changedFields }); } } } return { inserted: insertedIds.length, skipped: transactions.length - insertedIds.length, insertedIds, insertedTransactions, changedTransactions, }; } catch (error) { console.error('Error uploading Otsar HaHayal foreign transactions:', error); throw error; } } async uploadOtsarHahayalCreditCardTransactions(transactions) { try { if (transactions.length === 0) return { inserted: 0, skipped: 0, insertedIds: [], insertedTransactions: [], changedTransactions: [], }; const resourceIds = [...new Set(transactions.map(t => t.resourceId))]; const cardTypes = [...new Set(transactions.map(t => t.cardType))]; const dates = transactions.map(t => new Date(t.date)); const existing = await fetchOtsarHahayalCreditCardByKeys.run({ resourceIds, cardTypes, dates }, this.db); const existingByKey = new Map(); for (const row of existing) { const key = [ row.resource_id, row.card_type, row.date ? dateToTimelessDateString(row.date) : '', row.charge_date ? dateToTimelessDateString(row.charge_date) : '', row.deal_amount, row.deal_currency, row.name, row.notes, row.counter, ].join('|'); existingByKey.set(key, row); } const businessId = await this.getBusinessId(); const params = transactions.map(t => ({ resourceId: t.resourceId, maskedPan: t.maskedPan, cardType: t.cardType, dealGroup: t.dealGroup, date: t.date, chargeDate: t.chargeDate, name: t.name, dealAmount: t.dealAmount, chargeAmount: t.chargeAmount, notes: t.notes, walletType: t.walletType, chargeCurrency: t.chargeCurrency, dealCurrency: t.dealCurrency, counter: t.counter, ownerId: businessId, })); const result = await uploadOtsarHahayalCreditCardTransactions.run({ transactions: params }, this.db); const insertedIds = result .map(r => r.id) .filter((id) => typeof id === 'string'); const insertedIdSet = new Set(insertedIds); const insertedTransactions = result.map(r => ({ id: r.id, date: r.date ? dateToTimelessDateString(r.date) : null, description: r.name ?? null, amount: r.charge_amount == null ? null : String(-Number(r.charge_amount)), account: r.resource_id ?? null, })); const changedTransactions = []; for (const t of transactions) { const key = [ t.resourceId, t.cardType, t.date, t.chargeDate, t.dealAmount, t.dealCurrency, t.name, t.notes, t.counter, ].join('|'); const existingRow = existingByKey.get(key); if (existingRow && !insertedIdSet.has(existingRow.id)) { const changedFields = diffOtsarHahayalCreditCardRow(existingRow, t); if (changedFields.length > 0) { changedTransactions.push({ id: existingRow.id, changedFields }); } } } return { inserted: insertedIds.length, skipped: transactions.length - insertedIds.length, insertedIds, insertedTransactions, changedTransactions, }; } catch (error) { console.error('Error uploading Otsar HaHayal credit card transactions:', error); throw error; } } }; OtsarHahayalScraperIngestionProvider = __decorate([ Injectable({ scope: Scope.Operation, global: true, }), __metadata("design:paramtypes", [TenantAwareDBClient, AuthContextProvider]) ], OtsarHahayalScraperIngestionProvider); export { OtsarHahayalScraperIngestionProvider }; //# sourceMappingURL=otsar-hahayal-scraper-ingestion.provider.js.map