Recruiting Challenge: Storno nimmt Neupartner raus, Rang und Auszahlung nur mit Bestaetigung
Kundenentscheid 25.09.2026: - Storno: Ist jede bezahlte Starterpaket-Bestellung eines Neupartners storniert (txaction = cancelled), bekommt das Tracking cancelled_at, eine Storno-Logzeile nimmt die Einmalpunkte zurueck. Nachtlauf und Neuaufbau markieren; "Meine Berechnung" zeigt den Partner durchgestrichen mit "Storniert am ..., zaehlt nicht". - Gezaehlt wird fuer alle, einen Rang bekommen nur bestaetigte Teilnehmer; Export und Summen nur fuer sie. Unbestaetigte sehen "Deine Praemie nach Bestaetigung", im Admin "Teilnahme nicht bestaetigt, keine Auszahlung". - Datenschutz: andere Berater sehen Unbestaetigte in der Rangliste nicht mehr (auch nicht anonym), VIP-Konten schon, der eigene Eintrag bleibt. - Teilnahmebedingungen Punkt 2 und 7 und Hinweistexte in de/en/es/fr. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
42d2a9c0ab
commit
c4edbf97e4
23 changed files with 318 additions and 45 deletions
|
|
@ -13,11 +13,14 @@ use Illuminate\Support\Collection;
|
|||
* Rang-Bonus, wenn der Teilnehmer qualifiziert ist und innerhalb der Gewinnerplaetze
|
||||
* liegt. Grundlage ist der gespeicherte Stand des Teilnehmers (qualified_partners, rank),
|
||||
* also derselbe Stand wie in der Rangliste.
|
||||
*
|
||||
* Gerechnet wird fuer alle Teilnehmer; ausgezahlt wird nur an Teilnehmer mit bestaetigter
|
||||
* Teilnahme (Kundenentscheid 25.09.2026). Unbestaetigte haben keinen Rang, also keinen Bonus.
|
||||
*/
|
||||
class IncentivePayoutService
|
||||
{
|
||||
/**
|
||||
* @return array{partners: int, per_partner: float, partner_amount: float, rank_bonus: float, total: float}
|
||||
* @return array{partners: int, per_partner: float, partner_amount: float, rank_bonus: float, total: float, confirmed: bool}
|
||||
*/
|
||||
public function forParticipant(Incentive $incentive, IncentiveParticipant $participant): array
|
||||
{
|
||||
|
|
@ -32,13 +35,14 @@ class IncentivePayoutService
|
|||
'partner_amount' => $partnerAmount,
|
||||
'rank_bonus' => $rankBonus,
|
||||
'total' => round($partnerAmount + $rankBonus, 2),
|
||||
'confirmed' => $participant->accepted_terms_at !== null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Auszahlungszeilen: alle Teilnehmer mit Praemie > 0, nach Rang.
|
||||
* Auszahlungszeilen: Teilnehmer mit bestaetigter Teilnahme und Praemie > 0, nach Rang.
|
||||
*
|
||||
* @return Collection<int, array{participant: IncentiveParticipant, payout: array{partners: int, per_partner: float, partner_amount: float, rank_bonus: float, total: float}}>
|
||||
* @return Collection<int, array{participant: IncentiveParticipant, payout: array{partners: int, per_partner: float, partner_amount: float, rank_bonus: float, total: float, confirmed: bool}}>
|
||||
*/
|
||||
public function rows(Incentive $incentive): Collection
|
||||
{
|
||||
|
|
@ -52,14 +56,14 @@ class IncentivePayoutService
|
|||
'participant' => $participant,
|
||||
'payout' => $this->forParticipant($incentive, $participant),
|
||||
])
|
||||
->filter(fn (array $row) => $row['payout']['total'] > 0)
|
||||
->filter(fn (array $row) => $row['payout']['confirmed'] && $row['payout']['total'] > 0)
|
||||
->values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Summen ueber alle Auszahlungszeilen.
|
||||
*
|
||||
* @param Collection<int, array{participant: IncentiveParticipant, payout: array{partners: int, per_partner: float, partner_amount: float, rank_bonus: float, total: float}}> $rows
|
||||
* @param Collection<int, array{participant: IncentiveParticipant, payout: array{partners: int, per_partner: float, partner_amount: float, rank_bonus: float, total: float, confirmed: bool}}> $rows
|
||||
* @return array{recipients: int, partners: int, partner_amount: float, rank_bonus: float, total: float}
|
||||
*/
|
||||
public function totals(Collection $rows): array
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue