Add Convert to Estimate feature for invoices

New backend endpoint POST /invoices/{id}/convert-to-estimate that
creates a draft estimate from an invoice, copying items, taxes,
custom fields, and financial data. Frontend wired with dropdown
action, store method, and API service call.
This commit is contained in:
Darko Gjorgjijoski
2026-04-06 22:57:03 +02:00
parent c328d1cd10
commit 9ca998e64a
6 changed files with 107 additions and 0 deletions

View File

@@ -3,6 +3,7 @@
namespace App\Models;
use App\Services\InvoiceService;
use App\Services\Pdf\PdfTemplateUtils;
use App\Support\PdfHtmlSanitizer;
use App\Traits\GeneratesPdfTrait;
use App\Traits\HasCustomFieldsTrait;
@@ -12,6 +13,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Support\Str;
use Nwidart\Modules\Facades\Module;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
@@ -295,6 +297,22 @@ class Invoice extends Model implements HasMedia
$query->orWhere('id', $invoice_id);
}
public function getEstimateTemplateName(): string
{
$templateName = Str::replace('invoice', 'estimate', $this->template_name);
$names = [];
foreach (PdfTemplateUtils::getFormattedTemplates('estimate') as $template) {
$names[] = $template['name'];
}
if (! in_array($templateName, $names)) {
$templateName = 'estimate1';
}
return $templateName;
}
public function scopeWhereCompany($query)
{
$query->where('invoices.company_id', request()->header('company'));