chore(release): 2.0.0 #47
@@ -189,6 +189,49 @@ describe('IncomeAnalyticsService', () => {
|
||||
).toEqual(['10.25', '-0.25']);
|
||||
});
|
||||
|
||||
it('assigns signed payments to Moscow days and retains empty buckets', async () => {
|
||||
seed([
|
||||
{
|
||||
...entry('before', 'OPERATION_TYPE_COUPON', '0.1', 'RUB'),
|
||||
occurredAt: '2026-01-14T20:59:59.999Z',
|
||||
},
|
||||
{
|
||||
...entry('after', 'OPERATION_TYPE_COUPON', '0.2', 'RUB'),
|
||||
occurredAt: '2026-01-14T21:00:00.000Z',
|
||||
},
|
||||
{
|
||||
...entry('reversal', 'OPERATION_TYPE_DIVIDEND', '-0.1', 'RUB'),
|
||||
occurredAt: '2026-01-15T20:59:59.999Z',
|
||||
},
|
||||
]);
|
||||
const response = await service.analytics(
|
||||
'user',
|
||||
'account',
|
||||
'2026-01-14',
|
||||
'2026-01-16',
|
||||
);
|
||||
expect(response.data?.buckets).toEqual([
|
||||
{
|
||||
period: { from: '2026-01-14', to: '2026-01-14' },
|
||||
totalsByCurrency: [expect.objectContaining({
|
||||
total: { currency: 'RUB', value: '0.1' },
|
||||
})],
|
||||
},
|
||||
{
|
||||
period: { from: '2026-01-15', to: '2026-01-15' },
|
||||
totalsByCurrency: [expect.objectContaining({
|
||||
coupon: { currency: 'RUB', value: '0.2' },
|
||||
dividend: { currency: 'RUB', value: '-0.1' },
|
||||
total: { currency: 'RUB', value: '0.1' },
|
||||
})],
|
||||
},
|
||||
{
|
||||
period: { from: '2026-01-16', to: '2026-01-16' },
|
||||
totalsByCurrency: [],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('aggregates only exact coupon and dividend payments by source currency', async () => {
|
||||
operations.collectRanges.mockImplementation(
|
||||
(
|
||||
|
||||
@@ -232,13 +232,16 @@ function buckets(
|
||||
granularity: IncomeBucketGranularity,
|
||||
entries: BrokerageOperationDto[],
|
||||
) {
|
||||
const datedEntries = entries.map((entry) => ({
|
||||
entry,
|
||||
date: moscowDate(new Date(entry.occurredAt)),
|
||||
}));
|
||||
return rangeBuckets(range, granularity).map((period) => ({
|
||||
period,
|
||||
totalsByCurrency: totals(
|
||||
entries.filter((entry) => {
|
||||
const date = moscowDate(new Date(entry.occurredAt));
|
||||
return date >= period.from && date <= period.to;
|
||||
}),
|
||||
datedEntries
|
||||
.filter(({ date }) => date >= period.from && date <= period.to)
|
||||
.map(({ entry }) => entry),
|
||||
),
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user