Work on tests
This commit is contained in:
parent
efe78bb49f
commit
8104eacc79
@ -20,6 +20,5 @@ enum IconEnum: string
|
|||||||
|
|
||||||
case TAB_ALL = 'lucide-layout-grid';
|
case TAB_ALL = 'lucide-layout-grid';
|
||||||
case TAB_OVERDUE = 'lucide-calendar-clock';
|
case TAB_OVERDUE = 'lucide-calendar-clock';
|
||||||
case TAB_UNPRINTED = ' lucide-printer';
|
case TAB_UNPRINTED = 'lucide-printer';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,10 @@ public static function form(Form $form): Form
|
|||||||
|
|
||||||
Section::make()
|
Section::make()
|
||||||
->schema([
|
->schema([
|
||||||
|
Placeholder::make('ID')
|
||||||
|
->label('Order ID')
|
||||||
|
->content(fn (Order $record): ?string => $record->internal_po),
|
||||||
|
|
||||||
Placeholder::make('created_at')
|
Placeholder::make('created_at')
|
||||||
->label('Created')
|
->label('Created')
|
||||||
->content(fn (Order $record): ?string => $record->created_at?->diffForHumans()),
|
->content(fn (Order $record): ?string => $record->created_at?->diffForHumans()),
|
||||||
|
@ -39,12 +39,10 @@ class Invoice extends Model
|
|||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'has_gst' => 'boolean',
|
'has_gst' => 'boolean',
|
||||||
'has_pst' => 'boolean',
|
'has_pst' => 'boolean',
|
||||||
'date' => 'datetime',
|
'date' => 'datetime',
|
||||||
'total' => 'decimal:2',
|
'status' => InvoiceStatus::class,
|
||||||
'subtotal' => 'decimal:2',
|
|
||||||
'status' => InvoiceStatus::class,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public function calculateTotals(): void
|
public function calculateTotals(): void
|
||||||
|
@ -50,8 +50,17 @@ class Order extends Model
|
|||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'status' => OrderStatus::class,
|
'status' => OrderStatus::class,
|
||||||
'order_type' => OrderType::class,
|
'order_type' => OrderType::class,
|
||||||
|
'rush' => 'bool',
|
||||||
|
'repeat' => 'bool',
|
||||||
|
'new_art' => 'bool',
|
||||||
|
'event' => 'bool',
|
||||||
|
'digitizing' => 'bool',
|
||||||
|
'garments' => 'bool',
|
||||||
|
'supplied_file' => 'bool',
|
||||||
|
'printed' => 'bool',
|
||||||
|
'pre_production' => 'bool',
|
||||||
];
|
];
|
||||||
|
|
||||||
public static function boot(): void
|
public static function boot(): void
|
||||||
@ -109,13 +118,13 @@ public function getTotalProductQuantityAttribute(): int
|
|||||||
|
|
||||||
public function getTotalServicePriceAttribute(): float
|
public function getTotalServicePriceAttribute(): float
|
||||||
{
|
{
|
||||||
$total = 0;
|
$total = 0.00;
|
||||||
|
|
||||||
foreach ($this->productServices as $service) {
|
foreach ($this->productServices as $service) {
|
||||||
$total += $service->amount * $service->amount_price;
|
$total += $service->amount * $service->amount_price;
|
||||||
}
|
}
|
||||||
|
|
||||||
return number_format($total, 2);
|
return $total;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function active(): bool
|
public function active(): bool
|
||||||
|
@ -10,7 +10,7 @@ class CustomerFactory extends Factory
|
|||||||
{
|
{
|
||||||
protected $model = Customer::class;
|
protected $model = Customer::class;
|
||||||
|
|
||||||
public function definition()
|
public function definition(): array
|
||||||
{
|
{
|
||||||
$company_name = $this->faker->company();
|
$company_name = $this->faker->company();
|
||||||
$internal_name = explode(',', $company_name);
|
$internal_name = explode(',', $company_name);
|
||||||
|
@ -15,7 +15,7 @@ class InvoiceFactory extends Factory
|
|||||||
|
|
||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
$customer = Customer::all()->shuffle()->first();
|
$customer = Customer::all()->shuffle()->firstOrFail();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'created_at' => Carbon::now()->subDays(rand(1, 30)),
|
'created_at' => Carbon::now()->subDays(rand(1, 30)),
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use App\Enums\InvoiceStatus;
|
|
||||||
use App\Filament\Admin\Resources\InvoiceResource\Pages\CreateInvoice;
|
|
||||||
use App\Models\Customer;
|
|
||||||
use App\Models\Invoice;
|
|
||||||
use App\Models\TaxRate;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
||||||
|
|
||||||
uses(RefreshDatabase::class);
|
|
||||||
|
|
||||||
it('can create an invoice', function () {
|
|
||||||
$customer = Customer::factory()->create(); // Generates a customer
|
|
||||||
$user = User::factory(['is_admin' => true])->create();
|
|
||||||
$pst_rate = TaxRate::where('name', 'PST')->value('value') ?? 0;
|
|
||||||
$gst_rate = TaxRate::where('name', 'GST')->value('value') ?? 0;
|
|
||||||
|
|
||||||
$this->actingAs($user);
|
|
||||||
|
|
||||||
$formData = [
|
|
||||||
'customer_id' => $customer->id,
|
|
||||||
'date' => now()->toDateString(),
|
|
||||||
'due_date' => now()->addDays(7)->toDateString(),
|
|
||||||
'status' => InvoiceStatus::UNPAID->value,
|
|
||||||
'has_gst' => true,
|
|
||||||
'has_pst' => true,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Step 3: Submit the form and create an invoice
|
|
||||||
$this->livewire(CreateInvoice::class)
|
|
||||||
->fillForm($formData) // Simulates filling the form
|
|
||||||
->call('create') // Submits the form
|
|
||||||
->assertHasNoErrors(); // Verifies no validation errors occurred
|
|
||||||
|
|
||||||
// Step 4: Assert the invoice was successfully created in the database
|
|
||||||
$this->assertDatabaseHas('invoices', [
|
|
||||||
'internal_id' => 'INV400001',
|
|
||||||
'customer_id' => $formData['customer_id'],
|
|
||||||
'status' => $formData['status'],
|
|
||||||
'has_gst' => $formData['has_gst'],
|
|
||||||
'has_pst' => $formData['has_pst'],
|
|
||||||
'gst_rate' => $gst_rate,
|
|
||||||
'pst_rate' => $pst_rate,
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
// it can add orders
|
|
||||||
|
|
||||||
// it correctly calculates tax
|
|
@ -11,9 +11,18 @@
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
|
||||||
pest()->extend(Tests\TestCase::class)
|
pest()->extend(Tests\TestCase::class)
|
||||||
->use(Illuminate\Foundation\Testing\RefreshDatabase::class)
|
// ->use(Illuminate\Foundation\Testing\DatabaseMigrations::class)
|
||||||
->in('Feature');
|
// ->use(RefreshDatabase::class)
|
||||||
|
->beforeEach(function () {
|
||||||
|
DB::beginTransaction();
|
||||||
|
})
|
||||||
|
->afterEach(function () {
|
||||||
|
DB::rollBack();
|
||||||
|
})
|
||||||
|
->in('Unit');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -26,9 +35,9 @@
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
expect()->extend('toBeOne', function () {
|
//expect()->extend('toBeOne', function () {
|
||||||
return $this->toBe(1);
|
// return $this->toBe(1);
|
||||||
});
|
//});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
92
tests/Unit/InvoiceTest.php
Normal file
92
tests/Unit/InvoiceTest.php
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Enums\InvoiceStatus;
|
||||||
|
use App\Filament\Admin\Resources\InvoiceResource\Pages\CreateInvoice;
|
||||||
|
use App\Models\Customer;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Order;
|
||||||
|
use App\Models\ProductService;
|
||||||
|
use App\Models\TaxRate;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('can create an invoice', function () {
|
||||||
|
$user = User::factory(['is_admin' => true])->create();
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
$customer = Customer::factory()->create(); // Generates a customer
|
||||||
|
$pst_rate = TaxRate::where('name', 'PST')->value('value') ?? 0;
|
||||||
|
$gst_rate = TaxRate::where('name', 'GST')->value('value') ?? 0;
|
||||||
|
|
||||||
|
$formData = [
|
||||||
|
'customer_id' => $customer->id,
|
||||||
|
'date' => now()->toDateString(),
|
||||||
|
'due_date' => now()->addDays(7)->toDateString(),
|
||||||
|
'status' => InvoiceStatus::UNPAID->value,
|
||||||
|
'has_gst' => true,
|
||||||
|
'has_pst' => true,
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->livewire(CreateInvoice::class)
|
||||||
|
->fillForm($formData)
|
||||||
|
->call('create')
|
||||||
|
->assertHasNoErrors();
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('invoices', [
|
||||||
|
'internal_id' => 'INV400001',
|
||||||
|
'customer_id' => $formData['customer_id'],
|
||||||
|
'status' => $formData['status'],
|
||||||
|
'has_gst' => $formData['has_gst'],
|
||||||
|
'has_pst' => $formData['has_pst'],
|
||||||
|
'gst_rate' => $gst_rate,
|
||||||
|
'pst_rate' => $pst_rate,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$invoice = Invoice::where('internal_id', 'INV400001')->firstOrFail();
|
||||||
|
|
||||||
|
$this->assertEquals($invoice->orders->isEmpty(), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can add orders to an invoice', function () {
|
||||||
|
$customer = Customer::factory()->create();
|
||||||
|
$invoice = Invoice::factory()->create(['customer_id' => $customer->id]);
|
||||||
|
$orders = Order::factory()->for($customer)->count(3)->create();
|
||||||
|
|
||||||
|
$invoice->orders()->saveMany($orders);
|
||||||
|
|
||||||
|
$this->assertEquals($invoice->orders->count(), 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('correctly calculates tax amounts', function () {
|
||||||
|
$customer = Customer::factory()->create();
|
||||||
|
$order = Order::factory()->for($customer)->create();
|
||||||
|
$services = ProductService::factory()->count(3)->create(['order_id' => $order->id]);
|
||||||
|
|
||||||
|
$invoice = Invoice::factory(['has_gst' => true, 'has_pst' => true])->create(['customer_id' => $customer->id]);
|
||||||
|
$invoice->orders()->save($order);
|
||||||
|
|
||||||
|
$invoice->calculateTotals(); //FIXME this shouldn't be necessary
|
||||||
|
|
||||||
|
$subtotal = $order->total_service_price;
|
||||||
|
$pst_amount = $subtotal * $invoice->pst_rate / 100;
|
||||||
|
$gst_amount = $subtotal * $invoice->gst_rate / 100;
|
||||||
|
$total = $subtotal + $pst_amount + $gst_amount;
|
||||||
|
|
||||||
|
$this->assertSame($invoice->subtotal, $subtotal);
|
||||||
|
$this->assertSame($invoice->gst_amount, $gst_amount);
|
||||||
|
$this->assertSame($invoice->pst_amount, $pst_amount);
|
||||||
|
$this->assertSame($invoice->total, $total);
|
||||||
|
});
|
||||||
|
it('correctly re-calculates tax amounts when an order gets added', function () {});
|
||||||
|
|
||||||
|
it('correctly re-calculates tax amounts when an order gets removed', function () {});
|
||||||
|
|
||||||
|
it('correctly re-calculates tax amounts when an order\'s product services get added', function () {});
|
||||||
|
|
||||||
|
it('correctly re-calculates tax amounts when an order\'s product service\'s quantity gets changed', function () {});
|
||||||
|
|
||||||
|
it('correctly re-calculates tax amounts when an order\'s product service\'s amount gets changed', function () {});
|
||||||
|
|
||||||
|
it('correctly re-calculates tax amounts when an order\'s product services get removed', function () {});
|
@ -15,14 +15,17 @@
|
|||||||
use App\Models\ServiceFile;
|
use App\Models\ServiceFile;
|
||||||
use App\Models\ServiceType;
|
use App\Models\ServiceType;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||||
|
|
||||||
use function Pest\Livewire\livewire;
|
use function Pest\Livewire\livewire;
|
||||||
|
|
||||||
|
uses(DatabaseMigrations::class);
|
||||||
|
|
||||||
it('can create an order and all associated models and save it to the database', function () {
|
it('can create an order and all associated models and save it to the database', function () {
|
||||||
$type = fake()->randomElement(OrderType::cases());
|
$type = fake()->randomElement(OrderType::cases());
|
||||||
$status = fake()->randomElement(OrderStatus::cases());
|
$status = fake()->randomElement(OrderStatus::cases());
|
||||||
$customer = Customer::factory()->create();
|
$customer = Customer::factory()->create();
|
||||||
$contact = Contact::factory()->for($customer)->create();
|
// $contact = Contact::factory()->for($customer)->create();
|
||||||
$attributes = array_map(fn ($case) => $case->value, OrderAttributes::cases());
|
$attributes = array_map(fn ($case) => $case->value, OrderAttributes::cases());
|
||||||
$orderDate = today();
|
$orderDate = today();
|
||||||
$dueDate = today()->addDays(10);
|
$dueDate = today()->addDays(10);
|
||||||
@ -144,15 +147,15 @@
|
|||||||
$status,
|
$status,
|
||||||
$dueDate->format('Y-m-d'),
|
$dueDate->format('Y-m-d'),
|
||||||
'Notes go here! Here\'s the notes!',
|
'Notes go here! Here\'s the notes!',
|
||||||
1,
|
true,
|
||||||
1,
|
true,
|
||||||
1,
|
true,
|
||||||
1,
|
true,
|
||||||
1,
|
true,
|
||||||
1,
|
true,
|
||||||
1,
|
true,
|
||||||
1,
|
true,
|
||||||
1,
|
true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Order Products
|
// Order Products
|
Loading…
x
Reference in New Issue
Block a user