Add File based templates

This commit is contained in:
gohil jayvirsinh
2021-06-19 12:11:21 +00:00
committed by Mohit Panjwani
parent 00961bcae1
commit d1dd704cdf
58 changed files with 277 additions and 382 deletions

View File

@ -0,0 +1,63 @@
<?php
namespace Crater\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class CreateTemplateCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'make:template {name} {--type=}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create estimate or invoice pdf template. ';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$templateName = $this->argument('name');
$type = $this->option('type');
if (!$type) {
$type = $this->choice('Create a template for?', ['invoice', 'estimate']);
}
if (Storage::disk('views')->exists("/app/pdf/{$type}/{$templateName}.blade.php")) {
$this->info("Template with given name already exists.");
return 0;
}
Storage::disk('views')->copy("/app/pdf/{$type}/{$type}1.blade.php", "/app/pdf/{$type}/{$templateName}.blade.php");
copy(public_path("/assets/img/PDF/{$type}1.png"), public_path("/assets/img/PDF/{$templateName}.png"));
$path = resource_path("app/pdf/{$type}/{$templateName}.blade.php");
$type = ucfirst($type);
$this->info("{$type} Template created successfully at ". $path);
return 0;
}
}

View File

@ -15,6 +15,7 @@ class Kernel extends ConsoleKernel
protected $commands = [ protected $commands = [
Commands\ResetApp::class, Commands\ResetApp::class,
Commands\UpdateCommand::class, Commands\UpdateCommand::class,
Commands\CreateTemplateCommand::class
]; ];
/** /**

View File

@ -21,7 +21,7 @@ class ConvertEstimateController extends Controller
*/ */
public function __invoke(Request $request, Estimate $estimate) public function __invoke(Request $request, Estimate $estimate)
{ {
$estimate->load(['items', 'items.taxes', 'user', 'estimateTemplate', 'taxes']); $estimate->load(['items', 'items.taxes', 'user', 'taxes']);
$invoice_date = Carbon::now(); $invoice_date = Carbon::now();
$due_date = Carbon::now()->addDays(7); $due_date = Carbon::now()->addDays(7);
@ -39,7 +39,7 @@ class ConvertEstimateController extends Controller
'reference_number' => $estimate->reference_number, 'reference_number' => $estimate->reference_number,
'user_id' => $estimate->user_id, 'user_id' => $estimate->user_id,
'company_id' => $request->header('company'), 'company_id' => $request->header('company'),
'invoice_template_id' => 1, 'template_name' => 'invoice1',
'status' => Invoice::STATUS_DRAFT, 'status' => Invoice::STATUS_DRAFT,
'paid_status' => Invoice::STATUS_UNPAID, 'paid_status' => Invoice::STATUS_UNPAID,
'sub_total' => $estimate->sub_total, 'sub_total' => $estimate->sub_total,
@ -84,8 +84,7 @@ class ConvertEstimateController extends Controller
$invoice = Invoice::with([ $invoice = Invoice::with([
'items', 'items',
'user', 'user',
'invoiceTemplate', 'taxes'
'taxes',
])->find($invoice->id); ])->find($invoice->id);
return response()->json([ return response()->json([

View File

@ -5,6 +5,8 @@ namespace Crater\Http\Controllers\V1\Estimate;
use Crater\Http\Controllers\Controller; use Crater\Http\Controllers\Controller;
use Crater\Models\EstimateTemplate; use Crater\Models\EstimateTemplate;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class EstimateTemplatesController extends Controller class EstimateTemplatesController extends Controller
{ {
@ -16,8 +18,17 @@ class EstimateTemplatesController extends Controller
*/ */
public function __invoke(Request $request) public function __invoke(Request $request)
{ {
$templates = Storage::disk('views')->files('/app/pdf/estimate');
$estimateTemplates = [];
foreach ($templates as $key => $template) {
$templateName = Str::before(basename($template), '.blade.php');
$estimateTemplates[$key]['name'] = $templateName;
$estimateTemplates[$key]['path'] = asset('assets/img/PDF/'.$templateName.'.png');
}
return response()->json([ return response()->json([
'templates' => EstimateTemplate::all(), 'templates' => $estimateTemplates
]); ]);
} }
} }

View File

@ -18,7 +18,6 @@ class EstimatesController extends Controller
$estimates = Estimate::with([ $estimates = Estimate::with([
'items', 'items',
'user', 'user',
'estimateTemplate',
'taxes', 'taxes',
'creator', 'creator',
]) ])
@ -68,7 +67,6 @@ class EstimatesController extends Controller
'items', 'items',
'items.taxes', 'items.taxes',
'user', 'user',
'estimateTemplate',
'creator', 'creator',
'taxes', 'taxes',
'taxes.taxType', 'taxes.taxType',

View File

@ -21,7 +21,9 @@ class BootstrapController extends Controller
{ {
$user = Auth::user(); $user = Auth::user();
$default_language = $user->getSettings(['language'])['language']; $default_language = $user->getSettings(['language']);
$default_language = array_key_exists('language', $default_language) ? $default_language['language'] : 'en';
$settings = [ $settings = [
'moment_date_format', 'moment_date_format',

View File

@ -32,7 +32,7 @@ class CloneInvoiceController extends Controller
'reference_number' => $invoice->reference_number, 'reference_number' => $invoice->reference_number,
'user_id' => $invoice->user_id, 'user_id' => $invoice->user_id,
'company_id' => $request->header('company'), 'company_id' => $request->header('company'),
'invoice_template_id' => $invoice->invoice_template_id, 'template_name' => 'invoice1',
'status' => Invoice::STATUS_DRAFT, 'status' => Invoice::STATUS_DRAFT,
'paid_status' => Invoice::STATUS_UNPAID, 'paid_status' => Invoice::STATUS_UNPAID,
'sub_total' => $invoice->sub_total, 'sub_total' => $invoice->sub_total,
@ -78,8 +78,7 @@ class CloneInvoiceController extends Controller
$newInvoice = Invoice::with([ $newInvoice = Invoice::with([
'items', 'items',
'user', 'user',
'invoiceTemplate', 'taxes'
'taxes',
]) ])
->find($newInvoice->id); ->find($newInvoice->id);

View File

@ -3,7 +3,8 @@
namespace Crater\Http\Controllers\V1\Invoice; namespace Crater\Http\Controllers\V1\Invoice;
use Crater\Http\Controllers\Controller; use Crater\Http\Controllers\Controller;
use Crater\Models\InvoiceTemplate; use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class InvoiceTemplatesController extends Controller class InvoiceTemplatesController extends Controller
@ -16,7 +17,14 @@ class InvoiceTemplatesController extends Controller
*/ */
public function __invoke(Request $request) public function __invoke(Request $request)
{ {
$invoiceTemplates = InvoiceTemplate::all(); $templates = Storage::disk('views')->files('/app/pdf/invoice');
$invoiceTemplates = [];
foreach ($templates as $key => $template) {
$templateName = Str::before(basename($template), '.blade.php');
$invoiceTemplates[$key]['name'] = $templateName;
$invoiceTemplates[$key]['path'] = asset('assets/img/PDF/'.$templateName.'.png');
}
return response()->json([ return response()->json([
'invoiceTemplates' => $invoiceTemplates, 'invoiceTemplates' => $invoiceTemplates,

View File

@ -20,7 +20,7 @@ class InvoicesController extends Controller
{ {
$limit = $request->has('limit') ? $request->limit : 10; $limit = $request->has('limit') ? $request->limit : 10;
$invoices = Invoice::with(['items', 'user', 'creator', 'invoiceTemplate', 'taxes']) $invoices = Invoice::with(['items', 'user', 'creator', 'taxes'])
->join('users', 'users.id', '=', 'invoices.user_id') ->join('users', 'users.id', '=', 'invoices.user_id')
->applyFilters($request->only([ ->applyFilters($request->only([
'status', 'status',
@ -78,7 +78,6 @@ class InvoicesController extends Controller
'items', 'items',
'items.taxes', 'items.taxes',
'user', 'user',
'invoiceTemplate',
'taxes.taxType', 'taxes.taxType',
'fields.customField', 'fields.customField',
]); ]);

View File

@ -54,8 +54,8 @@ class EstimatesRequest extends FormRequest
'tax' => [ 'tax' => [
'required', 'required',
], ],
'estimate_template_id' => [ 'template_name' => [
'required', 'required'
], ],
'items' => [ 'items' => [
'required', 'required',

View File

@ -54,8 +54,8 @@ class InvoicesRequest extends FormRequest
'tax' => [ 'tax' => [
'required', 'required',
], ],
'invoice_template_id' => [ 'template_name' => [
'required', 'required'
], ],
'items' => [ 'items' => [
'required', 'required',

View File

@ -2,6 +2,10 @@
namespace Crater\Models; namespace Crater\Models;
use Crater\Models\Company;
use Crater\Models\Tax;
use Illuminate\Database\Eloquent\Model;
use Crater\Models\CompanySetting;
use App; use App;
use Barryvdh\DomPDF\Facade as PDF; use Barryvdh\DomPDF\Facade as PDF;
use Carbon\Carbon; use Carbon\Carbon;
@ -9,7 +13,6 @@ use Crater\Mail\SendEstimateMail;
use Crater\Traits\GeneratesPdfTrait; use Crater\Traits\GeneratesPdfTrait;
use Crater\Traits\HasCustomFieldsTrait; use Crater\Traits\HasCustomFieldsTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia; use Spatie\MediaLibrary\InteractsWithMedia;
@ -130,11 +133,6 @@ class Estimate extends Model implements HasMedia
return $this->hasMany(Tax::class); return $this->hasMany(Tax::class);
} }
public function estimateTemplate()
{
return $this->belongsTo('Crater\Models\EstimateTemplate');
}
public function getEstimateNumAttribute() public function getEstimateNumAttribute()
{ {
$position = $this->strposX($this->estimate_number, "-", 1) + 1; $position = $this->strposX($this->estimate_number, "-", 1) + 1;
@ -315,8 +313,7 @@ class Estimate extends Model implements HasMedia
return Estimate::with([ return Estimate::with([
'items.taxes', 'items.taxes',
'user', 'user',
'estimateTemplate', 'taxes'
'taxes',
]) ])
->find($estimate->id); ->find($estimate->id);
} }
@ -341,11 +338,10 @@ class Estimate extends Model implements HasMedia
} }
return Estimate::with([ return Estimate::with([
'items.taxes', 'items.taxes',
'user', 'user',
'estimateTemplate', 'taxes'
'taxes', ])
])
->find($this->id); ->find($this->id);
} }
@ -431,7 +427,7 @@ class Estimate extends Model implements HasMedia
} }
} }
$estimateTemplate = EstimateTemplate::find($this->estimate_template_id); $estimateTemplate = self::find($this->id)->template_name;
$company = Company::find($this->company_id); $company = Company::find($this->company_id);
$locale = CompanySetting::getSetting('language', $company->id); $locale = CompanySetting::getSetting('language', $company->id);
@ -451,7 +447,7 @@ class Estimate extends Model implements HasMedia
'taxes' => $taxes, 'taxes' => $taxes,
]); ]);
return PDF::loadView('app.pdf.estimate.'.$estimateTemplate->view); return PDF::loadView('app.pdf.estimate.'.$estimateTemplate);
} }
public function getCompanyAddress() public function getCompanyAddress()

View File

@ -1,23 +0,0 @@
<?php
namespace Crater\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class EstimateTemplate extends Model
{
use HasFactory;
protected $fillable = ['path', 'view', 'name'];
public function estimates()
{
return $this->hasMany(Estimate::class);
}
public function getPathAttribute($value)
{
return url($value);
}
}

View File

@ -2,6 +2,12 @@
namespace Crater\Models; namespace Crater\Models;
use Crater\Models\Company;
use Crater\Models\CompanySetting;
use Crater\Models\Currency;
use Crater\Models\Tax;
use Illuminate\Database\Eloquent\Model;
use Crater\Models\Payment;
use App; use App;
use Barryvdh\DomPDF\Facade as PDF; use Barryvdh\DomPDF\Facade as PDF;
use Carbon\Carbon; use Carbon\Carbon;
@ -9,7 +15,6 @@ use Crater\Mail\SendInvoiceMail;
use Crater\Traits\GeneratesPdfTrait; use Crater\Traits\GeneratesPdfTrait;
use Crater\Traits\HasCustomFieldsTrait; use Crater\Traits\HasCustomFieldsTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia; use Spatie\MediaLibrary\InteractsWithMedia;
@ -141,11 +146,6 @@ class Invoice extends Model implements HasMedia
return $this->belongsTo('Crater\Models\User', 'creator_id'); return $this->belongsTo('Crater\Models\User', 'creator_id');
} }
public function invoiceTemplate()
{
return $this->belongsTo(InvoiceTemplate::class);
}
public function getInvoicePdfUrlAttribute() public function getInvoicePdfUrlAttribute()
{ {
return url('/invoices/pdf/'.$this->unique_hash); return url('/invoices/pdf/'.$this->unique_hash);
@ -366,11 +366,10 @@ class Invoice extends Model implements HasMedia
} }
$invoice = Invoice::with([ $invoice = Invoice::with([
'items', 'items',
'user', 'user',
'invoiceTemplate', 'taxes'
'taxes', ])
])
->find($invoice->id); ->find($invoice->id);
return $invoice; return $invoice;
@ -418,11 +417,10 @@ class Invoice extends Model implements HasMedia
} }
$invoice = Invoice::with([ $invoice = Invoice::with([
'items', 'items',
'user', 'user',
'invoiceTemplate', 'taxes'
'taxes', ])
])
->find($this->id); ->find($this->id);
return $invoice; return $invoice;
@ -512,7 +510,7 @@ class Invoice extends Model implements HasMedia
} }
} }
$invoiceTemplate = InvoiceTemplate::find($this->invoice_template_id); $invoiceTemplate = self::find($this->id)->template_name;
$company = Company::find($this->company_id); $company = Company::find($this->company_id);
$locale = CompanySetting::getSetting('language', $company->id); $locale = CompanySetting::getSetting('language', $company->id);
@ -532,7 +530,7 @@ class Invoice extends Model implements HasMedia
'taxes' => $taxes, 'taxes' => $taxes,
]); ]);
return PDF::loadView('app.pdf.invoice.'.$invoiceTemplate->view); return PDF::loadView('app.pdf.invoice.'.$invoiceTemplate);
} }
public function getEmailAttachmentSetting() public function getEmailAttachmentSetting()

