Files
BarevClub/packages/core/src/partners.test.ts
T
2026-10-25 22:57:03 +04:00

44 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest';
import { partnerSplit, partnerTerms, withinDailyLimits } from './partners.ts';
import { isProviderFreeWithGap } from './slots.ts';
import { fromYerevan } from './time.ts';
describe('партнёры услуг: деньги', () => {
it('как Uber: наш % с оплаченного, остальное партнёру', () => {
const r = partnerSplit(20_000, { deal: 'COMMISSION', commissionPct: 30, profitSharePct: 0, fotPct: 0, taxPct: 0 });
expect(r).toMatchObject({ partner: 14_000, margin: 6_000, fot: 0, tax: 0, pct: 30 });
});
it('расходы наши: % партнёра от (оплачено − ФОТ − налог)', () => {
const r = partnerSplit(20_000, { deal: 'PROFIT_SHARE', commissionPct: 0, profitSharePct: 30, fotPct: 60, taxPct: 5 });
// ФОТ 12 000, налог 1 000, прибыль 7 000 → партнёру 2 100
expect(r).toMatchObject({ fot: 12_000, tax: 1_000, partner: 2_100, cost: 14_100, margin: 5_900 });
});
it('ФОТ и налог по умолчанию из настроек, свои — у партнёра', () => {
const base = { deal: 'PROFIT_SHARE' as const, commissionPct: 0, profitSharePct: 50 };
expect(partnerTerms({ ...base, fotPct: null, taxPct: null }, { fotPct: 50, taxPct: 10 })).toMatchObject({ fotPct: 50, taxPct: 10 });
expect(partnerTerms({ ...base, fotPct: 40, taxPct: 0 }, { fotPct: 50, taxPct: 10 })).toMatchObject({ fotPct: 40, taxPct: 0 });
});
});
describe('партнёры услуг: нагрузка сотрудника', () => {
it('лимит заказов и часов в день', () => {
const day = [{ durationMinutes: 180 }, { durationMinutes: 120 }];
expect(withinDailyLimits({ maxOrdersPerDay: 3, maxHoursPerDay: null }, day, 60)).toBe(true);
expect(withinDailyLimits({ maxOrdersPerDay: 2, maxHoursPerDay: null }, day, 60)).toBe(false);
expect(withinDailyLimits({ maxOrdersPerDay: null, maxHoursPerDay: 6 }, day, 60)).toBe(true);
expect(withinDailyLimits({ maxOrdersPerDay: null, maxHoursPerDay: 6 }, day, 61)).toBe(false);
});
it('между заказами остаётся время на дорогу', () => {
// суббота 24.10.2026, график 9:00–21:00 (0 — понедельник), занят 10:00–12:00
const p = { id: 'p', schedule: [{ weekday: 5, startMinute: 9 * 60, endMinute: 21 * 60 }], busy: [{ start: fromYerevan(2026, 10, 24, 600), end: fromYerevan(2026, 10, 24, 720) }] };
const at = (m: number, len = 120) => ({ start: fromYerevan(2026, 10, 24, m), end: fromYerevan(2026, 10, 24, m + len) });
expect(isProviderFreeWithGap(p, at(12 * 60), 0)).toBe(true);
expect(isProviderFreeWithGap(p, at(12 * 60 + 30), 60)).toBe(false);
expect(isProviderFreeWithGap(p, at(13 * 60), 60)).toBe(true);
expect(isProviderFreeWithGap(p, at(7 * 60 + 30, 90), 60)).toBe(false);
});
});