find($quoteId); if (!$quote) { throw new \Exception("Quote not found"); } // Create Invoice $invoiceData = [ 'client_id' => $quote->client_id, 'group_id' => $quote->group_id, 'source_quote_id' => $quote->id, 'status' => 'brouillon', // Start as draft 'invoice_date' => now(), 'currency' => $quote->currency, 'total_ht' => $quote->total_ht, 'total_tva' => $quote->total_tva, 'total_ttc' => $quote->total_ttc, ]; $invoice = parent::create($invoiceData); // Copy Lines foreach ($quote->lines as $line) { $this->invoiceLineRepository->create([ 'invoice_id' => $invoice->id, 'product_id' => $line->product_id, 'packaging_id' => $line->packaging_id, 'packages_qty' => $line->packages_qty, 'units_qty' => $line->units_qty, 'description' => $line->description, 'qty_base' => $line->qty_base, 'unit_price' => $line->unit_price, 'unit_price_per_package' => $line->unit_price_per_package, 'tva_rate_id' => $line->tva_rate_id, 'discount_pct' => $line->discount_pct, 'total_ht' => $line->total_ht, ]); } // Record history $this->recordHistory($invoice->id, null, 'brouillon', 'Created from Quote ' . $quote->reference); return $invoice; }); } public function all(array $columns = ['*']): \Illuminate\Support\Collection { return $this->model->with(['client', 'lines.product'])->get($columns); } public function create(array $data): Invoice { return DB::transaction(function () use ($data) { try { // Create the invoice $invoice = parent::create($data); // Create the invoice lines if (isset($data['lines']) && is_array($data['lines'])) { foreach ($data['lines'] as $lineData) { $lineData['invoice_id'] = $invoice->id; $this->invoiceLineRepository->create($lineData); } } // Record initial status history $this->recordHistory($invoice->id, null, $invoice->status, 'Invoice created'); return $invoice; } catch (\Exception $e) { Log::error('Error creating invoice with lines: ' . $e->getMessage(), [ 'exception' => $e, 'data' => $data, ]); throw $e; } }); } public function update(int|string $id, array $attributes): bool { return DB::transaction(function () use ($id, $attributes) { try { $invoice = $this->find($id); if (!$invoice) { return false; } $oldStatus = $invoice->status; // Update the invoice $updated = parent::update($id, $attributes); if ($updated) { $newStatus = $attributes['status'] ?? $oldStatus; // If status changed, record history if ($oldStatus !== $newStatus) { $this->recordHistory((int) $id, $oldStatus, $newStatus, 'Invoice status updated'); } } return $updated; } catch (\Exception $e) { Log::error('Error updating invoice: ' . $e->getMessage(), [ 'id' => $id, 'attributes' => $attributes, 'exception' => $e, ]); throw $e; } }); } public function find(int|string $id, array $columns = ['*']): ?Invoice { return $this->model->with(['client', 'lines.product', 'history.user'])->find($id, $columns); } private function recordHistory(int $invoiceId, ?string $oldStatus, string $newStatus, ?string $comment = null): void { \App\Models\DocumentStatusHistory::create([ 'document_type' => 'invoice', 'document_id' => $invoiceId, 'old_status' => $oldStatus, 'new_status' => $newStatus, 'changed_by' => auth()->id(), // Assuming authenticated user 'comment' => $comment, 'changed_at' => now(), ]); } }