Skip to content

Commit

Permalink
fetch extra data for mizrahi transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
simonlsk committed Nov 22, 2024
1 parent 28fd0e9 commit 3788ba5
Showing 1 changed file with 91 additions and 5 deletions.
96 changes: 91 additions & 5 deletions src/scrapers/mizrahi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SHEKEL_CURRENCY } from '../constants';
import {
pageEvalAll, waitUntilElementDisappear, waitUntilElementFound, waitUntilIframeFound,
} from '../helpers/elements-interactions';
import { fetchPostWithinPage } from '../helpers/fetch';
import { fetchPost, fetchPostWithinPage } from '../helpers/fetch';
import { waitForUrl } from '../helpers/navigation';
import {
type Transaction,
Expand All @@ -20,6 +20,13 @@ interface ScrapedTransaction {
MC02SchumEZ: number;
MC02AsmahtaMekoritEZ: string;
MC02TnuaTeurEZ: string;
MC02KodGoremEZ: string;
MC02SugTnuaKaspitEZ: string;
MC02AgidEZ: string;
MC02ErehTaaEZ: string;
MC02SeifMaralEZ: string;
MC02NoseMaralEZ: string;
TransactionNumber: string;
}

interface ScrapedTransactionsResult {
Expand All @@ -37,6 +44,27 @@ interface ScrapedTransactionsResult {
};
}

interface ExtraTransactionDetail {
Label: string;
Value: string;
}

interface ExtraTransactionResult {
body: {
fields: [
[
{
Records: [
{
Fields: ExtraTransactionDetail[];
},
];
},
],
];
};
}

const BASE_WEBSITE_URL = 'https://www.mizrahi-tefahot.co.il';
const LOGIN_URL = `${BASE_WEBSITE_URL}/login/index.html#/auth-page-he`;
const BASE_APP_URL = 'https://mto.mizrahi-tefahot.co.il';
Expand All @@ -47,6 +75,7 @@ const TRANSACTIONS_REQUEST_URLS = [
`${BASE_APP_URL}/OnlinePilot/api/SkyOSH/get428Index`,
`${BASE_APP_URL}/Online/api/SkyOSH/get428Index`,
];
const TRANSACTION_DETAILS_REQUEST_URL = `${BASE_APP_URL}/Online/api/OSH/getMaherBerurimSMF`;
const PENDING_TRANSACTIONS_PAGE = '/osh/legacy/legacy-Osh-p420';
const PENDING_TRANSACTIONS_IFRAME = 'p420.aspx';
const CHANGE_PASSWORD_URL = /https:\/\/www\.mizrahi-tefahot\.co\.il\/login\/index\.html#\/change-pass/;
Expand Down Expand Up @@ -130,6 +159,56 @@ function convertTransactions(txns: ScrapedTransaction[]): Transaction[] {
});
}

async function getTransactionExtraScrap(record: ScrapedTransaction, headers: Headers): Promise<ExtraTransactionResult> {
const formattedPeulaDate = moment(record.MC02PeulaTaaEZ).format(DATE_FORMAT);
// const formattedErechDate = moment(record.MC02ErehTaaEZ).format(DATE_FORMAT);
const data = {
inKodGorem: record.MC02KodGoremEZ,
inAsmachta: record.MC02AsmahtaMekoritEZ,
inSchum: record.MC02SchumEZ,
inNakvanit: record.MC02KodGoremEZ,
inSugTnua: record.MC02SugTnuaKaspitEZ,
inAgid: record.MC02AgidEZ,
inTarPeulaFormatted: formattedPeulaDate,
inTarErechFormatted: formattedPeulaDate,
inKodNose: record.MC02SeifMaralEZ,
inKodTatNose: record.MC02NoseMaralEZ,
inTransactionNumber: record.TransactionNumber,
};

const res = await fetchPost(TRANSACTION_DETAILS_REQUEST_URL, data, headers);
return res;
}

function simplifyExtraTransactionResultsToMemo(extraResult: ExtraTransactionResult): string {
let memo = '';
extraResult.body.fields.forEach(field =>
field?.forEach(group =>
group?.Records.forEach(record =>
record?.Fields.forEach((fieldRecord) => {
memo += `${fieldRecord.Label} ${fieldRecord.Value}; `;
}),
),
),
);
return memo;
}

async function getExtraScrap(originalRecords: ScrapedTransaction[], currentTxns: Transaction[], headers: Headers): Promise<Transaction[]> {
const promises = Object.values(originalRecords)
.map(async (record) => getTransactionExtraScrap(record, headers));
const accounts = await Promise.all(promises);
const txnsWithExtra = currentTxns.map((txn, i) => {
const extraDetails = accounts[i];
const currentTxn = { ...txn };
if (extraDetails) {
currentTxn.memo = simplifyExtraTransactionResultsToMemo(extraDetails);
}
return currentTxn;
});
return txnsWithExtra;
}

async function extractPendingTransactions(page: Frame): Promise<Transaction[]> {
const pendingTxn = await pageEvalAll(page, 'tr.rgRow', [], (trs) => {
return trs.map((tr) => Array.from(tr.querySelectorAll('td'), (td: HTMLTableDataCellElement) => td.textContent || ''));
Expand Down Expand Up @@ -228,24 +307,31 @@ class MizrahiScraper extends BaseScraperWithBrowser<ScraperSpecificCredentials>
throw new Error('Account number not found');
}

const headersMap: Record<string, any> = {};
const response = await Promise.any(TRANSACTIONS_REQUEST_URLS.map(async (url) => {
const request = await this.page.waitForRequest(url);
const data = createDataFromRequest(request, this.options.startDate);
const headers = createHeadersFromRequest(request);
headersMap[url] = createHeadersFromRequest(request);

return fetchPostWithinPage<ScrapedTransactionsResult>(this.page, url, data, headers);
return fetchPostWithinPage<ScrapedTransactionsResult>(this.page, url, data, headersMap[url]);
}));

const cookies = await this.page.cookies();
const headers = Object.values(headersMap)[0];
headers.Cookie = cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join('; ');

if (!response || response.header.success === false) {
throw new Error(`Error fetching transaction. Response message: ${response ? response.header.messages[0].text : ''}`);
}

const relevantRows = response.body.table.rows.filter((row) => row.RecTypeSpecified);
const oshTxn = convertTransactions(relevantRows);

const oshTxnWithExtra = this.options.additionalTransactionInformation ?
await getExtraScrap(relevantRows, oshTxn, headers) : oshTxn;

// workaround for a bug which the bank's API returns transactions before the requested start date
const startMoment = getStartMoment(this.options.startDate);
const oshTxnAfterStartDate = oshTxn.filter((txn) => moment(txn.date).isSameOrAfter(startMoment));
const oshTxnAfterStartDate = oshTxnWithExtra.filter((txn) => moment(txn.date).isSameOrAfter(startMoment));

const pendingTxn = await this.getPendingTransactions();
const allTxn = oshTxnAfterStartDate.concat(pendingTxn);
Expand Down

0 comments on commit 3788ba5

Please sign in to comment.