feat: podpora neplatících osob u objednávek
CI / Generate TypeScript types (push) Successful in 14s
CI / Server unit tests (push) Successful in 20s
CI / Build server (push) Successful in 24s
CI / Build client (push) Successful in 33s
CI / Playwright E2E tests (push) Successful in 1m17s
CI / Build and push Docker image (push) Successful in 39s
CI / Notify (push) Successful in 2s
CI / Generate TypeScript types (push) Successful in 14s
CI / Server unit tests (push) Successful in 20s
CI / Build server (push) Successful in 24s
CI / Build client (push) Successful in 33s
CI / Playwright E2E tests (push) Successful in 1m17s
CI / Build and push Docker image (push) Successful in 39s
CI / Notify (push) Successful in 2s
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { OrderGroup, OrderGroupMember } from "../../../types";
|
||||
|
||||
/**
|
||||
* Pomocné funkce pro výpočet částek ve skupinových objednávkách.
|
||||
*
|
||||
* Klíčové pravidlo: poplatky (balné + doprava + spropitné) se rozpočítávají
|
||||
* pouze mezi "aktivní" strávníky — tedy ty, kteří si reálně něco objednali.
|
||||
* Kdo si nic neobjedná (typicky objednávající, který nakupuje jen pro ostatní),
|
||||
* neplatí nic a nezapočítává se mu ani poměrná část poplatků.
|
||||
*/
|
||||
|
||||
/** Parametry poplatků a slevy potřebné k výpočtu částky člena. */
|
||||
export type GroupFeeParams = {
|
||||
/** Celkové poplatky skupiny v haléřích (balné + doprava + spropitné). */
|
||||
totalFees: number;
|
||||
/** Typ slevy ('percent' = procenta, 'fixed' = pevná částka v haléřích). */
|
||||
discountType?: string;
|
||||
/** Hodnota slevy — procenta, nebo pevná částka v haléřích dle discountType. */
|
||||
discountValue?: number;
|
||||
};
|
||||
|
||||
/** Vrátí true, pokud si člen něco objednal (má kladnou částku nebo příplatek). */
|
||||
export function isActiveMember(member: OrderGroupMember): boolean {
|
||||
return (member.amount ?? 0) + (member.surchargeAmount ?? 0) > 0;
|
||||
}
|
||||
|
||||
/** Počet aktivních strávníků — jen mezi ně se dělí poplatky. */
|
||||
export function countActiveMembers(members: OrderGroup["members"]): number {
|
||||
return Object.values(members).filter(isActiveMember).length;
|
||||
}
|
||||
|
||||
/** Celkové poplatky skupiny (balné + doprava + spropitné) v haléřích. */
|
||||
export function totalGroupFees(group: OrderGroup): number {
|
||||
return (group.fees ?? 0) + (group.shipping ?? 0) + (group.tip ?? 0);
|
||||
}
|
||||
|
||||
/** Poměrná část poplatků na jednoho aktivního strávníka v haléřích. */
|
||||
export function computeFeeShare(totalFees: number, activeCount: number): number {
|
||||
return activeCount > 0 ? Math.round(totalFees / activeCount) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Celková částka, kterou má člen zaplatit (v haléřích).
|
||||
* Neaktivní člen (nic si neobjednal) platí 0 — nepodílí se ani na poplatcích.
|
||||
*
|
||||
* @param member člen skupiny
|
||||
* @param params poplatky a sleva
|
||||
* @param feeShare poměrná část poplatků na osobu (viz computeFeeShare)
|
||||
* @param activeCount počet aktivních strávníků (dělitel pevné slevy)
|
||||
*/
|
||||
export function computeMemberTotal(
|
||||
member: OrderGroupMember,
|
||||
params: GroupFeeParams,
|
||||
feeShare: number,
|
||||
activeCount: number,
|
||||
): number {
|
||||
if (!isActiveMember(member)) return 0;
|
||||
const base = member.amount ?? 0;
|
||||
const surcharge = member.surchargeAmount ?? 0;
|
||||
const discountValue = params.discountValue ?? 0;
|
||||
const discount = discountValue > 0
|
||||
? (params.discountType === 'percent'
|
||||
? Math.round((base + surcharge) * discountValue / 100)
|
||||
: Math.round(discountValue / activeCount))
|
||||
: 0;
|
||||
return base + surcharge + feeShare - discount;
|
||||
}
|
||||
Reference in New Issue
Block a user