@accounter/server
Version:
420 lines (402 loc) • 12.3 kB
text/typescript
import { GraphQLResolveInfo } from 'graphql';
import { BusinessesProvider } from '@modules/financial-entities/providers/businesses.provider.js';
import { FinancialEntitiesProvider } from '@modules/financial-entities/providers/financial-entities.provider.js';
import {
ETANA_BUSINESS_ID,
ETHERSCAN_BUSINESS_ID,
ISRACARD_BUSINESS_ID,
KRAKEN_BUSINESS_ID,
POALIM_BUSINESS_ID,
SWIFT_BUSINESS_ID,
} from '@shared/constants';
import { Maybe, ResolverFn, ResolversParentTypes, ResolversTypes } from '@shared/gql-types';
import { formatAmount } from '@shared/helpers';
import type { TransactionsModule } from '../types.js';
type SuggestionData = {
phrases: Array<string>;
priority?: number;
};
type Suggestion = Omit<Awaited<ResolversTypes['TransactionSuggestions']>, 'business'> & {
business: string;
};
type DecoratedSuggestion = Suggestion & {
priority: number;
};
function sortPhrasesByPriority(
a: [string, DecoratedSuggestion],
b: [string, DecoratedSuggestion],
): number {
return b[1].priority - a[1].priority;
}
const missingInfoSuggestions = async (
DbTransaction: ResolversParentTypes['CommonTransaction'],
_: object,
{ injector }: GraphQLModules.Context,
__: GraphQLResolveInfo,
): Promise<Maybe<Suggestion>> => {
if (DbTransaction.business_id) {
return null;
}
if (DbTransaction.is_fee) {
if (DbTransaction.source_description?.includes('Swift')) {
return {
business: SWIFT_BUSINESS_ID,
};
}
switch (DbTransaction.source_origin) {
case 'ETANA': {
return {
business: ETANA_BUSINESS_ID,
};
}
case 'ETHERSCAN': {
return {
business: ETHERSCAN_BUSINESS_ID,
};
}
case 'KRAKEN': {
return {
business: KRAKEN_BUSINESS_ID,
};
}
case 'POALIM': {
return {
business: POALIM_BUSINESS_ID,
};
}
case 'ISRACARD': {
return {
business: ISRACARD_BUSINESS_ID,
};
}
}
}
if (DbTransaction.business_id) {
const business = await injector
.get(BusinessesProvider)
.getBusinessByIdLoader.load(DbTransaction.business_id);
if (business?.suggestion_data) {
return {
business: business.id,
};
}
}
const description = DbTransaction.source_description?.trim() ?? '';
const businesses = await injector
.get(BusinessesProvider)
.getAllBusinesses()
.then(businesses => businesses.filter(business => business.suggestion_data));
const suggestions: Record<string, DecoratedSuggestion> = {};
for (const business of businesses) {
if (!business.suggestion_data) continue;
const suggestionData = business.suggestion_data as SuggestionData;
for (const phrase of suggestionData.phrases) {
suggestions[phrase] = {
business: business.id,
priority: suggestionData.priority ?? 0,
};
}
}
for (const [phrase, suggestion] of Object.entries(suggestions).sort(sortPhrasesByPriority)) {
if (Array.isArray(phrase) && new RegExp(phrase.join('|')).test(description)) {
return suggestion;
}
if (description.includes(phrase)) {
return suggestion;
}
}
switch (DbTransaction.source_origin) {
case 'ETANA': {
if (DbTransaction.is_fee || /\bfee\b/.test(description.toLowerCase())) {
return {
business: ETANA_BUSINESS_ID,
};
}
const amount = formatAmount(DbTransaction.amount);
if (amount < 0) {
return {
business: POALIM_BUSINESS_ID,
};
}
if (amount > 0) {
return {
business: KRAKEN_BUSINESS_ID,
};
}
break;
}
case 'ETHERSCAN': {
if (DbTransaction.is_fee || /\bfee\b/.test(description.toLowerCase())) {
return {
business: ETHERSCAN_BUSINESS_ID,
};
}
const amount = formatAmount(DbTransaction.amount);
if (amount < 0) {
return {
business: KRAKEN_BUSINESS_ID,
};
}
if (amount > 0) {
return {
business: '73519067-c8fe-4073-aec6-608ff596f8a8', // name: 'The Graph Foundation'
};
}
break;
}
case 'KRAKEN': {
if (
DbTransaction.is_fee ||
/\bfee\b/.test(description.toLowerCase()) ||
/\btrade\b/.test(description.toLowerCase())
) {
return {
business: KRAKEN_BUSINESS_ID,
};
}
const amount = formatAmount(DbTransaction.amount);
if (amount < 0) {
return {
business: ETANA_BUSINESS_ID,
};
}
if (amount > 0) {
return {
business: ETHERSCAN_BUSINESS_ID,
};
}
break;
}
}
if (
description.includes('ע\' העברת מט"ח') ||
(description.includes('העברת מט"ח') && Math.abs(formatAmount(DbTransaction.amount)) < 400) ||
(description.includes('מטח') && Math.abs(formatAmount(DbTransaction.amount)) < 400) ||
description.includes('F.C.COM') ||
description.includes('ע.מפעולות-ישיר') ||
description.includes('ריבית חובה') ||
description.includes('FEE')
) {
return {
business: POALIM_BUSINESS_ID,
};
}
if (description.includes('דותן שמחה') || description.includes('שמחה דותן')) {
return {
business: 'ca9d301f-f6db-40a8-a02e-7cf4b63fa2df', //name: 'Dotan Employee',
};
}
if (description.includes('גולדשטין אורי')) {
return {
business: '7843b805-3bb7-4d1c-9219-ff783100334b', //name: 'Uri Employee',
};
}
if (description.includes('גרדוש')) {
return {
business: 'f4b591f3-d817-4e3d-9ecb-35b38d2df7ef', //name: 'Gil Employee',
};
}
if (description.includes('תובל')) {
return {
business: '4420accf-da13-43b0-9aaa-3b94758598e4', //name: 'Tuval Employee',
};
}
if (description.includes('מנורה מבטחים פנס')) {
return {
business: 'af386033-a577-4c9a-880a-d49acd15141d', //name: 'מנורה פנסיה',
};
}
if (description.includes('פניקס אקסלנס')) {
return {
business: '1453f8d1-adae-4761-851b-83799290b8d1', //name: 'פניקס השתלמות',
};
}
if (description.includes('מיטב דש גמל ופנס')) {
return {
business: '340c3552-0a15-4e22-ba03-19ae9322859c', //name: 'איילון פנסיה',
};
}
if (description.includes('מגדל מקפת')) {
return {
business: 'fc2ea992-a2be-4f8a-a639-542a81276beb', //name: 'מגדל פנסיה',
};
}
if (description.includes('מגדל השתלמות')) {
return {
business: '2697dae8-cbd5-4669-8e80-d0964e5c077e', //name: 'מגדל השתלמות',
};
}
if (description.includes('ביטוח לאומי')) {
return {
business: '6d4b01dd-5a5e-4a43-8e40-e9dadfcc10fa', //name: 'Social Security Deductions',
};
}
if (description.includes('LANCE GLOBAL')) {
return {
business: '9c9f3979-08b1-453c-832a-d5eba2bba79a', //name: 'Lance Global Inc',
};
}
if (
(description.includes('העברת מט"ח') &&
(description.includes('fbv') || description.includes('fv'))) ||
description.includes('kamil kisiela')
) {
return {
business: 'f1749353-979b-46df-8931-93a3aafab1f4', //name: 'Jelly JS Kamil Kisiela',
};
}
if (description.includes('מס הכנסה')) {
const flag = description.includes('מס הכנסה ני');
return {
business: flag
? 'f1ade516-4999-4919-9d94-6b013221536d' //name: 'Tax Deductions',
: '9d3a8a88-6958-4119-b509-d50a7cdc0744', //name: 'Tax',
};
}
if (description.includes('גורניצקי')) {
return {
business: 'fe11b834-c218-472b-a129-8ac296553258', //name: 'Gornitzky & Co., Advocates',
};
}
if (description.includes('המכס ומעמ-גביי תשלום') || description.includes('CUSTOM + V.A.T')) {
return {
business: 'c7fdf6f6-e075-44ee-b251-cbefea366826', //name: 'VAT',
};
}
if (description.includes('חניון')) {
return {
business: description.includes('אחוזות החוף')
? 'b51aeb4d-48ed-43e5-84a2-f12b6905fd51' //name: 'Ahuzot',
: 'ed7b54f1-f695-4bc2-b8af-887e3115bfcc', //name: 'Parking',
};
}
if (description.includes('ETANA')) {
return {
business: '4ea86b9b-1c8f-46de-b25e-532f8e34001c', //name: 'Etana',
};
}
if (description.includes('deel')) {
return {
business: '8d34f668-7233-4ce3-9c9c-82550b0839ff', //name: 'Deel Germany GmbH',
};
}
if (description.includes('GITHUB')) {
const suggested = {
business: 'af23ab30-5cf9-4433-abe1-14ae70ab64d7', //name: 'GitHub, Inc',
};
return suggested;
}
if (formatAmount(DbTransaction.amount) === -4329) {
return {
business: '8069311d-314e-4d1a-8f76-629757070ca0', //name: 'Avi Peretz',
};
}
if (description.includes('APPLE COM BILL/ITUNES.COM')) {
return {
business: '6346872a-708d-4910-9428-72019b053ea5', //name: 'Apple',
};
}
if (
description.includes('ע\' העברת מט"ח') ||
(description.includes('העברת מט"ח') && Math.abs(formatAmount(DbTransaction.amount)) < 400) ||
(description.includes('מטח') && Math.abs(formatAmount(DbTransaction.amount)) < 400) ||
description.includes('F.C.COM') ||
description.includes('ע.מפעולות-ישיר') ||
description.includes('ריבית חובה') ||
description.includes('FEE')
) {
return {
business: POALIM_BUSINESS_ID,
};
}
if (description.includes('ריבית זכות')) {
return {
business: POALIM_BUSINESS_ID,
};
}
if (description.includes('פועלים- דמי כרטיס')) {
return {
business: POALIM_BUSINESS_ID,
};
}
if (description.includes('אריה קריסטל')) {
return {
business: '245e149b-b328-471f-9e11-bdaa10dc5fb7', //name: 'Arye Kristal',
};
}
if (description.includes('aleksandra')) {
return {
business: 'b001b503-93ce-497c-bb6c-1c5f1eb6b776', //name: 'ALEKSANDRA MONWID-OLECHNOWICZ'
};
}
if (description.includes('denelop')) {
const current = new Date();
current.setMonth(current.getMonth() - 1);
return {
business: '737df651-8e02-40dd-b749-228bad16f279',
};
}
if (description.includes('slava')) {
return {
business: '74c8b843-3819-44a0-abc6-730d4d829e9f', // SLAVA UKRAINI
};
}
if (description.includes('COURIER PLUS INC')) {
return {
business: '74c8a4e0-ea3b-4906-a6b3-a868ee6d700d', // name: 'Courier Plus Inc DBA Dutchie'
};
}
if (description.includes('GOBRANDS')) {
return {
business: '011dac15-1a48-447e-91f0-ef4344137caa', // name: 'GoBrands Inc'
};
}
if (description.includes('MEDIC FIRST AI')) {
return {
business: 'dcb28428-6ba4-4ee3-94a9-ebd188c82822', // name: 'HSI Workplace Compliance Solutions, Inc'
};
}
if (formatAmount(DbTransaction.amount) === -12_000) {
const current = new Date();
current.setMonth(current.getMonth() - 1);
return {
business: 'd140fae3-f841-464c-84a7-c526c0123f36', //name: 'Saihajpreet Singh',
};
}
if (formatAmount(DbTransaction.amount) === -600) {
return {
business: '02d467c9-0818-45e3-9a25-9f99d0101a9e', //name: 'ZAUM',
};
}
return null;
};
function missingInfoSuggestionsWrapper(
...args: Parameters<
ResolverFn<
Maybe<ResolversTypes['TransactionSuggestions']>,
ResolversParentTypes['ConversionTransaction'],
GraphQLModules.Context,
object
>
>
) {
return missingInfoSuggestions(...args).then(res => {
if (res && 'business' in res) {
return {
...res,
business: args[2].injector
.get(FinancialEntitiesProvider)
.getFinancialEntityByIdLoader.load(res.business),
} as ResolversTypes['TransactionSuggestions'];
}
return res;
});
}
export const transactionSuggestionsResolvers: TransactionsModule.Resolvers = {
ConversionTransaction: {
missingInfoSuggestions: missingInfoSuggestionsWrapper,
},
CommonTransaction: {
missingInfoSuggestions: missingInfoSuggestionsWrapper,
},
};