Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
66 lines
2.6 KiB
TypeScript
66 lines
2.6 KiB
TypeScript
import {
|
|
defaultParams,
|
|
paramsSchemaSchema,
|
|
payoutByRules,
|
|
payoutFor,
|
|
payoutRulesSchema,
|
|
pricingSchema,
|
|
quote,
|
|
type ParamValues,
|
|
type PriceBreakdown,
|
|
type RateType,
|
|
} from '@barev/core';
|
|
|
|
type Rate = { type: RateType; value: number };
|
|
|
|
export interface PayoutProvider {
|
|
rateType: RateType;
|
|
rateValue: number;
|
|
company: { rateType: RateType; rateValue: number } | null;
|
|
payoutPreset: { rules: unknown } | null;
|
|
}
|
|
|
|
export interface PayoutOrder {
|
|
totalPrice: number;
|
|
basePrice: number;
|
|
params: unknown;
|
|
priceBreakdown: unknown;
|
|
service: { pricing: unknown; paramsSchema: unknown };
|
|
}
|
|
|
|
/** Разбивка цены заказа: сохранённая при создании или пересчитанная по параметрам (старые заказы) */
|
|
export function breakdownOf(o: PayoutOrder): PriceBreakdown | null {
|
|
if (o.priceBreakdown && typeof o.priceBreakdown === 'object') return o.priceBreakdown as PriceBreakdown;
|
|
try {
|
|
const schema = paramsSchemaSchema.parse(o.service.paramsSchema);
|
|
const params = { ...defaultParams(schema), ...(o.params as ParamValues) };
|
|
return quote(pricingSchema.parse(o.service.pricing), params).breakdown;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PRO-8: выплата исполнителю за заказ.
|
|
* - сотрудник компании — договорная ставка компании (от итоговой цены);
|
|
* - исполнитель с пресетом (джун / мидл / прайват) — фикс или % по каждой строке цены;
|
|
* - иначе — индивидуальная ставка (фикс за заказ или % от итога).
|
|
*/
|
|
export function orderPayout(o: PayoutOrder, p: PayoutProvider): number {
|
|
if (p.company) return payoutFor(o.totalPrice, { type: p.company.rateType, value: p.company.rateValue });
|
|
if (p.payoutPreset) {
|
|
const rules = payoutRulesSchema.safeParse(p.payoutPreset.rules);
|
|
const b = breakdownOf(o);
|
|
if (rules.success && b) return payoutByRules(b, rules.data).total;
|
|
}
|
|
const rate: Rate = { type: p.rateType, value: p.rateValue };
|
|
return payoutFor(o.totalPrice, rate);
|
|
}
|
|
|
|
/** Описание ставки для экрана «История» исполнителя */
|
|
export function rateLabel(p: PayoutProvider & { payoutPreset: { name: string; rules: unknown } | null }) {
|
|
if (p.company) return { kind: 'company' as const, type: p.company.rateType, value: p.company.rateValue };
|
|
if (p.payoutPreset) return { kind: 'preset' as const, name: p.payoutPreset.name };
|
|
return { kind: 'own' as const, type: p.rateType, value: p.rateValue };
|
|
}
|