View File

@ -1,23 +0,0 @@
<?php
namespace Crater\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class InvoiceTemplate extends Model
{
use HasFactory;
protected $fillable = ['path', 'view', 'name'];
public function invoices()
{
return $this->hasMany(Invoice::class);
}
public function getPathAttribute($value)
{
return url($value);
}
}

View File

@ -90,6 +90,12 @@ return [
'app' => env('DROPBOX_APP'), 'app' => env('DROPBOX_APP'),
'root' => env('DROPBOX_ROOT'), 'root' => env('DROPBOX_ROOT'),
], ],
'views' => [
'driver' => 'local',
'root' => resource_path('views'),
],
], ],
/* /*

View File

@ -3,7 +3,6 @@
namespace Database\Factories; namespace Database\Factories;
use Crater\Models\Estimate; use Crater\Models\Estimate;
use Crater\Models\EstimateTemplate;
use Crater\Models\User; use Crater\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
@ -76,7 +75,7 @@ class EstimateFactory extends Factory
'company_id' => User::where('role', 'super admin')->first()->company_id, 'company_id' => User::where('role', 'super admin')->first()->company_id,
'user_id' => User::factory()->create(['role' => 'customer'])->id, 'user_id' => User::factory()->create(['role' => 'customer'])->id,
'status' => Estimate::STATUS_DRAFT, 'status' => Estimate::STATUS_DRAFT,
'estimate_template_id' => EstimateTemplate::find(1) ?? EstimateTemplate::factory(), 'template_name' => 'estimate1',
'sub_total' => $this->faker->randomDigitNotNull, 'sub_total' => $this->faker->randomDigitNotNull,
'total' => $this->faker->randomDigitNotNull, 'total' => $this->faker->randomDigitNotNull,
'discount_type' => $this->faker->randomElement(['percentage', 'fixed']), 'discount_type' => $this->faker->randomElement(['percentage', 'fixed']),

View File

@ -1,30 +0,0 @@
<?php
namespace Database\Factories;
use Crater\Models\EstimateTemplate;
use Illuminate\Database\Eloquent\Factories\Factory;
class EstimateTemplateFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = EstimateTemplate::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'path' => $this->faker->word,
'view' => $this->faker->word,
'name' => $this->faker->word,
];
}
}

View File

@ -3,7 +3,6 @@
namespace Database\Factories; namespace Database\Factories;
use Crater\Models\Invoice; use Crater\Models\Invoice;
use Crater\Models\InvoiceTemplate;
use Crater\Models\User; use Crater\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
@ -101,7 +100,7 @@ class InvoiceFactory extends Factory
'invoice_number' => 'INV-'.Invoice::getNextInvoiceNumber('INV'), 'invoice_number' => 'INV-'.Invoice::getNextInvoiceNumber('INV'),
'reference_number' => Invoice::getNextInvoiceNumber('INV'), 'reference_number' => Invoice::getNextInvoiceNumber('INV'),
'user_id' => User::factory()->create(['role' => 'customer'])->id, 'user_id' => User::factory()->create(['role' => 'customer'])->id,
'invoice_template_id' => InvoiceTemplate::find(1) ?? InvoiceTemplate::factory(), 'template_name' => 'invoice1',
'status' => Invoice::STATUS_DRAFT, 'status' => Invoice::STATUS_DRAFT,
'tax_per_item' => 'NO', 'tax_per_item' => 'NO',
'discount_per_item' => 'NO', 'discount_per_item' => 'NO',

View File

@ -1,30 +0,0 @@
<?php
namespace Database\Factories;
use Crater\Models\InvoiceTemplate;
use Illuminate\Database\Eloquent\Factories\Factory;
class InvoiceTemplateFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = InvoiceTemplate::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'path' => $this->faker->word,
'view' => $this->faker->word,
'name' => $this->faker->word,
];
}
}

View File

@ -34,8 +34,6 @@ class CreateInvoicesTable extends Migration
$table->boolean('sent')->default(false); $table->boolean('sent')->default(false);
$table->boolean('viewed')->default(false); $table->boolean('viewed')->default(false);
$table->string('unique_hash')->nullable(); $table->string('unique_hash')->nullable();
$table->integer('invoice_template_id')->unsigned()->nullable();
$table->foreign('invoice_template_id')->references('id')->on('invoice_templates');
$table->integer('user_id')->unsigned()->nullable(); $table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('company_id')->unsigned()->nullable(); $table->integer('company_id')->unsigned()->nullable();

View File

@ -32,8 +32,6 @@ class CreateEstimatesTable extends Migration
$table->string('unique_hash')->nullable(); $table->string('unique_hash')->nullable();
$table->integer('user_id')->unsigned()->nullable(); $table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('estimate_template_id')->unsigned()->nullable();
$table->foreign('estimate_template_id')->references('id')->on('estimate_templates');
$table->integer('company_id')->unsigned()->nullable(); $table->integer('company_id')->unsigned()->nullable();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade'); $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
$table->timestamps(); $table->timestamps();

View File

@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
class CreateInvoiceTemplatesTable extends Migration class AddTemplateNameToInvoicesTable extends Migration
{ {
/** /**
* Run the migrations. * Run the migrations.
@ -13,12 +13,8 @@ class CreateInvoiceTemplatesTable extends Migration
*/ */
public function up() public function up()
{ {
Schema::create('invoice_templates', function (Blueprint $table) { Schema::table('invoices', function (Blueprint $table) {
$table->increments('id'); $table->string('template_name')->nullable();
$table->string('name')->nullable();
$table->string('view');
$table->string('path');
$table->timestamps();
}); });
} }
@ -29,6 +25,8 @@ class CreateInvoiceTemplatesTable extends Migration
*/ */
public function down() public function down()
{ {
Schema::dropIfExists('invoice_templates'); Schema::table('invoices', function (Blueprint $table) {
$table->dropColumn('template_name');
});
} }
} }

