From bf5b544ca33f9fbc057429fb2573abac6d9403c0 Mon Sep 17 00:00:00 2001 From: mchev Date: Sun, 4 May 2025 02:24:56 +0200 Subject: [PATCH] Adding Flat Tax support with fixed amount (#253) * Possibility to set a fixed amount on tax types settings * Pint and manage flat taxes on items * Fix display errors and handle global taxes * Tests * Pint with PHP 8.2 cause with PHP 8.3 version it cause workflow error * Merging percent and fixed amount into one column * Now display the currency on SelectTaxPopup on fixed taxes --- app/Http/Requests/TaxTypeRequest.php | 11 ++- app/Http/Resources/TaxResource.php | 2 + app/Http/Resources/TaxTypeResource.php | 2 + app/Models/Invoice.php | 1 + app/Models/Tax.php | 1 + app/Models/TaxType.php | 1 + database/factories/TaxTypeFactory.php | 2 + ...55_update_taxes_to_handle_fixed_amount.php | 36 +++++++++ lang/en.json | 10 ++- .../CreateItemRowTax.vue | 33 +++++++- .../estimate-invoice-common/CreateTotal.vue | 15 +++- .../CreateTotalTaxes.vue | 9 ++- .../SelectTaxPopup.vue | 14 +++- .../components/modal-components/ItemModal.vue | 18 ++++- .../modal-components/TaxTypeModal.vue | 76 +++++++++++++++---- resources/scripts/admin/stores/tax-type.js | 4 + .../scripts/admin/views/items/Create.vue | 18 ++++- .../admin/views/settings/TaxTypesSetting.vue | 27 ++++++- .../app/pdf/estimate/partials/table.blade.php | 12 ++- .../app/pdf/invoice/partials/table.blade.php | 12 ++- tests/Feature/Admin/ItemTest.php | 28 +++++++ tests/Feature/Admin/TaxTypeTest.php | 13 ++++ 22 files changed, 306 insertions(+), 39 deletions(-) create mode 100644 database/migrations/2024_12_11_102055_update_taxes_to_handle_fixed_amount.php diff --git a/app/Http/Requests/TaxTypeRequest.php b/app/Http/Requests/TaxTypeRequest.php index 63605c4c..c16be432 100644 --- a/app/Http/Requests/TaxTypeRequest.php +++ b/app/Http/Requests/TaxTypeRequest.php @@ -28,8 +28,17 @@ class TaxTypeRequest extends FormRequest ->where('type', TaxType::TYPE_GENERAL) ->where('company_id', $this->header('company')), ], - 'percent' => [ + 'calculation_type' => [ 'required', + Rule::in(['percentage', 'fixed']), + ], + 'percent' => [ + 'nullable', + 'numeric', + ], + 'fixed_amount' => [ + 'nullable', + 'numeric', ], 'description' => [ 'nullable', diff --git a/app/Http/Resources/TaxResource.php b/app/Http/Resources/TaxResource.php index fe330850..d6e5ca61 100644 --- a/app/Http/Resources/TaxResource.php +++ b/app/Http/Resources/TaxResource.php @@ -25,6 +25,8 @@ class TaxResource extends JsonResource 'name' => $this->name, 'amount' => $this->amount, 'percent' => $this->percent, + 'calculation_type' => $this->calculation_type, + 'fixed_amount' => $this->fixed_amount, 'compound_tax' => $this->compound_tax, 'base_amount' => $this->base_amount, 'currency_id' => $this->currency_id, diff --git a/app/Http/Resources/TaxTypeResource.php b/app/Http/Resources/TaxTypeResource.php index 4a735205..a553c647 100644 --- a/app/Http/Resources/TaxTypeResource.php +++ b/app/Http/Resources/TaxTypeResource.php @@ -17,6 +17,8 @@ class TaxTypeResource extends JsonResource 'id' => $this->id, 'name' => $this->name, 'percent' => $this->percent, + 'fixed_amount' => $this->fixed_amount, + 'calculation_type' => $this->calculation_type, 'type' => $this->type, 'compound_tax' => $this->compound_tax, 'collective_tax' => $this->collective_tax, diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 5f2956b7..ae24c30a 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -521,6 +521,7 @@ class Invoice extends Model implements HasMedia public static function createTaxes($invoice, $taxes) { + $exchange_rate = $invoice->exchange_rate; foreach ($taxes as $tax) { diff --git a/app/Models/Tax.php b/app/Models/Tax.php index c4711123..ae5682c6 100644 --- a/app/Models/Tax.php +++ b/app/Models/Tax.php @@ -21,6 +21,7 @@ class Tax extends Model return [ 'amount' => 'integer', 'percent' => 'float', + 'fixed_amount' => 'integer', ]; } diff --git a/app/Models/TaxType.php b/app/Models/TaxType.php index 30dc7392..85480f0e 100644 --- a/app/Models/TaxType.php +++ b/app/Models/TaxType.php @@ -19,6 +19,7 @@ class TaxType extends Model { return [ 'percent' => 'float', + 'fixed_amount' => 'integer', 'compound_tax' => 'boolean', ]; } diff --git a/database/factories/TaxTypeFactory.php b/database/factories/TaxTypeFactory.php index 7af2321b..895e0fdb 100644 --- a/database/factories/TaxTypeFactory.php +++ b/database/factories/TaxTypeFactory.php @@ -22,8 +22,10 @@ class TaxTypeFactory extends Factory { return [ 'name' => $this->faker->word(), + 'calculation_type' => 'percentage', 'company_id' => User::find(1)->companies()->first()->id, 'percent' => $this->faker->numberBetween($min = 0, $max = 100), + 'fixed_amount' => null, 'description' => $this->faker->text(), 'compound_tax' => 0, 'collective_tax' => 0, diff --git a/database/migrations/2024_12_11_102055_update_taxes_to_handle_fixed_amount.php b/database/migrations/2024_12_11_102055_update_taxes_to_handle_fixed_amount.php new file mode 100644 index 00000000..961b46b4 --- /dev/null +++ b/database/migrations/2024_12_11_102055_update_taxes_to_handle_fixed_amount.php @@ -0,0 +1,36 @@ +enum('calculation_type', ['percentage', 'fixed'])->default('percentage')->after('name'); + $table->integer('fixed_amount')->nullable()->after('percent'); + $table->decimal('percent', 5, 2)->nullable()->change(); + }); + + Schema::table('taxes', function (Blueprint $table) { + $table->enum('calculation_type', ['percentage', 'fixed'])->default('percentage')->after('name'); + $table->integer('fixed_amount')->nullable()->after('percent'); + $table->decimal('percent', 5, 2)->nullable()->change(); + }); + } + + public function down() + { + Schema::table('tax_types', function (Blueprint $table) { + $table->dropColumn(['calculation_type', 'fixed_amount']); + $table->decimal('percent', 5, 2)->change(); + }); + + Schema::table('taxes', function (Blueprint $table) { + $table->dropColumn(['calculation_type', 'fixed_amount']); + $table->decimal('percent', 5, 2)->change(); + }); + } +}; diff --git a/lang/en.json b/lang/en.json index 92445c8d..84650b9d 100644 --- a/lang/en.json +++ b/lang/en.json @@ -161,7 +161,10 @@ "name": "Name", "description": "Description", "percent": "Percent", - "compound_tax": "Compound Tax" + "compound_tax": "Compound Tax", + "percentage": "Percentage", + "fixed_amount": "Fixed Amount", + "tax_type": "Tax Type" }, "global_search": { "search": "Search...", @@ -1205,7 +1208,12 @@ "tax_per_item": "Tax Per Item", "tax_name": "Tax Name", "compound_tax": "Compound Tax", + "amount": "Amount", "percent": "Percent", + "fixed_amount": "Fixed Amount", + "calculation_type": "Calculation Type", + "percentage": "Percentage", + "fixed": "Fixed", "action": "Action", "tax_setting_description": "Enable this if you want to add taxes to individual invoice items. By default, taxes are added directly to the invoice.", "created_message": "Tax type created successfully", diff --git a/resources/scripts/admin/components/estimate-invoice-common/CreateItemRowTax.vue b/resources/scripts/admin/components/estimate-invoice-common/CreateItemRowTax.vue index eecd3e5f..e212d955 100644 --- a/resources/scripts/admin/components/estimate-invoice-common/CreateItemRowTax.vue +++ b/resources/scripts/admin/components/estimate-invoice-common/CreateItemRowTax.vue @@ -19,12 +19,24 @@ >