. */ declare(strict_types=1); namespace FireflyIII\Factory; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Recurrence; use FireflyIII\Services\Internal\Support\RecurringTransactionTrait; use FireflyIII\Services\Internal\Support\TransactionTypeTrait; use FireflyIII\User; use Illuminate\Support\Facades\Log; use Illuminate\Support\MessageBag; use JsonException; /** * Class RecurrenceFactory */ class RecurrenceFactory { use TransactionTypeTrait; use RecurringTransactionTrait; private MessageBag $errors; private User $user; /** * Constructor. * */ public function __construct() { $this->errors = new MessageBag(); } /** * @param array $data * * @return Recurrence * @throws FireflyException * @throws JsonException */ public function create(array $data): Recurrence { try { $type = $this->findTransactionType(ucfirst($data['recurrence']['type'])); } catch (FireflyException $e) { $message = sprintf('Cannot make a recurring transaction of type "%s"', $data['recurrence']['type']); Log::error($message); Log::error($e->getTraceAsString()); throw new FireflyException($message, 0, $e); } $firstDate = null; $repeatUntil = null; $repetitions = 0; $title = null; $description = ''; $applyRules = true; $active = true; $repeatUntilString = null; if (array_key_exists('first_date', $data['recurrence'])) { /** @var Carbon $firstDate */ $firstDate = $data['recurrence']['first_date']; } if (array_key_exists('nr_of_repetitions', $data['recurrence'])) { $repetitions = (int)$data['recurrence']['nr_of_repetitions']; } if (array_key_exists('repeat_until', $data['recurrence'])) { $repeatUntil = $data['recurrence']['repeat_until']; } if (array_key_exists('title', $data['recurrence'])) { $title = $data['recurrence']['title']; } if (array_key_exists('description', $data['recurrence'])) { $description = $data['recurrence']['description']; } if (array_key_exists('apply_rules', $data['recurrence'])) { $applyRules = $data['recurrence']['apply_rules']; } if (array_key_exists('active', $data['recurrence'])) { $active = $data['recurrence']['active']; } $repeatUntilString = $repeatUntil?->format('Y-m-d'); $recurrence = new Recurrence( [ 'user_id' => $this->user->id, 'transaction_type_id' => $type->id, 'title' => $title, 'description' => $description, 'first_date' => $firstDate?->format('Y-m-d'), 'repeat_until' => $repetitions > 0 ? null : $repeatUntilString, 'latest_date' => null, 'repetitions' => $repetitions, 'apply_rules' => $applyRules, 'active' => $active, ] ); $recurrence->save(); if (array_key_exists('notes', $data['recurrence'])) { $this->updateNote($recurrence, (string)$data['recurrence']['notes']); } $this->createRepetitions($recurrence, $data['repetitions'] ?? []); try { $this->createTransactions($recurrence, $data['transactions'] ?? []); } catch (FireflyException $e) { Log::error($e->getMessage()); $recurrence->forceDelete(); $message = sprintf('Could not create recurring transaction: %s', $e->getMessage()); $this->errors->add('store', $message); throw new FireflyException($message, 0, $e); } return $recurrence; } /** * @return MessageBag */ public function getErrors(): MessageBag { return $this->errors; } /** * @param User $user */ public function setUser(User $user): void { $this->user = $user; } }