View File

@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
class CreateEstimateTemplatesTable extends Migration class AddTemplateNameToEstimatesTable extends Migration
{ {
/** /**
* Run the migrations. * Run the migrations.
@ -13,12 +13,8 @@ class CreateEstimateTemplatesTable extends Migration
*/ */
public function up() public function up()
{ {
Schema::create('estimate_templates', function (Blueprint $table) { Schema::table('estimates', function (Blueprint $table) {
$table->increments('id'); $table->string('template_name')->nullable();
$table->string('name')->nullable();
$table->string('view');
$table->string('path');
$table->timestamps();
}); });
} }
@ -29,6 +25,8 @@ class CreateEstimateTemplatesTable extends Migration
*/ */
public function down() public function down()
{ {
Schema::dropIfExists('estimate_templates'); Schema::table('estimates', function (Blueprint $table) {
$table->dropColumn('template_name');
});
} }
} }

View File

@ -0,0 +1,61 @@
<?php
use Crater\Models\Estimate;
use Crater\Models\Invoice;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class RemoveTemplateIdFromInvoicesAndEstimatesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasColumn('invoices', 'invoice_template_id'))
{
$invoices = Invoice::all();
$invoices->map(function ($invoice) {
$invoice->template_name = 'invoice'.$invoice->invoice_template_id;
$invoice->save();
});
Schema::table('invoices', function (Blueprint $table) {
$table->dropForeign(['invoice_template_id']);
$table->dropColumn('invoice_template_id');
});
}
if (Schema::hasColumn('estimates', 'estimate_template_id'))
{
$estimates = Estimate::all();
$estimates->map(function ($estimate) {
$estimate->template_name = 'estimate'.$estimate->estimate_template_id;
$estimate->save();
});
Schema::table('estimates', function (Blueprint $table) {
$table->dropForeign(['estimate_template_id']);
$table->dropColumn('estimate_template_id');
});
}
Schema::dropIfExists('invoice_templates');
Schema::dropIfExists('estimate_templates');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

View File

@ -17,8 +17,6 @@ class DatabaseSeeder extends Seeder
$this->call(CurrenciesTableSeeder::class); $this->call(CurrenciesTableSeeder::class);
$this->call(DefaultSettingsSeeder::class); $this->call(DefaultSettingsSeeder::class);
$this->call(CountriesTableSeeder::class); $this->call(CountriesTableSeeder::class);
$this->call(EstimateTemplateSeeder::class);
$this->call(InvoiceTemplateSeeder::class);
$this->call(PaymentMethodSeeder::class); $this->call(PaymentMethodSeeder::class);
$this->call(UnitSeeder::class); $this->call(UnitSeeder::class);
} }

View File

@ -1,35 +0,0 @@
<?php
namespace Database\Seeders;
use Crater\Models\EstimateTemplate;
use Illuminate\Database\Seeder;
class EstimateTemplateSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
EstimateTemplate::create([
'name' => 'Template 1',
'view' => 'estimate1',
'path' => '/assets/img/PDF/Template1.png',
]);
EstimateTemplate::create([
'name' => 'Template 2',
'view' => 'estimate2',
'path' => '/assets/img/PDF/Template2.png',
]);
EstimateTemplate::create([
'name' => 'Template 3',
'view' => 'estimate3',
'path' => '/assets/img/PDF/Template3.png',
]);
}
}

View File

@ -1,35 +0,0 @@
<?php
namespace Database\Seeders;
use Crater\Models\InvoiceTemplate;
use Illuminate\Database\Seeder;
class InvoiceTemplateSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
InvoiceTemplate::create([
'name' => 'Template 1',
'view' => 'invoice1',
'path' => '/assets/img/PDF/Template1.png',
]);
InvoiceTemplate::create([
'name' => ' Template 2',
'view' => 'invoice2',
'path' => '/assets/img/PDF/Template2.png',
]);
InvoiceTemplate::create([
'name' => 'Template 3',
'view' => 'invoice3',
'path' => '/assets/img/PDF/Template3.png',
]);
}
}

View File

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

View File

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

View File

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

