diff --git a/src/entities/broker-operation/ui/LedgerEntryRow.tsx b/src/entities/broker-operation/ui/LedgerEntryRow.tsx index 1392828..f1637e8 100644 --- a/src/entities/broker-operation/ui/LedgerEntryRow.tsx +++ b/src/entities/broker-operation/ui/LedgerEntryRow.tsx @@ -16,10 +16,18 @@ type LedgerEntryRowProps = { type PaymentPresentation = { amount: string; - direction: "incoming" | "outgoing" | "neutral"; + label: string; tone: "positive" | "negative" | "neutral"; }; +function entryLabelKey(operation: BrokerageOperation): string { + if (operation.category === "income") + return operation.type === "OPERATION_TYPE_COUPON" + ? "ledger.entryLabel.income.coupon" + : "ledger.entryLabel.income.dividend"; + return `ledger.category.${operation.category}`; +} + const LedgerEntryRow: FC = (props) => { const { operation } = props; const { t } = useTranslation(); @@ -28,11 +36,9 @@ const LedgerEntryRow: FC = (props) => { operation.ticker ?? operation.instrumentType ?? t("ledger.noInstrument"); const logoSrc = imageFailed ? null : instrumentLogoUrl(operation.logoName); const payment = paymentPresentation(operation); - const metadata = [ - formatSnapshotTime(operation.occurredAt), - instrument, - t(`ledger.category.${operation.category}`), - ].join(" · "); + const metadata = [formatSnapshotTime(operation.occurredAt), instrument].join( + " · ", + ); return ( @@ -59,7 +65,7 @@ const LedgerEntryRow: FC = (props) => { {payment.amount} - {t(`ledger.direction.${payment.direction}`)} + {t(payment.label)} @@ -70,11 +76,15 @@ function paymentPresentation( operation: BrokerageOperation, ): PaymentPresentation { if (!operation.payment) - return { amount: "—", direction: "neutral", tone: "neutral" }; + return { + amount: "—", + label: "ledger.noMoney", + tone: "neutral", + }; if (isZeroDecimal(operation.payment.value)) return { amount: formatMoney(operation.payment), - direction: "neutral", + label: "ledger.noMoney", tone: "neutral", }; if (operation.payment.value.startsWith("-")) @@ -83,12 +93,12 @@ function paymentPresentation( ...operation.payment, value: operation.payment.value.slice(1), })}`, - direction: "outgoing", + label: entryLabelKey(operation), tone: "negative", }; return { amount: `+${formatMoney(operation.payment)}`, - direction: "incoming", + label: entryLabelKey(operation), tone: "positive", }; } diff --git a/src/pages/account-operations/ui/AccountOperationsPage.test.tsx b/src/pages/account-operations/ui/AccountOperationsPage.test.tsx index 8bfe0f8..bf6fa86 100644 --- a/src/pages/account-operations/ui/AccountOperationsPage.test.tsx +++ b/src/pages/account-operations/ui/AccountOperationsPage.test.tsx @@ -61,7 +61,7 @@ describe("OperationRow", () => { expect(screen.queryByText("Количество: 2")).toBeNull(); }); - it("labels a positive payment as a Russian incoming amount", () => { + it("labels a positive payment with its category type", () => { render( @@ -75,10 +75,70 @@ describe("OperationRow", () => { , ); - expect(screen.getByText("Поступление")).toBeInTheDocument(); + expect(screen.getByText("Сделка")).toBeInTheDocument(); expect(screen.getByText("+15 ₽")).toBeInTheDocument(); }); + it("labels a coupon income as Купон", () => { + render( + + + + + , + ); + + expect(screen.getByText("Купон")).toBeInTheDocument(); + expect(screen.getByText("+8 ₽")).toBeInTheDocument(); + }); + + it("labels a dividend income as Дивиденд", () => { + render( + + + + + , + ); + + expect(screen.getByText("Дивиденд")).toBeInTheDocument(); + expect(screen.getByText("+20 ₽")).toBeInTheDocument(); + }); + + it("labels a fee as Комиссия", () => { + render( + + + + + , + ); + + expect(screen.getByText("Комиссия")).toBeInTheDocument(); + expect(screen.getByText("−3 ₽")).toBeInTheDocument(); + }); + it("keeps a zero payment neutral", () => { render( @@ -94,7 +154,7 @@ describe("OperationRow", () => { ); expect(screen.getByText("Без движения денег")).toBeInTheDocument(); - expect(screen.queryByText("Поступление")).toBeNull(); + expect(screen.queryByText("Сделка")).toBeNull(); }); it("uses an instrument initial when the ledger entry has no logo", () => { diff --git a/src/pages/account/ui/AccountPage.test.tsx b/src/pages/account/ui/AccountPage.test.tsx index bb93e91..8464948 100644 --- a/src/pages/account/ui/AccountPage.test.tsx +++ b/src/pages/account/ui/AccountPage.test.tsx @@ -465,7 +465,7 @@ describe("AccountPage states", () => { expect(screen.getByText("Вторая")).toBeInTheDocument(); }); - it("uses the ledger row for a recent outgoing operation", () => { + it("uses the ledger row for a recent outgoing trade operation", () => { renderPage( { />, ); - expect(screen.getByText("Списание")).toBeInTheDocument(); + expect(screen.getByText("Сделка")).toBeInTheDocument(); expect(screen.getByText("−12 ₽")).toBeInTheDocument(); }); diff --git a/src/shared/i18n/locales/ru.ts b/src/shared/i18n/locales/ru.ts index 47111ec..6dbea7b 100644 --- a/src/shared/i18n/locales/ru.ts +++ b/src/shared/i18n/locales/ru.ts @@ -105,10 +105,11 @@ const ru = { emptyText: "Измените период или фильтры.", noMoney: "Без движения денег", noInstrument: "Без инструмента", - direction: { - incoming: "Поступление", - outgoing: "Списание", - neutral: "Без движения денег", + entryLabel: { + income: { + coupon: "Купон", + dividend: "Дивиденд", + }, }, category: { trade: "Сделка",