'storno-'.uniqid().'@example.test', 'password' => bcrypt('secret'), 'lang' => 'de', 'admin' => 0, 'm_level' => 1, ]); } function stornoVolume(User $user, int $month, int $year, float $points = 100.0): UserSalesVolume { return UserSalesVolume::forceCreate([ 'user_id' => $user->id, 'user_invoice_id' => 4711, 'month' => $month, 'year' => $year, 'date' => sprintf('%d-%02d-05', $year, $month), 'points' => $points, 'total_net' => $points, 'status' => 2, 'status_points' => 1, 'status_turnover' => 1, ]); } it('bucht den Storno, solange der Monat der Ursprungsbuchung noch laeuft', function () { $user = stornoUser(); $original = stornoVolume($user, 9, 2026); $cancellation = SalesPointsVolume::cancelSalesPointsVolume($original, 9911); expect($cancellation)->not->toBeNull() ->and((float) $cancellation->points)->toBe(-100.0) ->and((int) $cancellation->status)->toBe(6) ->and((int) $cancellation->month)->toBe(9) ->and((int) $cancellation->year)->toBe(2026); expect(UserSalesVolume::where('user_id', $user->id)->where('status', 6)->count())->toBe(1); }); it('laesst einen abgeschlossenen Monat unveraendert', function () { $user = stornoUser(); $original = stornoVolume($user, 8, 2026); $cancellation = SalesPointsVolume::cancelSalesPointsVolume($original, 9911); expect($cancellation)->toBeNull() ->and(UserSalesVolume::where('user_id', $user->id)->where('status', 6)->count())->toBe(0); }); it('behandelt denselben Monat im Vorjahr als abgeschlossen', function () { $user = stornoUser(); $original = stornoVolume($user, 9, 2025); expect(SalesPointsVolume::isStornoMonthOpen($original))->toBeFalse() ->and(SalesPointsVolume::cancelSalesPointsVolume($original, 9911))->toBeNull(); }); it('zieht abgeschlossene Monate im laufenden Monat ab, wenn der Schalter gesetzt ist', function () { Setting::setContentBySlug(SalesPointsVolume::SETTING_STORNO_CURRENT_MONTH, 1, 'bool'); $user = stornoUser(); $original = stornoVolume($user, 8, 2026); $cancellation = SalesPointsVolume::cancelSalesPointsVolume($original, 9911); expect($cancellation)->not->toBeNull() ->and((float) $cancellation->points)->toBe(-100.0) ->and((int) $cancellation->month)->toBe(9) ->and((int) $cancellation->year)->toBe(2026); }); it('ist ohne gesetzten Schalter ausgeschaltet', function () { expect(SalesPointsVolume::stornoDeductsInCurrentMonth())->toBeFalse(); Setting::setContentBySlug(SalesPointsVolume::SETTING_STORNO_CURRENT_MONTH, 0, 'bool'); expect(SalesPointsVolume::stornoDeductsInCurrentMonth())->toBeFalse(); Setting::setContentBySlug(SalesPointsVolume::SETTING_STORNO_CURRENT_MONTH, 1, 'bool'); expect(SalesPointsVolume::stornoDeductsInCurrentMonth())->toBeTrue(); }); it('folgt der Anwendungsuhr, nicht der Systemuhr', function () { // Bewusst ein anderer Kalendermonat als der des Testlaufs: die Regel darf // nicht davon abhaengen, welchen Monat der Server gerade zeigt. Carbon::setTestNow('2027-03-15 09:00:00'); $user = stornoUser(); $imLaufendenMonat = stornoVolume($user, 3, 2027); $imVormonat = stornoVolume($user, 2, 2027); expect(SalesPointsVolume::isStornoMonthOpen($imLaufendenMonat))->toBeTrue() ->and(SalesPointsVolume::isStornoMonthOpen($imVormonat))->toBeFalse(); $cancellation = SalesPointsVolume::cancelSalesPointsVolume($imLaufendenMonat, 9911); expect((int) $cancellation->month)->toBe(3) ->and((int) $cancellation->year)->toBe(2027) ->and($cancellation->message)->toBe('Storniert am 15.03.2027'); });