diff --git a/database/migrations/2026_04_07_000001_increase_tax_percent_precision_to_three_decimals.php b/database/migrations/2026_04_07_000001_increase_tax_percent_precision_to_three_decimals.php new file mode 100644 index 00000000..6ba5d92d --- /dev/null +++ b/database/migrations/2026_04_07_000001_increase_tax_percent_precision_to_three_decimals.php @@ -0,0 +1,30 @@ +decimal('percent', 5, 3)->nullable()->change(); + }); + + Schema::table('taxes', function (Blueprint $table) { + $table->decimal('percent', 5, 3)->nullable()->change(); + }); + } + + public function down(): void + { + Schema::table('tax_types', function (Blueprint $table) { + $table->decimal('percent', 5, 2)->nullable()->change(); + }); + + Schema::table('taxes', function (Blueprint $table) { + $table->decimal('percent', 5, 2)->nullable()->change(); + }); + } +}; diff --git a/resources/scripts/admin/components/modal-components/TaxTypeModal.vue b/resources/scripts/admin/components/modal-components/TaxTypeModal.vue index a2819007..0af63e40 100644 --- a/resources/scripts/admin/components/modal-components/TaxTypeModal.vue +++ b/resources/scripts/admin/components/modal-components/TaxTypeModal.vue @@ -58,15 +58,16 @@ variant="horizontal" required > - @@ -207,7 +208,38 @@ const v$ = useVuelidate( computed(() => taxTypeStore) ) +function onTaxPercentInput(val) { + v$.value.currentTaxType.percent.$touch() + + if (val === '' || val === null) { + taxTypeStore.currentTaxType.percent = null + + return + } + + const n = typeof val === 'number' ? val : parseFloat(val) + taxTypeStore.currentTaxType.percent = Number.isNaN(n) ? null : n +} + +function onTaxPercentBlur() { + const p = taxTypeStore.currentTaxType.percent + if (p === null || p === undefined || p === '') { + return + } + + const n = typeof p === 'number' ? p : parseFloat(p) + if (Number.isNaN(n)) { + return + } + + taxTypeStore.currentTaxType.percent = Math.round(n * 1000) / 1000 +} + async function submitTaxTypeData() { + if (taxTypeStore.currentTaxType.calculation_type === 'percentage') { + onTaxPercentBlur() + } + v$.value.currentTaxType.$touch() if (v$.value.currentTaxType.$invalid) { return true diff --git a/resources/scripts/admin/views/settings/TaxTypesSetting.vue b/resources/scripts/admin/views/settings/TaxTypesSetting.vue index 740dfe5b..b6fd3122 100644 --- a/resources/scripts/admin/views/settings/TaxTypesSetting.vue +++ b/resources/scripts/admin/views/settings/TaxTypesSetting.vue @@ -248,4 +248,5 @@ function openTaxModal() { refreshData: table.value && table.value.refresh, }) } + diff --git a/tests/Feature/Admin/TaxTypeTest.php b/tests/Feature/Admin/TaxTypeTest.php index 1c0c6413..0fa08dce 100644 --- a/tests/Feature/Admin/TaxTypeTest.php +++ b/tests/Feature/Admin/TaxTypeTest.php @@ -5,6 +5,7 @@ use App\Http\Requests\TaxTypeRequest; use App\Models\TaxType; use App\Models\User; use Illuminate\Support\Facades\Artisan; +use Illuminate\Support\Facades\DB; use Laravel\Sanctum\Sanctum; use function Pest\Laravel\deleteJson; @@ -110,3 +111,22 @@ test('create fixed amount tax type', function () { $this->assertDatabaseHas('tax_types', $taxType); }); + +test('create percentage tax type with three decimals', function () { + $payload = TaxType::factory()->raw([ + 'calculation_type' => 'percentage', + 'percent' => 6.625, + 'fixed_amount' => null, + ]); + + $response = postJson('api/v1/tax-types', $payload) + ->assertStatus(201); + + $taxTypeId = $response->json('data.id'); + + expect($taxTypeId)->not()->toBeNull(); + + $rawPercent = DB::table('tax_types')->where('id', $taxTypeId)->value('percent'); + + expect((string) $rawPercent)->toBe('6.625'); +});