refactor!: support RUB only (WealthLedger/main#55) (#168)
Frontend verify / commits (push) Skipped
Frontend verify / security (push) Successful in 11s
Frontend verify / verify (push) Failing after 9m0s

This commit was merged in pull request #168.
This commit is contained in:
2026-11-11 09:36:29 +03:00
parent e2062ce837
commit 2b94a16ae5
55 changed files with 540 additions and 1153 deletions
@@ -49,7 +49,7 @@ const analytics
buckets: [
{
period: { from: "2026-08-01", to: "2026-08-01" },
totalsByCurrency: [summary("RUB", "10", "2")],
total: summary("10", "2"),
},
],
calculatedAt: "2026-08-27T00:00:00Z",
@@ -77,7 +77,7 @@ const analytics
},
],
period: { from: "2026-08-01", to: "2026-08-27" },
totalsByCurrency: [summary("RUB", "10", "2")],
total: summary("10", "2"),
} satisfies IncomeAnalytics & { instruments: [unknown] };
function entry(): IncomeAnalytics["entries"][number] {
@@ -145,12 +145,11 @@ function renderPage(
return { ...view, queryClient };
}
function summary(currency: string, coupon: string, dividend: string) {
function summary(coupon: string, dividend: string) {
return {
coupon: money(currency, coupon),
currency,
dividend: money(currency, dividend),
total: money(currency, String(Number(coupon) + Number(dividend))),
coupon: money("RUB", coupon),
dividend: money("RUB", dividend),
total: money("RUB", String(Number(coupon) + Number(dividend))),
};
}
@@ -308,7 +307,7 @@ describe("AccountIncomePage", () => {
buckets: [],
entries: [],
instruments: [],
totalsByCurrency: [],
total: summary("0", "0"),
}),
),
),
@@ -410,7 +409,7 @@ describe("AccountIncomePage", () => {
it.each([
["full", analytics],
["empty", { ...analytics, buckets: [], entries: [], instruments: [], totalsByCurrency: [] }],
["empty", { ...analytics, buckets: [], entries: [], instruments: [], total: summary("0", "0") }],
])("shows the server source time and last attempt for a %s result", async (_name, data) => {
server.use(
http.get("*/api/v1/brokerage-accounts/account-1/income-analytics", () =>
@@ -737,11 +736,11 @@ describe("income period and snapshot boundary", () => {
const instruments = [
{
...analytics.instruments[0],
coupon: money("USD", "10"),
dividend: money("USD", "0"),
key: "usd",
coupon: money("RUB", "10"),
dividend: money("RUB", "0"),
key: "rub-positive",
receiptCount: 1,
total: money("USD", "10"),
total: money("RUB", "10"),
},
{
...analytics.instruments[0],
@@ -770,7 +769,7 @@ describe("income period and snapshot boundary", () => {
payment: instrument.total,
})),
instruments,
totalsByCurrency: [summary("RUB", "-5", "0"), summary("USD", "10", "0")],
total: summary("-5", "0"),
});
render(
@@ -782,10 +781,9 @@ describe("income period and snapshot boundary", () => {
screen.getByRole("heading", { name: "Выплаты" }),
).toBeInTheDocument();
expect(screen.queryByText("RUB")).not.toBeInTheDocument();
expect(screen.queryByText("USD")).not.toBeInTheDocument();
const cards = screen.getAllByRole("listitem");
expect(cards).toHaveLength(3);
expect(cards[0]).toHaveTextContent("+10 $");
expect(cards[0]).toHaveTextContent("+10 ₽");
expect(cards[1]).toHaveTextContent("−2 ₽");
expect(cards[2]).toHaveTextContent("−3 ₽");
expect(screen.queryByText(/Итого:|Выплат:/)).not.toBeInTheDocument();
@@ -5,7 +5,6 @@ import {
Stack,
Title,
} from "@mantine/core";
import { StateView } from "@wealthledger/ui";
import { FormProvider } from "react-hook-form";
import { useTranslation } from "react-i18next";
@@ -25,13 +24,9 @@ const AccountIncomePageLoadedSummary: FC<LoadedProps> = (props) => {
const { analytics } = props;
if (props.partial) {
return <Alert role="status">{t("investment.partial")}</Alert>;
}
return analytics.totalsByCurrency.length > 0
? <IncomeSummary totals={analytics.totalsByCurrency} />
: <StateView text={t("income.emptyText")} title={t("income.emptyTitle")} />;
return props.partial
? <Alert role="status">{t("investment.partial")}</Alert>
: <IncomeSummary totals={analytics.total} />;
};
const AccountIncomePageLoaded: FC<LoadedProps> = (props) => {
@@ -7,7 +7,7 @@ import type { IncomeAnalytics } from "@/entities/income";
import { formatMoney } from "@/shared/lib";
type IncomeSummaryProps = { totals: IncomeAnalytics["totalsByCurrency"] };
type IncomeSummaryProps = { totals: IncomeAnalytics["total"] };
const IncomeSummary: FC<IncomeSummaryProps> = (props) => {
const { t } = useTranslation();
@@ -16,16 +16,14 @@ const IncomeSummary: FC<IncomeSummaryProps> = (props) => {
<Stack>
<Title order={2}>{t("income.summaryTitle")}</Title>
{props.totals.map(total => (
<Paper key={total.currency} p="md" radius="md" withBorder>
<Text fw={700}>{formatMoney(total.total)}</Text>
<Paper p="md" radius="md" withBorder>
<Text fw={700}>{formatMoney(props.totals.total)}</Text>
<Text c="dimmed" size="sm">
{t("income.coupon")}: {formatMoney(total.coupon)} ·{" "}
{t("income.dividend")}: {formatMoney(total.dividend)}
</Text>
</Paper>
))}
<Text c="dimmed" size="sm">
{t("income.coupon")}: {formatMoney(props.totals.coupon)} ·{" "}
{t("income.dividend")}: {formatMoney(props.totals.dividend)}
</Text>
</Paper>
</Stack>
);
};