Skip to content

Commit

Permalink
Merge pull request #118 from rupato-deriv/Rupato/BOT-2201/Account-swi…
Browse files Browse the repository at this point in the history
…tcher-DIEL-Logic

Rupato/bot 2201/account switcher diel logic
  • Loading branch information
shafin-deriv authored Nov 11, 2024
2 parents 29490bf + 6bb98aa commit d13aad2
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 7 deletions.
38 changes: 31 additions & 7 deletions src/components/layout/header/account-switcher.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useMemo } from 'react';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import React from 'react';
import clsx from 'clsx';
import { observer } from 'mobx-react-lite';
import { CurrencyIcon } from '@/components/currency/currency-icon';
Expand All @@ -11,6 +12,7 @@ import { useStore } from '@/hooks/useStore';
import { LegacyLogout1pxIcon } from '@deriv/quill-icons/Legacy';
import { localize } from '@deriv-com/translations';
import { AccountSwitcher as UIAccountSwitcher, Divider, Text } from '@deriv-com/ui';
import { checkSwitcherType } from './utils';

type TModifiedAccount = ReturnType<typeof useApiBase>['accountList'][number] & {
balance: string;
Expand All @@ -37,8 +39,36 @@ const tabs_labels = {
real: localize('Real'),
};

interface AccountSwitcherData {
renderCountryIsLowRiskAndHasNoRealAccount: boolean;
renderCountryIsEuAndNoRealAccount: boolean;
renderCountryIsNonEuAndNoRealAccount: boolean;
renderCountryIsEuHasOnlyRealAccount: boolean;
renderCountryIsNonEuHasOnlyRealAccount: boolean;
renderCountryIsLowRiskAndHasRealAccount: boolean;
}

const RenderAccountItems = ({ isVirtual, modifiedAccountList, switchAccount }: TAccountSwitcherProps) => {
const { client } = useStore();
const { landing_companies } = client;

const account_switcher_data = useRef<AccountSwitcherData | null>(null);

const fetchAccountSwitcherData = useCallback(async () => {
if (account_switcher_data.current || !client?.loginid || !modifiedAccountList) return;
const account_data = {
login_id: client.loginid,
modifiedAccountList,
landing_companies,
is_virtual: isVirtual,
};
const account_info = await checkSwitcherType(account_data);
account_switcher_data.current = account_info;
}, [client, modifiedAccountList]);

Check warning on line 67 in src/components/layout/header/account-switcher.tsx

View workflow job for this annotation

GitHub Actions / build_to_cloudflare_pages

React Hook useCallback has missing dependencies: 'isVirtual' and 'landing_companies'. Either include them or remove the dependency array

useEffect(() => {
fetchAccountSwitcherData();
}, []);

Check warning on line 71 in src/components/layout/header/account-switcher.tsx

View workflow job for this annotation

GitHub Actions / build_to_cloudflare_pages

React Hook useEffect has a missing dependency: 'fetchAccountSwitcherData'. Either include it or remove the dependency array

return (
<>
Expand Down Expand Up @@ -70,12 +100,6 @@ const RenderAccountItems = ({ isVirtual, modifiedAccountList, switchAccount }: T
<Divider color='var(--du-general-active)' height='2px' />

<div className='account-switcher-footer'>
{/* TODO: need to handle total assets */}
{/* <UIAccountSwitcher.TotalAsset
title={localize('Total assets')}
description={localize('Total assets in your Deriv accounts.')}
value={`${activeAccount.balance} ${activeAccount.currency}`}
/> */}
<UIAccountSwitcher.TradersHubLink href='https://app.deriv.com'>
{localize(`Looking for CFD accounts? Go to Trader's Hub`)}
</UIAccountSwitcher.TradersHubLink>
Expand Down
133 changes: 133 additions & 0 deletions src/components/layout/header/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { api_base } from '@/external/bot-skeleton';

export const LOW_RISK_COUNTRIES = () => ['za', 'ec', 'bw'];
export const EU_COUNTRIES = () => [
'it',
'de',
'fr',
'lu',
'gr',
'mf',
'es',
'sk',
'lt',
'nl',
'at',
'bg',
'si',
'cy',
'be',
'ro',
'hr',
'pt',
'pl',
'lv',
'ee',
'cz',
'fi',
'hu',
'dk',
'se',
'ie',
'im',
'gb',
'mt',
];

export const isEu = country_code => EU_COUNTRIES().includes(country_code);

export const isEuByAccount = (account = {}) => {
const { loginInfo = {} } = account;
return EU_COUNTRIES().includes(loginInfo.country);
};

export const isEuLandingCompany = landing_company => /^(maltainvest|malta|iom)$/.test(landing_company);

export const hasEuAccount = token_list =>
token_list.some(token_obj => isEuLandingCompany(token_obj.loginInfo.landing_company_name));

const isLowRisk = (financial, gaming, upgrade) => {
const { shortcode: f_sc = '' } = financial || {};
const { shortcode: g_sc = '' } = gaming || {};
return (f_sc === 'maltainvest' && g_sc === 'svg') || (upgrade?.includes('svg') && upgrade?.includes('maltainvest'));
};

const isHighRisk = (financial_company, gaming_company, risk_classification) => {
const restricted_countries =
financial_company?.shortcode === 'svg' ||
(gaming_company?.shortcode === 'svg' && financial_company?.shortcode !== 'maltainvest');

const high_risk_landing_company = financial_company?.shortcode === 'svg' && gaming_company?.shortcode === 'svg';
return risk_classification === 'high' || high_risk_landing_company || restricted_countries;
};

const isMultiplier = landing_company_list => {
const multiplier_account = landing_company_list?.financial_company?.legal_allowed_contract_categories;
const is_multiplier = multiplier_account?.includes('multiplier');
return {
is_multiplier: multiplier_account?.length === 1 && is_multiplier,
country_code: landing_company_list.id,
};
};

export const checkSwitcherType = async account_data => {
const { client_accounts = {}, activeLoginid, isVirtual, landing_company } = account_data;

const virtual_accounts = [];
const non_eu_accounts = [];
const eu_accounts = [];
const real_accounts = [...eu_accounts, ...non_eu_accounts];
if (!activeLoginid) return null;
const account_info = { ...api_base.account_info };

if (!account_info) return null;

const account_status = { ...api_base.account_status };

const { country, upgradeable_landing_companies = [] } = account_info;
const is_eu = isEu(country);
const { country_code } = isMultiplier(landing_company);
//TODO: check if this is needed
//is_multiplier
// const is_high_risk_or_eu = is_eu && is_high_risk;

const { financial_company, gaming_company } = landing_company;

const { risk_classification } = account_status || {};
const is_country_low_risk = LOW_RISK_COUNTRIES().includes(country_code);

let is_low_risk = isLowRisk(financial_company, gaming_company, upgradeable_landing_companies);
let is_high_risk = isHighRisk(financial_company, gaming_company, risk_classification);
const low_risk_no_account = is_low_risk && Object.keys(client_accounts).length === 1;
const high_risk_no_account = is_high_risk && Object.keys(client_accounts).length === 1;
//TODO: check if this is needed
// const is_high_risk_or_eu = is_eu && is_high_risk;

if (low_risk_no_account) is_low_risk = false;
if (high_risk_no_account) is_high_risk = false;
if (is_low_risk) is_high_risk = false;
if (is_high_risk) is_low_risk = false;

client_accounts.forEach(account => {
if (account.loginid.startsWith('VR')) virtual_accounts.push({ ...client_accounts[account], account });
if (account.loginid.startsWith('MF')) eu_accounts.push({ ...client_accounts[account], account });
if (account.loginid.startsWith('CR')) non_eu_accounts.push({ ...client_accounts[account], account });
});

const renderCountryIsLowRiskAndHasNoRealAccount = !isVirtual && is_country_low_risk && !real_accounts.length === 0;
const renderCountryIsEuAndNoRealAccount = !isVirtual && !is_country_low_risk && is_eu && !real_accounts.length;
const renderCountryIsNonEuAndNoRealAccount = !isVirtual && !is_country_low_risk && !is_eu && !real_accounts.length;
const renderCountryIsEuHasOnlyRealAccount = !isVirtual && is_country_low_risk && is_eu && real_accounts.length > 0;
const renderCountryIsNonEuHasOnlyRealAccount =
!isVirtual && is_country_low_risk && !is_eu && real_accounts.length > 0;
const renderCountryIsLowRiskAndHasRealAccount = !isVirtual && is_country_low_risk && real_accounts.length > 0;

return {
renderCountryIsLowRiskAndHasNoRealAccount,
renderCountryIsEuAndNoRealAccount,
renderCountryIsNonEuAndNoRealAccount,
renderCountryIsEuHasOnlyRealAccount,
renderCountryIsNonEuHasOnlyRealAccount,
renderCountryIsLowRiskAndHasRealAccount,
};
};
16 changes: 16 additions & 0 deletions src/external/bot-skeleton/services/api/api-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,22 @@ class APIBase {
is_authorized = false;
active_symbols_promise: Promise<void> | null = null;
common_store: CommonStore | undefined;
landing_company: string | null = null;

//TODO : Need to remove this api call because we have it in client store
async getLandingCompany() {
if (!this.api || !this.account_info?.country) {
return null;
}
try {
const landing_company = await this.api.send({ landing_company: this.account_info.country });
this.landing_company = landing_company;
} catch (error) {
console.error('Error fetching landing company:', error);
this.landing_company = null;
}
return this.landing_company;
}

unsubscribeAllSubscriptions = () => {
this.current_auth_subscriptions?.forEach(subscription_promise => {
Expand Down

0 comments on commit d13aad2

Please sign in to comment.