authorize('site.manage'); // modals are reachable without the route middleware $series = InvoiceSeries::query()->where('uuid', $uuid)->firstOrFail(); $this->uuid = $uuid; $this->name = $series->name; $this->prefix = $series->prefix; $this->digits = (int) $series->digits; $this->yearlyReset = (bool) $series->yearly_reset; $this->nextNumber = (int) $series->next_number; $this->active = (bool) $series->active; $this->issued = $series->invoices()->count(); $this->floor = (int) $series->next_number; } public function save() { $this->authorize('site.manage'); $series = InvoiceSeries::query()->where('uuid', $this->uuid)->firstOrFail(); // Recomputed from the database, never read back from the properties the // browser returns: these two rules are what keep already-issued numbers // from being re-used, and a forged field must not lift either. $issued = $series->invoices()->count(); $floor = (int) $series->next_number; $rules = [ 'name' => 'required|string|max:120', 'digits' => 'required|integer|min:3|max:10', 'active' => 'boolean', 'nextNumber' => ['required', 'integer', 'min:'.$floor], ]; if ($issued === 0) { $rules['prefix'] = [ 'required', 'string', 'max:12', 'regex:/^[A-Z0-9-]+$/', Rule::unique('invoice_series', 'prefix')->ignore($series->id), ]; // Only while nothing has been issued: switching an established // series between yearly and continuous puts a gap in one of them. $rules['yearlyReset'] = 'boolean'; } if ($issued === 0) { $this->prefix = strtoupper(trim($this->prefix)); } else { $this->prefix = $series->prefix; $this->yearlyReset = (bool) $series->yearly_reset; } $data = $this->validate($rules); $series->update([ 'name' => $data['name'], 'digits' => $data['digits'], 'next_number' => $data['nextNumber'], 'active' => $data['active'], ...($issued === 0 ? [ 'prefix' => $data['prefix'], 'yearly_reset' => $data['yearlyReset'], ] : []), ]); $this->dispatch('notify', message: __('finance.series_saved')); return $this->redirectRoute('admin.finance', navigate: true); } public function render() { return view('livewire.admin.edit-invoice-series'); } }