@ -7,14 +7,19 @@
:key="index" :key="index"
:class="{ :class="{
'border border-solid border-primary-500': 'border border-solid border-primary-500':
selectedTemplate === template.id, selectedTemplate === template.name,
}" }"
class="relative flex flex-col m-2 border border-gray-200 border-solid cursor-pointer hover:border-primary-300" class="relative flex flex-col m-2 border border-gray-200 border-solid cursor-pointer hover:border-primary-300"
@click="selectedTemplate = template.id"
> >
<img :src="template.path" alt="template-image" />
<img <img
v-if="selectedTemplate === template.id" :src="template.path"
:alt="template.name"
class="w-full"
@click="selectedTemplate = template.name"
/>
<img
v-if="selectedTemplate === template.name"
:alt="template.name"
class="absolute z-10 w-5 h-5 text-primary-500" class="absolute z-10 w-5 h-5 text-primary-500"
style="top: -6px; right: -5px" style="top: -6px; right: -5px"
src="/assets/img/tick.png" src="/assets/img/tick.png"
@ -24,8 +29,8 @@
'w-full p-1 bg-gray-200 text-sm text-center absolute bottom-0 left-0', 'w-full p-1 bg-gray-200 text-sm text-center absolute bottom-0 left-0',
{ {
'text-primary-500 bg-primary-100': 'text-primary-500 bg-primary-100':
selectedTemplate === template.id, selectedTemplate === template.name,
'text-gray-600': selectedTemplate != template.id, 'text-gray-600': selectedTemplate != template.name,
}, },
]" ]"
> >
@ -53,16 +58,16 @@ import { mapActions, mapGetters } from 'vuex'
export default { export default {
data() { data() {
return { return {
selectedTemplate: 1, selectedTemplate: null,
isLoading: false, isLoading: false,
} }
}, },
computed: { computed: {
...mapGetters('modal', ['modalData']), ...mapGetters('modal', ['modalData']),
...mapGetters('estimate', ['getTemplateId']), ...mapGetters('estimate', ['getTemplateName']),
}, },
mounted() { mounted() {
this.selectedTemplate = this.getTemplateId this.selectedTemplate = this.getTemplateName
}, },
methods: { methods: {
...mapActions('estimate', ['setTemplate']), ...mapActions('estimate', ['setTemplate']),
@ -77,7 +82,7 @@ export default {
} }
}, },
closeEstimateModal() { closeEstimateModal() {
this.selectedTemplate = this.getTemplateId this.selectedTemplate = this.getTemplateName
this.closeModal() this.closeModal()
this.resetModalData() this.resetModalData()
}, },

View File

@ -7,14 +7,19 @@
:key="index" :key="index"
:class="{ :class="{
'border border-solid border-primary-500': 'border border-solid border-primary-500':
selectedTemplate === template.id, selectedTemplate === template.name,
}" }"
class="relative flex flex-col m-2 border border-gray-200 border-solid cursor-pointer hover:border-primary-300" class="relative flex flex-col m-2 border border-gray-200 border-solid cursor-pointer hover:border-primary-300"
@click="selectedTemplate = template.id"
> >
<img :src="template.path" alt="template-image" />
<img <img
v-if="selectedTemplate === template.id" :src="template.path"
:alt="template.name"
class="w-full"
@click="selectedTemplate = template.name"
/>
<img
v-if="selectedTemplate === template.name"
:alt="template.name"
class="absolute z-10 w-5 h-5 text-primary-500" class="absolute z-10 w-5 h-5 text-primary-500"
style="top: -6px; right: -5px" style="top: -6px; right: -5px"
src="/assets/img/tick.png" src="/assets/img/tick.png"
@ -53,16 +58,16 @@ import { mapActions, mapGetters } from 'vuex'
export default { export default {
data() { data() {
return { return {
selectedTemplate: 1, selectedTemplate: null,
isLoading: false, isLoading: false,
} }
}, },
computed: { computed: {
...mapGetters('modal', ['modalData']), ...mapGetters('modal', ['modalData']),
...mapGetters('invoice', ['getTemplateId']), ...mapGetters('invoice', ['getTemplateName']),
}, },
mounted() { mounted() {
this.selectedTemplate = this.getTemplateId this.selectedTemplate = this.getTemplateName
}, },
methods: { methods: {
...mapActions('invoice', ['setTemplate']), ...mapActions('invoice', ['setTemplate']),
@ -77,7 +82,7 @@ export default {
} }
}, },
closeInvoiceModal() { closeInvoiceModal() {
this.selectedTemplate = this.getTemplateId this.selectedTemplate = this.getTemplateName
this.closeModal() this.closeModal()
this.resetModalData() this.resetModalData()
}, },

View File

@ -60,10 +60,7 @@ export const fetchEstimate = ({ commit, dispatch, state }, id) => {
window.axios window.axios
.get(`/api/v1/estimates/${id}`) .get(`/api/v1/estimates/${id}`)
.then((response) => { .then((response) => {
commit( commit(types.SET_TEMPLATE_NAME, response.data.estimate.template_name)
types.SET_TEMPLATE_ID,
response.data.estimate.estimate_template_id
)
resolve(response) resolve(response)
}) })
.catch((err) => { .catch((err) => {
@ -297,7 +294,7 @@ export const resetItem = ({ commit, dispatch, state }) => {
export const setTemplate = ({ commit, dispatch, state }, data) => { export const setTemplate = ({ commit, dispatch, state }, data) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
commit(types.SET_TEMPLATE_ID, data) commit(types.SET_TEMPLATE_NAME, data)
resolve({}) resolve({})
}) })
} }

View File

@ -1,6 +1,6 @@
export const estimates = (state) => state.estimates export const estimates = (state) => state.estimates
export const selectAllField = (state) => state.selectAllField export const selectAllField = (state) => state.selectAllField
export const getTemplateId = (state) => state.estimateTemplateId export const getTemplateName = (state) => state.estimateTemplateName
export const selectedEstimates = (state) => state.selectedEstimates export const selectedEstimates = (state) => state.selectedEstimates
export const totalEstimates = (state) => state.totalEstimates export const totalEstimates = (state) => state.totalEstimates
export const selectedCustomer = (state) => state.selectedCustomer export const selectedCustomer = (state) => state.selectedCustomer

View File

@ -4,7 +4,7 @@ import * as getters from './getters'
const initialState = { const initialState = {
estimates: [], estimates: [],
estimateTemplateId: 1, estimateTemplateName: null,
selectAllField: false, selectAllField: false,
selectedEstimates: [], selectedEstimates: [],
totalEstimates: 0, totalEstimates: 0,

View File

@ -9,7 +9,7 @@ export const RESET_CUSTOMER = 'RESET_CUSTOMER'
export const RESET_ITEM = 'RESET_ITEM' export const RESET_ITEM = 'RESET_ITEM'
export const SET_CUSTOMER = 'SET_CUSTOMER' export const SET_CUSTOMER = 'SET_CUSTOMER'
export const SET_ITEM = 'SET_ITEM' export const SET_ITEM = 'SET_ITEM'
export const SET_TEMPLATE_ID = 'SET_TEMPLATE_ID' export const SET_TEMPLATE_NAME = 'SET_TEMPLATE_NAME'
export const SELECT_CUSTOMER = 'SELECT_CUSTOMER' export const SELECT_CUSTOMER = 'SELECT_CUSTOMER'
export const RESET_SELECTED_CUSTOMER = 'RESET_SELECTED_CUSTOMER' export const RESET_SELECTED_CUSTOMER = 'RESET_SELECTED_CUSTOMER'
export const SET_SELECT_ALL_STATE = 'SET_SELECT_ALL_STATE' export const SET_SELECT_ALL_STATE = 'SET_SELECT_ALL_STATE'

View File

@ -52,8 +52,8 @@ export default {
state.selectAllField = false state.selectAllField = false
}, },
[types.SET_TEMPLATE_ID](state, templateId) { [types.SET_TEMPLATE_NAME](state, templateName) {
state.estimateTemplateId = templateId state.estimateTemplateName = templateName
}, },
[types.SELECT_CUSTOMER](state, data) { [types.SELECT_CUSTOMER](state, data) {

View File

@ -21,7 +21,7 @@ export const fetchInvoice = ({ commit, dispatch, state }, id) => {
window.axios window.axios
.get(`/api/v1/invoices/${id}`) .get(`/api/v1/invoices/${id}`)
.then((response) => { .then((response) => {
commit(types.SET_TEMPLATE_ID, response.data.invoice.invoice_template_id) commit(types.SET_TEMPLATE_NAME, response.data.invoice.template_name)
resolve(response) resolve(response)
}) })
.catch((err) => { .catch((err) => {
@ -219,7 +219,7 @@ export const resetCustomer = ({ commit, dispatch, state }) => {
export const setTemplate = ({ commit, dispatch, state }, data) => { export const setTemplate = ({ commit, dispatch, state }, data) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
commit(types.SET_TEMPLATE_ID, data) commit(types.SET_TEMPLATE_NAME, data)
resolve({}) resolve({})
}) })
} }

View File

@ -1,6 +1,6 @@
export const invoices = (state) => state.invoices export const invoices = (state) => state.invoices
export const selectAllField = (state) => state.selectAllField export const selectAllField = (state) => state.selectAllField
export const getTemplateId = (state) => state.invoiceTemplateId export const getTemplateName = (state) => state.invoiceTemplateName
export const selectedInvoices = (state) => state.selectedInvoices export const selectedInvoices = (state) => state.selectedInvoices
export const totalInvoices = (state) => state.totalInvoices export const totalInvoices = (state) => state.totalInvoices
export const selectedCustomer = (state) => state.selectedCustomer export const selectedCustomer = (state) => state.selectedCustomer

View File

@ -4,7 +4,7 @@ import * as getters from './getters'
const initialState = { const initialState = {
invoices: [], invoices: [],
invoiceTemplateId: 1, invoiceTemplateName: null,
selectedInvoices: [], selectedInvoices: [],
selectAllField: false, selectAllField: false,
totalInvoices: 0, totalInvoices: 0,

View File

@ -12,7 +12,7 @@ export const SET_CUSTOMER = 'SET_CUSTOMER'
export const RESET_ITEM = 'RESET_ITEM' export const RESET_ITEM = 'RESET_ITEM'
export const SET_ITEM = 'SET_ITEM' export const SET_ITEM = 'SET_ITEM'
export const SET_TEMPLATE_ID = 'SET_TEMPLATE_ID' export const SET_TEMPLATE_NAME = 'SET_TEMPLATE_NAME'
export const SELECT_CUSTOMER = 'SELECT_CUSTOMER' export const SELECT_CUSTOMER = 'SELECT_CUSTOMER'
export const RESET_SELECTED_CUSTOMER = 'RESET_SELECTED_CUSTOMER' export const RESET_SELECTED_CUSTOMER = 'RESET_SELECTED_CUSTOMER'

View File

@ -51,8 +51,8 @@ export default {
state.selectedInvoices = [] state.selectedInvoices = []
}, },
[types.SET_TEMPLATE_ID](state, templateId) { [types.SET_TEMPLATE_NAME](state, templateName) {
state.invoiceTemplateId = templateId state.invoiceTemplateName = templateName
}, },
[types.SELECT_CUSTOMER](state, data) { [types.SELECT_CUSTOMER](state, data) {

View File

@ -266,8 +266,8 @@
variant="gray" variant="gray"
@click="openTemplateModal" @click="openTemplateModal"
> >
<span class="flex text-black"> <span class="flex text-black capitalize">
{{ $t('estimates.estimate_template') }} {{ getTemplateId }} {{ getTemplateName }}
<pencil-icon class="h-5 ml-2 -mr-1" /> <pencil-icon class="h-5 ml-2 -mr-1" />
</span> </span>
</sw-button> </sw-button>
@ -514,9 +514,9 @@ export default {
...mapGetters('company', ['defaultCurrency']), ...mapGetters('company', ['defaultCurrency']),
...mapGetters('estimate', [ ...mapGetters('estimate', [
'getTemplateId',
'selectedCustomer', 'selectedCustomer',
'selectedNote', 'selectedNote',
'getTemplateName',
]), ]),
...mapGetters('estimateTemplate', ['getEstimateTemplates']), ...mapGetters('estimateTemplate', ['getEstimateTemplates']),
@ -708,6 +708,7 @@ export default {
'selectCustomer', 'selectCustomer',
'updateEstimate', 'updateEstimate',
'resetSelectedNote', 'resetSelectedNote',
'setTemplate',
]), ]),
...mapActions('item', ['fetchItems']), ...mapActions('item', ['fetchItems']),
@ -789,6 +790,7 @@ export default {
this.estimateNumAttribute = res4.data.nextNumber this.estimateNumAttribute = res4.data.nextNumber
this.estimatePrefix = res4.data.prefix this.estimatePrefix = res4.data.prefix
} }
this.setTemplate(this.getEstimateTemplates[0].name)
} else { } else {
this.estimatePrefix = res4.data.prefix this.estimatePrefix = res4.data.prefix
} }
@ -903,7 +905,7 @@ export default {
total: this.total, total: this.total,
tax: this.totalTax, tax: this.totalTax,
user_id: null, user_id: null,
estimate_template_id: this.getTemplateId, template_name: this.getTemplateName,
} }
if (this.selectedCustomer != null) { if (this.selectedCustomer != null) {

View File

@ -183,7 +183,7 @@ export default {
}, },
computed: { computed: {
...mapGetters('estimate', ['getTemplateId', 'selectedCustomer']), ...mapGetters('estimate', ['getTemplateName', 'selectedCustomer']),
}, },
created() { created() {

View File

@ -259,7 +259,7 @@
@click="openTemplateModal" @click="openTemplateModal"
> >
<span class="flex text-black"> <span class="flex text-black">
{{ $t('invoices.template') }} {{ getTemplateId }} {{ getTemplateName }}
<pencil-icon class="h-5 ml-2 -mr-1" /> <pencil-icon class="h-5 ml-2 -mr-1" />
</span> </span>
</sw-button> </sw-button>
@ -510,7 +510,7 @@ export default {
...mapGetters('notes', ['notes']), ...mapGetters('notes', ['notes']),
...mapGetters('invoice', [ ...mapGetters('invoice', [
'getTemplateId', 'getTemplateName',
'selectedCustomer', 'selectedCustomer',
'selectedNote', 'selectedNote',
]), ]),
@ -710,6 +710,7 @@ export default {
'selectCustomer', 'selectCustomer',
'updateInvoice', 'updateInvoice',
'resetSelectedNote', 'resetSelectedNote',
'setTemplate',
]), ]),
...mapActions('invoiceTemplate', ['fetchInvoiceTemplates']), ...mapActions('invoiceTemplate', ['fetchInvoiceTemplates']),
@ -784,6 +785,7 @@ export default {
this.invoiceNumAttribute = res4.data.nextNumber this.invoiceNumAttribute = res4.data.nextNumber
this.invoicePrefix = res4.data.prefix this.invoicePrefix = res4.data.prefix
} }
this.setTemplate(this.getInvoiceTemplates[0].name)
} else { } else {
this.invoicePrefix = res4.data.prefix this.invoicePrefix = res4.data.prefix
} }
@ -899,7 +901,7 @@ export default {
total: this.total, total: this.total,
tax: this.totalTax, tax: this.totalTax,
user_id: null, user_id: null,
invoice_template_id: this.getTemplateId, template_name: this.getTemplateName,
} }
if (this.selectedCustomer != null) { if (this.selectedCustomer != null) {

View File

@ -185,7 +185,7 @@ export default {
}, },
computed: { computed: {
...mapGetters('invoice', ['getTemplateId', 'selectedCustomer']), ...mapGetters('invoice', ['getTemplateName', 'selectedCustomer']),
}, },
created() { created() {

View File

@ -51,7 +51,7 @@ test('create estimate', function () {
->assertStatus(200); ->assertStatus(200);
$this->assertDatabaseHas('estimates', [ $this->assertDatabaseHas('estimates', [
'estimate_template_id' => $estimate['estimate_template_id'], 'template_name' => $estimate['template_name'],
'estimate_number' => $estimate['estimate_number'], 'estimate_number' => $estimate['estimate_number'],
'discount_type' => $estimate['discount_type'], 'discount_type' => $estimate['discount_type'],
'discount_val' => $estimate['discount_val'], 'discount_val' => $estimate['discount_val'],
@ -97,7 +97,7 @@ test('update estimate', function () {
$newEstimate = $response->decodeResponseJson()['estimate']; $newEstimate = $response->decodeResponseJson()['estimate'];
$this->assertDatabaseHas('estimates', [ $this->assertDatabaseHas('estimates', [
'estimate_template_id' => $estimate2['estimate_template_id'], 'template_name' => $estimate2['template_name'],
'estimate_number' => $estimate2['estimate_number'], 'estimate_number' => $estimate2['estimate_number'],
'discount_type' => $estimate2['discount_type'], 'discount_type' => $estimate2['discount_type'],
'discount_val' => $estimate2['discount_val'], 'discount_val' => $estimate2['discount_val'],

View File

@ -46,7 +46,7 @@ test('create invoice', function () {
$response->assertOk(); $response->assertOk();
$this->assertDatabaseHas('invoices', [ $this->assertDatabaseHas('invoices', [
'invoice_template_id' => $invoice['invoice_template_id'], 'template_name' => $invoice['template_name'],
'invoice_number' => $invoice['invoice_number'], 'invoice_number' => $invoice['invoice_number'],
'sub_total' => $invoice['sub_total'], 'sub_total' => $invoice['sub_total'],
'discount' => $invoice['discount'], 'discount' => $invoice['discount'],
@ -78,7 +78,7 @@ test('create invoice as sent', function () {
'tax' => $invoice['tax'], 'tax' => $invoice['tax'],
'discount' => $invoice['discount'], 'discount' => $invoice['discount'],
'user_id' => $invoice['user_id'], 'user_id' => $invoice['user_id'],
'invoice_template_id' => $invoice['invoice_template_id'], 'template_name' => $invoice['template_name'],
]); ]);
$this->assertDatabaseHas('invoice_items', $invoice['items'][0]); $this->assertDatabaseHas('invoice_items', $invoice['items'][0]);
@ -115,7 +115,7 @@ test('update invoice', function () {
'tax' => $invoice2['tax'], 'tax' => $invoice2['tax'],
'discount' => $invoice2['discount'], 'discount' => $invoice2['discount'],
'user_id' => $invoice2['user_id'], 'user_id' => $invoice2['user_id'],
'invoice_template_id' => $invoice2['invoice_template_id'], 'template_name' => $invoice2['template_name'],
]); ]);
$this->assertDatabaseHas('invoice_items', $invoice2['items'][0]); $this->assertDatabaseHas('invoice_items', $invoice2['items'][0]);

View File

@ -1,28 +0,0 @@
<?php
use Crater\Models\EstimateTemplate;
use Crater\Models\User;
use Illuminate\Support\Facades\Artisan;
use Laravel\Sanctum\Sanctum;
beforeEach(function () {
Artisan::call('db:seed', ['--class' => 'DatabaseSeeder', '--force' => true]);
Artisan::call('db:seed', ['--class' => 'DemoSeeder', '--force' => true]);
$user = User::where('role', 'super admin')->first();
$this->withHeaders([
'company' => $user->company_id,
]);
Sanctum::actingAs(
$user,
['*']
);
});
test('estimate template has many estimates', function () {
$estimateTemplate = EstimateTemplate::factory()->hasEstimates(5)->create();
$this->assertCount(5, $estimateTemplate->estimates);
$this->assertTrue($estimateTemplate->estimates()->exists());
});

View File

@ -46,13 +46,6 @@ test('estimate has many taxes', function () {
$this->assertTrue($estimate->taxes()->exists()); $this->assertTrue($estimate->taxes()->exists());
}); });
test('estimate belongs to estimate template', function () {
$estimate = Estimate::factory()->forEstimateTemplate()->create();
$this->assertTrue($estimate->estimateTemplate()->exists());
});
test('get next estimate number', function () { test('get next estimate number', function () {
$estimate = Estimate::factory()->create(); $estimate = Estimate::factory()->create();
@ -114,7 +107,7 @@ test('create estimate', function () {
$this->assertDatabaseHas('estimates', [ $this->assertDatabaseHas('estimates', [
'estimate_number' => $estimate['estimate_number'], 'estimate_number' => $estimate['estimate_number'],
'user_id' => $estimate['user_id'], 'user_id' => $estimate['user_id'],
'estimate_template_id' => $estimate['estimate_template_id'], 'template_name' => $estimate['template_name'],
'sub_total' => $estimate['sub_total'], 'sub_total' => $estimate['sub_total'],
'total' => $estimate['total'], 'total' => $estimate['total'],
'discount' => $estimate['discount'], 'discount' => $estimate['discount'],
@ -162,7 +155,7 @@ test('update estimate', function () {
$this->assertDatabaseHas('estimates', [ $this->assertDatabaseHas('estimates', [
'estimate_number' => $newEstimate['estimate_number'], 'estimate_number' => $newEstimate['estimate_number'],
'user_id' => $newEstimate['user_id'], 'user_id' => $newEstimate['user_id'],
'estimate_template_id' => $newEstimate['estimate_template_id'], 'template_name' => $newEstimate['template_name'],
'sub_total' => $newEstimate['sub_total'], 'sub_total' => $newEstimate['sub_total'],
'total' => $newEstimate['total'], 'total' => $newEstimate['total'],
'discount' => $newEstimate['discount'], 'discount' => $newEstimate['discount'],

View File

@ -1,28 +0,0 @@
<?php
use Crater\Models\InvoiceTemplate;
use Crater\Models\User;
use Illuminate\Support\Facades\Artisan;
use Laravel\Sanctum\Sanctum;
beforeEach(function () {
Artisan::call('db:seed', ['--class' => 'DatabaseSeeder', '--force' => true]);
Artisan::call('db:seed', ['--class' => 'DemoSeeder', '--force' => true]);
$user = User::where('role', 'super admin')->first();
$this->withHeaders([
'company' => $user->company_id,
]);
Sanctum::actingAs(
$user,
['*']
);
});
test('invoice template has many invoices', function () {
$invoiceTemplate = InvoiceTemplate::factory()->hasInvoices(5)->create();
$this->assertCount(5, $invoiceTemplate->invoices);
$this->assertTrue($invoiceTemplate->invoices()->exists());
});

View File

@ -54,12 +54,6 @@ test('invoice belongs to user', function () {
$this->assertTrue($invoice->user()->exists()); $this->assertTrue($invoice->user()->exists());
}); });
test('invoice belongs to invoice template', function () {
$invoice = Invoice::factory()->forInvoiceTemplate()->create();
$this->assertTrue($invoice->invoiceTemplate()->exists());
});
test('get next invoice number', function () { test('get next invoice number', function () {
$invoice = Invoice::factory()->create(); $invoice = Invoice::factory()->create();
@ -140,7 +134,7 @@ test('create invoice', function () {
'discount' => $invoice['discount'], 'discount' => $invoice['discount'],
'notes' => $invoice['notes'], 'notes' => $invoice['notes'],
'user_id' => $invoice['user_id'], 'user_id' => $invoice['user_id'],
'invoice_template_id' => $invoice['invoice_template_id'], 'template_name' => $invoice['template_name'],
]); ]);
}); });
@ -191,7 +185,7 @@ test('update invoice', function () {
'discount' => $newInvoice['discount'], 'discount' => $newInvoice['discount'],
'notes' => $newInvoice['notes'], 'notes' => $newInvoice['notes'],
'user_id' => $newInvoice['user_id'], 'user_id' => $newInvoice['user_id'],
'invoice_template_id' => $newInvoice['invoice_template_id'], 'template_name' => $newInvoice['template_name'],
]); ]);
}); });

View File

@ -33,8 +33,8 @@ test('estimate request validation rules', function () {
'tax' => [ 'tax' => [
'required', 'required',
], ],
'estimate_template_id' => [ 'template_name' => [
'required', 'required'
], ],
'items' => [ 'items' => [
'required', 'required',

View File

@ -33,8 +33,8 @@ test('invoice request validation rules', function () {
'tax' => [ 'tax' => [
'required', 'required',
], ],
'invoice_template_id' => [ 'template_name' => [
'required', 'required'
], ],
'items' => [ 'items' => [
'required', 'required',