@accounter/server
Version:
Accounter GraphQL server
557 lines • 17.7 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Injectable, Scope } from 'graphql-modules';
import { sql } from '@pgtyped/runtime';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
import { formatValue } from '../helpers/utils.helper.js';
import { validateIsracardAmexTransactions } from '../helpers/validators.helper.js';
const fetchIsracardByCards = sql `
SELECT
id,
card,
specific_date,
card_index,
deals_inbound,
supplier_id,
supplier_name,
deal_sum_type,
payment_sum_sign,
purchase_date,
full_purchase_date,
more_info,
horaat_keva,
voucher_number,
voucher_number_ratz,
solek,
purchase_date_outbound,
full_purchase_date_outbound,
currency_id,
current_payment_currency,
city,
supplier_name_outbound,
full_supplier_name_outbound,
payment_date,
full_payment_date,
is_show_deals_outbound,
adendum,
voucher_number_ratz_outbound,
is_show_link_for_supplier_details,
deal_sum,
payment_sum,
full_supplier_name_heb,
deal_sum_outbound,
payment_sum_outbound,
is_horaat_keva,
stage,
return_code,
message,
return_message,
display_properties,
table_page_num,
is_error,
is_captcha,
is_button,
site_name,
kod_matbea_mekori,
esb_services_call
FROM accounter_schema.isracard_creditcard_transactions
WHERE card = ANY($cards!)
`;
const uploadIsracardTransactions = sql `
INSERT INTO accounter_schema.isracard_creditcard_transactions (
specific_date,
card_index,
deals_inbound,
supplier_id,
supplier_name,
deal_sum_type,
payment_sum_sign,
purchase_date,
full_purchase_date,
more_info,
horaat_keva,
voucher_number,
voucher_number_ratz,
solek,
purchase_date_outbound,
full_purchase_date_outbound,
currency_id,
current_payment_currency,
city,
supplier_name_outbound,
full_supplier_name_outbound,
payment_date,
full_payment_date,
is_show_deals_outbound,
adendum,
voucher_number_ratz_outbound,
is_show_link_for_supplier_details,
deal_sum,
payment_sum,
full_supplier_name_heb,
deal_sum_outbound,
payment_sum_outbound,
is_horaat_keva,
stage,
return_code,
message,
return_message,
display_properties,
table_page_num,
is_error,
is_captcha,
is_button,
site_name,
client_ip_address,
card,
charging_date,
kod_matbea_mekori,
esb_services_call
)
VALUES $$transactions(
specificDate,
cardIndex,
dealsInbound,
supplierId,
supplierName,
dealSumType,
paymentSumSign,
purchaseDate,
fullPurchaseDate,
moreInfo,
horaatKeva,
voucherNumber,
voucherNumberRatz,
solek,
purchaseDateOutbound,
fullPurchaseDateOutbound,
currencyId,
currentPaymentCurrency,
city,
supplierNameOutbound,
fullSupplierNameOutbound,
paymentDate,
fullPaymentDate,
isShowDealsOutbound,
adendum,
voucherNumberRatzOutbound,
isShowLinkForSupplierDetails,
dealSum,
paymentSum,
fullSupplierNameHeb,
dealSumOutbound,
paymentSumOutbound,
isHoraatKeva,
stage,
returnCode,
message,
returnMessage,
displayProperties,
tablePageNum,
isError,
isCaptcha,
isButton,
siteName,
clientIpAddress,
card,
chargingDate,
kodMatbeaMekori,
esbServicesCall
)
ON CONFLICT (
card,
COALESCE(full_purchase_date, full_purchase_date_outbound),
full_payment_date,
COALESCE(payment_sum, payment_sum_outbound),
voucher_number,
COALESCE(voucher_number_ratz, voucher_number_ratz_outbound),
supplier_id,
current_payment_currency,
COALESCE(full_supplier_name_heb, full_supplier_name_outbound),
more_info,
deal_sum
)
DO NOTHING
RETURNING id, full_purchase_date, supplier_name, payment_sum, card;
`;
const fetchAmexByCards = sql `
SELECT
id,
card,
specific_date,
card_index,
deals_inbound,
supplier_id,
supplier_name,
deal_sum_type,
payment_sum_sign,
purchase_date,
full_purchase_date,
more_info,
horaat_keva,
voucher_number,
voucher_number_ratz,
solek,
purchase_date_outbound,
full_purchase_date_outbound,
currency_id,
current_payment_currency,
city,
supplier_name_outbound,
full_supplier_name_outbound,
payment_date,
full_payment_date,
is_show_deals_outbound,
adendum,
voucher_number_ratz_outbound,
is_show_link_for_supplier_details,
deal_sum,
payment_sum,
full_supplier_name_heb,
deal_sum_outbound,
payment_sum_outbound,
is_horaat_keva,
stage,
return_code,
message,
return_message,
display_properties,
table_page_num,
is_error,
is_captcha,
is_button,
site_name,
kod_matbea_mekori,
esb_services_call
FROM accounter_schema.amex_creditcard_transactions
WHERE card = ANY($cards!)
`;
const uploadAmexTransactions = sql `
INSERT INTO accounter_schema.amex_creditcard_transactions (
specific_date,
card_index,
deals_inbound,
supplier_id,
supplier_name,
deal_sum_type,
payment_sum_sign,
purchase_date,
full_purchase_date,
more_info,
horaat_keva,
voucher_number,
voucher_number_ratz,
solek,
purchase_date_outbound,
full_purchase_date_outbound,
currency_id,
current_payment_currency,
city,
supplier_name_outbound,
full_supplier_name_outbound,
payment_date,
full_payment_date,
is_show_deals_outbound,
adendum,
voucher_number_ratz_outbound,
is_show_link_for_supplier_details,
deal_sum,
payment_sum,
full_supplier_name_heb,
deal_sum_outbound,
payment_sum_outbound,
is_horaat_keva,
stage,
return_code,
message,
return_message,
display_properties,
table_page_num,
is_error,
is_captcha,
is_button,
site_name,
client_ip_address,
card,
charging_date,
kod_matbea_mekori,
esb_services_call
)
VALUES $$transactions(
specificDate,
cardIndex,
dealsInbound,
supplierId,
supplierName,
dealSumType,
paymentSumSign,
purchaseDate,
fullPurchaseDate,
moreInfo,
horaatKeva,
voucherNumber,
voucherNumberRatz,
solek,
purchaseDateOutbound,
fullPurchaseDateOutbound,
currencyId,
currentPaymentCurrency,
city,
supplierNameOutbound,
fullSupplierNameOutbound,
paymentDate,
fullPaymentDate,
isShowDealsOutbound,
adendum,
voucherNumberRatzOutbound,
isShowLinkForSupplierDetails,
dealSum,
paymentSum,
fullSupplierNameHeb,
dealSumOutbound,
paymentSumOutbound,
isHoraatKeva,
stage,
returnCode,
message,
returnMessage,
displayProperties,
tablePageNum,
isError,
isCaptcha,
isButton,
siteName,
clientIpAddress,
card,
chargingDate,
kodMatbeaMekori,
esbServicesCall
)
ON CONFLICT (
card,
COALESCE(full_purchase_date, full_purchase_date_outbound),
full_payment_date,
COALESCE(payment_sum, payment_sum_outbound),
voucher_number,
COALESCE(voucher_number_ratz, voucher_number_ratz_outbound),
supplier_id,
current_payment_currency,
COALESCE(full_supplier_name_heb, full_supplier_name_outbound),
more_info,
deal_sum
)
DO NOTHING
RETURNING id, full_purchase_date, supplier_name, payment_sum, card;
`;
function isracardAmexConflictKey(row) {
return JSON.stringify([
row.card,
row.full_purchase_date ?? row.full_purchase_date_outbound ?? '',
row.full_payment_date ?? '',
Number(row.payment_sum ?? row.payment_sum_outbound ?? 0),
row.voucher_number ?? 0,
row.voucher_number_ratz ?? row.voucher_number_ratz_outbound ?? 0,
row.supplier_id ?? 0,
row.current_payment_currency ?? '',
row.full_supplier_name_heb ?? row.full_supplier_name_outbound ?? '',
row.more_info ?? '',
Number(row.deal_sum ?? 0),
]);
}
const ISRACARD_DIFF_FIELDS = [
{ key: 'adendum', incoming: t => t.adendum ?? null },
{ key: 'city', incoming: t => t.city ?? null },
{ key: 'currency_id', incoming: t => t.currencyId ?? null },
{ key: 'deal_sum', incoming: t => t.dealSum ?? null },
{
key: 'deal_sum_outbound',
incoming: t => (t.dealSumOutbound == null ? null : String(t.dealSumOutbound)),
},
{ key: 'deal_sum_type', incoming: t => t.dealSumType ?? null },
{ key: 'deals_inbound', incoming: t => t.dealsInbound ?? null },
{ key: 'display_properties', incoming: t => t.displayProperties ?? null },
{ key: 'esb_services_call', incoming: t => t.esbServicesCall ?? null },
{ key: 'horaat_keva', incoming: t => t.horaatKeva ?? null },
{ key: 'is_button', incoming: t => t.isButton ?? null },
{ key: 'is_captcha', incoming: t => t.isCaptcha ?? null },
{ key: 'is_error', incoming: t => t.isError ?? null },
{ key: 'is_horaat_keva', incoming: t => t.isHoraatKeva ?? null },
{ key: 'is_show_deals_outbound', incoming: t => t.isShowDealsOutbound ?? null },
{
key: 'is_show_link_for_supplier_details',
incoming: t => t.isShowLinkForSupplierDetails ?? null,
},
{ key: 'kod_matbea_mekori', incoming: t => t.kodMatbeaMekori ?? null },
{ key: 'message', incoming: t => t.message ?? null },
{ key: 'payment_date', incoming: t => t.paymentDate ?? null },
{ key: 'payment_sum_sign', incoming: t => t.paymentSumSign ?? null },
{ key: 'purchase_date', incoming: t => t.purchaseDate ?? null },
{ key: 'purchase_date_outbound', incoming: t => t.purchaseDateOutbound ?? null },
{ key: 'return_code', incoming: t => t.returnCode ?? null },
{ key: 'return_message', incoming: t => t.returnMessage ?? null },
{ key: 'site_name', incoming: t => t.siteName ?? null },
{ key: 'solek', incoming: t => t.solek ?? null },
{ key: 'specific_date', incoming: t => t.specificDate ?? null },
{ key: 'stage', incoming: t => t.stage ?? null },
{ key: 'supplier_name', incoming: t => t.supplierName ?? null },
{ key: 'supplier_name_outbound', incoming: t => t.supplierNameOutbound ?? null },
{ key: 'table_page_num', incoming: t => t.tablePageNum ?? null },
{ key: 'voucher_number_ratz', incoming: t => t.voucherNumberRatz ?? null },
{ key: 'voucher_number_ratz_outbound', incoming: t => t.voucherNumberRatzOutbound ?? null },
];
const ISRACARD_AMEX_NUMERIC_FIELDS = [
'deal_sum',
'deal_sum_outbound',
'payment_sum',
'payment_sum_outbound',
];
function diffIsracardAmexRow(existing, incoming) {
const changed = [];
for (const { key, incoming: getIncoming } of ISRACARD_DIFF_FIELDS) {
const isNumberField = ISRACARD_AMEX_NUMERIC_FIELDS.includes(key);
const oldValue = formatValue(existing[key], isNumberField);
const newValue = formatValue(getIncoming(incoming), isNumberField);
const oldStr = oldValue;
const newStr = newValue;
if (oldStr !== newStr) {
changed.push({ field: key, oldValue: oldStr, newValue: newStr });
}
}
return changed;
}
let IsracardAmexScraperIngestionProvider = class IsracardAmexScraperIngestionProvider {
db;
constructor(db) {
this.db = db;
}
async uploadIsracardTransactions(transactions) {
if (transactions.length === 0)
return {
inserted: 0,
skipped: 0,
insertedIds: [],
insertedTransactions: [],
changedTransactions: [],
};
const validated = validateIsracardAmexTransactions(transactions);
const cards = [
...new Set(validated.map(t => t.card).filter((c) => Number.isFinite(c))),
];
const existing = await fetchIsracardByCards.run({ cards: [...cards] }, this.db);
const existingByKey = new Map(existing.map(row => [isracardAmexConflictKey(row), row]));
const result = await uploadIsracardTransactions.run({ transactions: validated }, 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.full_purchase_date ?? null,
description: r.supplier_name ?? null,
amount: r.payment_sum == null ? null : String(r.payment_sum),
account: String(r.card),
}));
const changedTransactions = [];
for (const t of validated) {
if (t.card === null || t.card === undefined)
continue;
const key = isracardAmexConflictKey({
card: t.card,
full_purchase_date: t.fullPurchaseDate ?? null,
full_purchase_date_outbound: t.fullPurchaseDateOutbound ?? null,
full_payment_date: t.fullPaymentDate ?? null,
payment_sum: t.paymentSum !== null && t.paymentSum !== undefined ? String(t.paymentSum) : null,
payment_sum_outbound: t.paymentSumOutbound !== null && t.paymentSumOutbound !== undefined
? String(t.paymentSumOutbound)
: null,
voucher_number: t.voucherNumber ?? null,
supplier_id: t.supplierId ?? null,
current_payment_currency: t.currentPaymentCurrency ?? null,
full_supplier_name_heb: t.fullSupplierNameHeb ?? null,
full_supplier_name_outbound: t.fullSupplierNameOutbound ?? null,
more_info: t.moreInfo ?? null,
});
const existingRow = existingByKey.get(key);
if (existingRow && !insertedIdSet.has(existingRow.id)) {
const changedFields = diffIsracardAmexRow(existingRow, t);
if (changedFields.length > 0) {
changedTransactions.push({ id: existingRow.id, changedFields });
}
}
}
return {
inserted: insertedIds.length,
skipped: transactions.length - insertedIds.length,
insertedIds,
insertedTransactions,
changedTransactions,
};
}
async uploadAmexTransactions(transactions) {
if (transactions.length === 0)
return {
inserted: 0,
skipped: 0,
insertedIds: [],
insertedTransactions: [],
changedTransactions: [],
};
const validated = validateIsracardAmexTransactions(transactions);
const cards = [
...new Set(validated.map(t => t.card).filter((c) => Number.isFinite(c))),
];
const existing = await fetchAmexByCards.run({ cards: [...cards] }, this.db);
const existingByKey = new Map(existing.map(row => [isracardAmexConflictKey(row), row]));
const result = await uploadAmexTransactions.run({ transactions: validated }, 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.full_purchase_date ?? null,
description: r.supplier_name ?? null,
amount: r.payment_sum == null ? null : String(r.payment_sum),
account: String(r.card),
}));
const changedTransactions = [];
for (const t of validated) {
if (t.card === null || t.card === undefined)
continue;
const key = isracardAmexConflictKey({
card: t.card,
full_purchase_date: t.fullPurchaseDate ?? null,
full_purchase_date_outbound: t.fullPurchaseDateOutbound ?? null,
full_payment_date: t.fullPaymentDate ?? null,
payment_sum: t.paymentSum !== null && t.paymentSum !== undefined ? String(t.paymentSum) : null,
payment_sum_outbound: t.paymentSumOutbound !== null && t.paymentSumOutbound !== undefined
? String(t.paymentSumOutbound)
: null,
voucher_number: t.voucherNumber ?? null,
supplier_id: t.supplierId ?? null,
current_payment_currency: t.currentPaymentCurrency ?? null,
full_supplier_name_heb: t.fullSupplierNameHeb ?? null,
full_supplier_name_outbound: t.fullSupplierNameOutbound ?? null,
more_info: t.moreInfo ?? null,
});
const existingRow = existingByKey.get(key);
if (existingRow && !insertedIdSet.has(existingRow.id)) {
const changedFields = diffIsracardAmexRow(existingRow, t);
if (changedFields.length > 0) {
changedTransactions.push({ id: existingRow.id, changedFields });
}
}
}
return {
inserted: insertedIds.length,
skipped: transactions.length - insertedIds.length,
insertedIds,
insertedTransactions,
changedTransactions,
};
}
};
IsracardAmexScraperIngestionProvider = __decorate([
Injectable({
scope: Scope.Operation,
global: true,
}),
__metadata("design:paramtypes", [TenantAwareDBClient])
], IsracardAmexScraperIngestionProvider);
export { IsracardAmexScraperIngestionProvider };
//# sourceMappingURL=isracard-amex-scraper-ingestion.provider.js.map