diff --git a/app/Console/Commands/CreateClientInvoice.php b/app/Console/Commands/CreateClientInvoice.php index b6664d2..e9c0e20 100644 --- a/app/Console/Commands/CreateClientInvoice.php +++ b/app/Console/Commands/CreateClientInvoice.php @@ -92,17 +92,26 @@ public function handle() // } else { $spend = 0; // } + $managementFee = intval(str_replace(',', '', $row['management_fee'])) ?? 0; + $mediaFee = intval(str_replace(',', '', $row['media_fee'])) ?? 0; + $managementFeeAmount = $managementFee > 0 ? $managementFee / 1.08 : 0; + $mediaFeeAmount = $mediaFee > 0 ? $mediaFee / 1.08 : 0; + $invoice = ClientInvoice::updateOrCreate( ['invoice_no' => $row['invoice_no']], [ 'client_id' => $row['client_id'], - 'is_credit_card' => intval(str_replace(',', '',$row['media_fee'])) == 0 ? 1 : 0, + 'is_credit_card' => $mediaFee == 0 ? 1 : 0, 'start_date' => $startDate, 'end_date' => $endDate, - 'management_fee' => intval(str_replace(',', '',$row['management_fee'])) ?? 0, - 'media_fee' => intval(str_replace(',', '',$row['media_fee'])) ?? 0, + 'management_fee' => $managementFee, + 'management_fee_amount' => $managementFeeAmount, + 'management_fee_tax' => $managementFee - $managementFeeAmount, + 'media_fee' => $mediaFee, + 'media_fee_amount' => $mediaFeeAmount, + 'media_fee_tax' => $mediaFee - $mediaFeeAmount, 'tax_percent' => 8, - 'nett_amount' => intval(str_replace(',', '',$row['media_fee'])) > 0 ? intval(str_replace(',', '',$row['media_fee'])) / 1.08 : 0, + 'nett_amount' => $mediaFeeAmount, 'total_spending' => $spend, ] ); diff --git a/app/Console/Commands/GetGoogleCompanyDetails.php b/app/Console/Commands/GetGoogleCompanyDetails.php index 818ab7d..642ec9c 100644 --- a/app/Console/Commands/GetGoogleCompanyDetails.php +++ b/app/Console/Commands/GetGoogleCompanyDetails.php @@ -20,6 +20,7 @@ public function handle() $mccCustomerId = env('GOOGLE_ADS_LOGIN_CUSTOMER_ID'); // Manager ID without dashes $adsService = new GoogleAdsService(); $accounts = $adsService->listAccounts(); + Log::info('Fetched accounts from Google Ads', ['accounts' => $accounts]); foreach ($accounts as $account) { $company = Client::updateOrCreate( ['customer_id' => $account['id']], diff --git a/app/Http/Controllers/Api/ClientInvoiceController.php b/app/Http/Controllers/Api/ClientInvoiceController.php index 5e57768..9fc0914 100644 --- a/app/Http/Controllers/Api/ClientInvoiceController.php +++ b/app/Http/Controllers/Api/ClientInvoiceController.php @@ -36,7 +36,11 @@ public function pending(): JsonResponse 'end_date', 'payment_no', 'management_fee', + 'management_fee_amount', + 'management_fee_tax', 'media_fee', + 'media_fee_amount', + 'media_fee_tax', 'nett_amount', 'total_spending', 'created_at', @@ -72,14 +76,18 @@ public function store(Request $request): JsonResponse 'start_date' => ['nullable', 'date'], 'end_date' => ['nullable', 'date', 'after_or_equal:start_date'], 'management_fee' => ['required', 'numeric', 'min:0'], + 'management_fee_amount' => ['nullable', 'numeric', 'min:0'], + 'management_fee_tax' => ['nullable', 'numeric', 'min:0'], 'media_fee' => ['required', 'numeric', 'min:0'], - 'tax_percent' => ['nullable', 'numeric', 'min:0', 'max:100'], + 'media_fee_amount' => ['nullable', 'numeric', 'min:0'], + 'media_fee_tax' => ['nullable', 'numeric', 'min:0'], 'total_spending' => ['nullable', 'numeric', 'min:0'], ]); $mediaFee = $validated['media_fee']; - $taxPercent = $validated['tax_percent'] ?? 0; - $nettAmount = $mediaFee - ($mediaFee * ($taxPercent / 100)); + + $taxPercent = (float) ($validated['tax_percent'] ?? 0); + $nettAmount = $mediaFee / (1 + ($taxPercent / 100)); $sqlAccCode = $this->clientLookupService->normalizeSqlAccCode($validated['sql_acc_code'] ?? null); $client = ! empty($validated['client_id']) ? \App\Models\Client::find($validated['client_id']) @@ -111,8 +119,12 @@ public function store(Request $request): JsonResponse 'start_date' => $validated['start_date'] ?? null, 'end_date' => $validated['end_date'] ?? null, 'management_fee' => $validated['management_fee'], + 'management_fee_amount' => $validated['management_fee_amount'] ?? null, + 'management_fee_tax' => $validated['management_fee_tax'] ?? null, 'media_fee' => $validated['media_fee'], - 'tax_percent' => $taxPercent, + 'media_fee_amount' => $validated['media_fee_amount'] ?? null, + 'media_fee_tax' => $validated['media_fee_tax'] ?? null, + 'tax_percent' => null, 'nett_amount' => $nettAmount, 'total_spending' => $validated['total_spending'] ?? null, ]); @@ -221,7 +233,7 @@ private function formatPreviousPayment(array $payment): array $sqlAccCode = $this->paymentItemSqlAccCode($paymentItem); $estimatedTotal = $this->paymentItemEstimatedTotal($paymentItem); $exact_tax = $this->paymentItemTax($paymentItem); - $taxPercent = $this->paymentTaxPercent($paymentItem)/100 + 1; + $taxPercent = $this->paymentTaxPercent($paymentItem) / 100 + 1; $amount = $usesRepeatedPaymentAmount ? $paymentAmount * ($estimatedTotal / $estimatedItemsTotal) : (float) ($paymentItem['amount'] ?? 0); @@ -250,10 +262,10 @@ private function formatPreviousPayment(array $payment): array 'status' => $payment['status'] ?? null, 'sql_created_at' => $payment['sql_created_at'] ?? null, 'amount' => $payment['amount'] ?? null, - 'media_fee' => $totals['media_fee']/1.08, - 'management_fee' => $totals['management_fee']/1.08, - 'invoice_media_fee' => $totals['invoice_media_fee']/1.08, - 'invoice_management_fee' => $totals['invoice_management_fee']/1.08, + 'media_fee' => $totals['media_fee'] / 1.08, + 'management_fee' => $totals['management_fee'] / 1.08, + 'invoice_media_fee' => $totals['invoice_media_fee'] / 1.08, + 'invoice_management_fee' => $totals['invoice_management_fee'] / 1.08, 'invoice_number' => data_get($payment, 'invoice.invoice_number'), ]; } diff --git a/app/Http/Controllers/ClientInvoiceController.php b/app/Http/Controllers/ClientInvoiceController.php index dca7621..99e9eae 100644 --- a/app/Http/Controllers/ClientInvoiceController.php +++ b/app/Http/Controllers/ClientInvoiceController.php @@ -86,7 +86,11 @@ public function store(Request $request) 'start_date' => ['nullable', 'date'], 'end_date' => ['nullable', 'date', 'after_or_equal:start_date'], 'management_fee' => ['required', 'numeric', 'min:0'], + 'management_fee_amount' => ['nullable', 'numeric', 'min:0'], + 'management_fee_tax' => ['nullable', 'numeric', 'min:0'], 'media_fee' => ['required', 'numeric', 'min:0'], + 'media_fee_amount' => ['nullable', 'numeric', 'min:0'], + 'media_fee_tax' => ['nullable', 'numeric', 'min:0'], 'tax_percent' => ['nullable', 'numeric', 'min:0', 'max:100'], 'total_spending' => ['nullable', 'numeric', 'min:0'], ]); @@ -95,8 +99,8 @@ public function store(Request $request) abort_unless($this->hierarchyService->canViewClient(Auth::user(), $client), 403); $mediaFee = $validated['media_fee']; - $taxPercent = $validated['tax_percent'] ?? 0; - $nettAmount = $mediaFee - ($mediaFee * ($taxPercent / 100)); + $taxPercent = (float) ($validated['tax_percent'] ?? 0); + $nettAmount = $mediaFee / (1 + ($taxPercent / 100)); $invoice = ClientInvoice::create([ 'client_id' => $validated['client_id'], @@ -109,7 +113,11 @@ public function store(Request $request) 'start_date' => $validated['start_date'] ?? null, 'end_date' => $validated['end_date'] ?? null, 'management_fee' => $validated['management_fee'], + 'management_fee_amount' => $validated['management_fee_amount'] ?? null, + 'management_fee_tax' => $validated['management_fee_tax'] ?? null, 'media_fee' => $validated['media_fee'], + 'media_fee_amount' => $validated['media_fee_amount'] ?? null, + 'media_fee_tax' => $validated['media_fee_tax'] ?? null, 'tax_percent' => $taxPercent, 'nett_amount' => $nettAmount, 'total_spending' => $validated['total_spending'] ?? null, @@ -145,15 +153,20 @@ public function update(Request $request, ClientInvoice $invoice) 'end_date' => ['nullable', 'date', 'after_or_equal:start_date'], 'amount' => ['required', 'numeric', 'min:0'], 'management_fee' => ['required', 'numeric', 'min:0'], + 'management_fee_amount' => ['nullable', 'numeric', 'min:0'], + 'management_fee_tax' => ['nullable', 'numeric', 'min:0'], 'media_fee' => ['required', 'numeric', 'min:0'], + 'media_fee_amount' => ['nullable', 'numeric', 'min:0'], + 'media_fee_tax' => ['nullable', 'numeric', 'min:0'], 'tax_percent' => ['nullable', 'numeric', 'min:0', 'max:100'], + 'nett_amount' => ['nullable', 'numeric', 'min:0'], 'total_spending' => ['nullable', 'numeric', 'min:0'], ]); $managementFee = $validated['management_fee']; $mediaFee = $validated['media_fee']; $taxPercent = (float) ($validated['tax_percent'] ?? 0); - $nettAmount = $mediaFee / (1 + ($taxPercent / 100)); + $nettAmount = $validated['nett_amount'] ?? ($mediaFee / (1 + ($taxPercent / 100))); $invoice->update([ 'invoice_no' => $validated['invoice_no'], @@ -171,6 +184,10 @@ public function update(Request $request, ClientInvoice $invoice) 'total_spending' => $validated['total_spending'] ?? null, ]); + if(empty($invoice->approved_at)) { + $this->approvalService->approve($invoice); + } + return redirect() ->route('google-ads.accounts.show', ['id' => $invoice->client->customer_id]) ->with('message-info', 'Invoice updated successfully.'); @@ -315,10 +332,6 @@ public function storeClient(Request $request, ClientInvoice $invoice) $selectedClientIsLinked = Client::query() ->where('id', $validated['client_id']) - ->whereHas('customers', function ($query) { - $query->whereNotNull('sql_acc_code') - ->where('sql_acc_code', '!=', ''); - }) ->exists(); if ($selectedClientIsLinked) { diff --git a/app/Http/Controllers/GoogleAdsController.php b/app/Http/Controllers/GoogleAdsController.php index db6d861..55b11f2 100644 --- a/app/Http/Controllers/GoogleAdsController.php +++ b/app/Http/Controllers/GoogleAdsController.php @@ -250,7 +250,7 @@ private function hydrateClient(array $account): array 'time_zone' => $account['time_zone'], ] ); - + // dd($localClient); $localClient->load(['assignations.user', 'invoices']); $assignments = $localClient->assignations @@ -327,7 +327,11 @@ private function hydrateClient(array $account): array 'amount' => $invoice->amount, 'total_spend' => number_format($totalInvoiceSpend, 2, '.', ''), 'management_fee' => $invoice->management_fee, + 'management_fee_amount' => $invoice->management_fee_amount, + 'management_fee_tax' => $invoice->management_fee_tax, 'media_fee' => $invoice->media_fee, + 'media_fee_amount' => $invoice->media_fee_amount, + 'media_fee_tax' => $invoice->media_fee_tax, 'tax_percent' => $invoice->tax_percent, 'nett_amount' => $invoice->nett_amount, 'total_spending' => $invoice->total_spending, @@ -467,17 +471,26 @@ public function insertCSVDataToDB() } } } + $managementFee = intval($row['management_fee']); + $mediaFee = intval($row['media_fee']); + $managementFeeAmount = $managementFee > 0 ? $managementFee / 1.08 : 0; + $mediaFeeAmount = $mediaFee > 0 ? $mediaFee / 1.08 : 0; + ClientInvoice::updateOrCreate( ['invoice_no' => $row['invoice_no']], [ 'client_id' => $row['client_id'], - 'is_credit_card' => intval($row['media_fee']) == 0 ? 1 : 0, + 'is_credit_card' => $mediaFee == 0 ? 1 : 0, 'start_date' => $startDate, 'end_date' => $endDate, - 'management_fee' => intval($row['management_fee']), - 'media_fee' => intval($row['media_fee']), + 'management_fee' => $managementFee, + 'management_fee_amount' => $managementFeeAmount, + 'management_fee_tax' => $managementFee - $managementFeeAmount, + 'media_fee' => $mediaFee, + 'media_fee_amount' => $mediaFeeAmount, + 'media_fee_tax' => $mediaFee - $mediaFeeAmount, 'tax_percent' => 8, - 'nett_amount' => intval($row['media_fee']) > 0 ? intval($row['media_fee']) / 1.08 : 0, + 'nett_amount' => $mediaFeeAmount, 'total_spending' => $spend, ] ); diff --git a/app/Http/Controllers/Management/RoleController.php b/app/Http/Controllers/Management/RoleController.php index 942d648..99eef1f 100644 --- a/app/Http/Controllers/Management/RoleController.php +++ b/app/Http/Controllers/Management/RoleController.php @@ -64,21 +64,28 @@ public function edit(int $id): Response { $role = Role::findOrFail($id); - // 1. Get all permissions with their "checked" state - $permissions = Permission::all()->map(function ($permission) use ($role) { - return [ - 'id' => $permission->id, - 'name' => $permission->name, // e.g. "user.create" - 'description' => $permission->description, - 'checked' => $role->hasPermissionTo($permission->name), - ]; - }); + $permissions = Permission::query() + ->orderBy('group') + ->orderBy('name') + ->get() + ->map(function ($permission) use ($role) { + $group = $permission->group + ?: $permission->group_name + ?: str($permission->name)->before('.')->headline()->toString(); + + return [ + 'id' => $permission->id, + 'name' => $permission->name, + 'group' => $group, + 'group_name' => $permission->group_name, + 'description' => $permission->description, + 'checked' => $role->hasPermissionTo($permission->name), + ]; + }); - // 2. Group them by the prefix (the part before the dot) $grouped = $permissions->groupBy(function ($item) { - return explode('.', $item['name'])[0]; + return $item['group']; })->map(function ($group) { - // 3. Force it to be a sequential array so JS sees it as [] return $group->values()->toArray(); }); diff --git a/app/Models/ClientInvoice.php b/app/Models/ClientInvoice.php index 318cce4..2f70566 100644 --- a/app/Models/ClientInvoice.php +++ b/app/Models/ClientInvoice.php @@ -26,7 +26,11 @@ class ClientInvoice extends Model 'amount', 'tax_percent', 'media_fee', + 'media_fee_amount', + 'media_fee_tax', 'management_fee', + 'management_fee_amount', + 'management_fee_tax', 'nett_amount', 'total_spending', ]; @@ -40,7 +44,11 @@ class ClientInvoice extends Model 'amount' => 'decimal:2', 'tax_percent' => 'decimal:2', 'media_fee' => 'decimal:2', + 'media_fee_amount' => 'decimal:2', + 'media_fee_tax' => 'decimal:2', 'management_fee' => 'decimal:2', + 'management_fee_amount' => 'decimal:2', + 'management_fee_tax' => 'decimal:2', 'nett_amount' => 'decimal:2', 'total_spending' => 'decimal:2', ]; diff --git a/app/Services/GoogleAdsService.php b/app/Services/GoogleAdsService.php index fd7c189..cbe83e4 100644 --- a/app/Services/GoogleAdsService.php +++ b/app/Services/GoogleAdsService.php @@ -108,7 +108,6 @@ public function listCampaigns(string $clientCustomerId): array { $client = $this->buildClient($this->loginCustomerId); $service = $client->getGoogleAdsServiceClient(); - $customerId = str_replace('-', '', $clientCustomerId); $query = <<search($request); + $campaigns = []; foreach ($response->iterateAllElements() as $row) { $c = $row->getCampaign(); diff --git a/bootstrap/app.php b/bootstrap/app.php index 34a6bb8..a46239b 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -6,6 +6,8 @@ use Illuminate\Foundation\Configuration\Exceptions; use Illuminate\Foundation\Configuration\Middleware; use Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets; +use Spatie\Permission\Middleware\PermissionMiddleware; +use Spatie\Permission\Middleware\RoleMiddleware; return Application::configure(basePath: dirname(__DIR__)) ->withRouting( @@ -15,6 +17,11 @@ health: '/up', ) ->withMiddleware(function (Middleware $middleware): void { + $middleware->alias([ + 'permission' => PermissionMiddleware::class, + 'role' => RoleMiddleware::class, + ]); + $middleware->encryptCookies(except: ['appearance', 'sidebar_state']); $middleware->web(append: [ diff --git a/database/migrations/2026_05_22_144807_add_fee_amount_tax_columns_to_client_invoices_table.php b/database/migrations/2026_05_22_144807_add_fee_amount_tax_columns_to_client_invoices_table.php new file mode 100644 index 0000000..0f0021f --- /dev/null +++ b/database/migrations/2026_05_22_144807_add_fee_amount_tax_columns_to_client_invoices_table.php @@ -0,0 +1,68 @@ +decimal('management_fee_amount', 10, 2)->nullable()->after('management_fee'); + }); + } + + if (! Schema::hasColumn('client_invoices', 'management_fee_tax')) { + Schema::table('client_invoices', function (Blueprint $table) { + $table->decimal('management_fee_tax', 10, 2)->nullable()->after('management_fee_amount'); + }); + } + + if (! Schema::hasColumn('client_invoices', 'media_fee_amount')) { + Schema::table('client_invoices', function (Blueprint $table) { + $table->decimal('media_fee_amount', 10, 2)->nullable()->after('media_fee'); + }); + } + + if (! Schema::hasColumn('client_invoices', 'media_fee_tax')) { + Schema::table('client_invoices', function (Blueprint $table) { + $table->decimal('media_fee_tax', 10, 2)->nullable()->after('media_fee_amount'); + }); + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + if (Schema::hasColumn('client_invoices', 'media_fee_tax')) { + Schema::table('client_invoices', function (Blueprint $table) { + $table->dropColumn('media_fee_tax'); + }); + } + + if (Schema::hasColumn('client_invoices', 'media_fee_amount')) { + Schema::table('client_invoices', function (Blueprint $table) { + $table->dropColumn('media_fee_amount'); + }); + } + + if (Schema::hasColumn('client_invoices', 'management_fee_tax')) { + Schema::table('client_invoices', function (Blueprint $table) { + $table->dropColumn('management_fee_tax'); + }); + } + + if (Schema::hasColumn('client_invoices', 'management_fee_amount')) { + Schema::table('client_invoices', function (Blueprint $table) { + $table->dropColumn('management_fee_amount'); + }); + } + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index fc5c034..ee7eddd 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -15,7 +15,9 @@ public function run(): void { // User::factory(10)->create(); - User::firstOrCreate( + $this->call(RoleSeeder::class); + + $user = User::firstOrCreate( ['email' => 'test@example.com'], [ 'name' => 'Test User', @@ -23,5 +25,7 @@ public function run(): void 'email_verified_at' => now(), ] ); + + $user->assignRole('Admin'); } } diff --git a/database/seeders/RoleSeeder.php b/database/seeders/RoleSeeder.php index de9956a..1e724a4 100644 --- a/database/seeders/RoleSeeder.php +++ b/database/seeders/RoleSeeder.php @@ -2,12 +2,10 @@ namespace Database\Seeders; -use App\Models\User; use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; -use Illuminate\Support\Facades\Hash; +use Spatie\Permission\PermissionRegistrar; class RoleSeeder extends Seeder { @@ -16,8 +14,51 @@ class RoleSeeder extends Seeder */ public function run(): void { - $adminRole = Role::create(['name' => 'Admin','guard_name' => 'web']); - $salesRole = Role::create(['name' => 'Sales' ,'guard_name' => 'web']); - $socialMedia = Role::create(['name' => 'Social Media Specialist','guard_name' => 'web']); + app(PermissionRegistrar::class)->forgetCachedPermissions(); + + $permissions = [ + ['name' => 'dashboard.view', 'group' => 'Dashboard', 'description' => 'View dashboard'], + ['name' => 'google-ads.accounts.view', 'group' => 'Google Ads Accounts', 'description' => 'View Google Ads accounts'], + ['name' => 'google-ads.accounts.sync', 'group' => 'Google Ads Accounts', 'description' => 'Sync Google account records'], + ['name' => 'google-ads.accounts.update', 'group' => 'Google Ads Accounts', 'description' => 'Update Google Ads account assignment details'], + ['name' => 'google-ads.activities.create', 'group' => 'Google Ads Activities', 'description' => 'Create account activities'], + ['name' => 'google-ads.activities.update', 'group' => 'Google Ads Activities', 'description' => 'Update account activities'], + ['name' => 'google-ads.activities.complete', 'group' => 'Google Ads Activities', 'description' => 'Mark account activities as complete'], + ['name' => 'google-ads.activities.delete', 'group' => 'Google Ads Activities', 'description' => 'Delete account activities'], + ['name' => 'google-ads.import', 'group' => 'Google Ads Accounts', 'description' => 'Import Google Ads data'], + ['name' => 'google.reports.view', 'group' => 'Google Reports', 'description' => 'View Google campaign reports'], + ['name' => 'client-invoices.create', 'group' => 'Client Invoices', 'description' => 'Create client invoices'], + ['name' => 'client-invoices.create-client', 'group' => 'Client Invoices', 'description' => 'Create clients from pending invoices'], + ['name' => 'client-invoices.update', 'group' => 'Client Invoices', 'description' => 'Update client invoices'], + ['name' => 'client-invoices.approve', 'group' => 'Client Invoices', 'description' => 'Approve client invoices'], + ['name' => 'client-invoices.delete', 'group' => 'Client Invoices', 'description' => 'Delete client invoices'], + ['name' => 'client-invoices.view-pdf', 'group' => 'Client Invoices', 'description' => 'View invoice PDF'], + ['name' => 'clients.adjustments.create', 'group' => 'Client Adjustments', 'description' => 'Create client invoice adjustments'], + ['name' => 'clients.adjustments.delete', 'group' => 'Client Adjustments', 'description' => 'Delete client invoice adjustments'], + ['name' => 'management.roles.view', 'group' => 'Role Management', 'description' => 'View roles'], + ['name' => 'management.roles.update', 'group' => 'Role Management', 'description' => 'Update role permissions'], + ['name' => 'management.users.view', 'group' => 'User Management', 'description' => 'View users'], + ['name' => 'management.users.create', 'group' => 'User Management', 'description' => 'Create users'], + ['name' => 'management.users.update', 'group' => 'User Management', 'description' => 'Update users'], + ]; + + foreach ($permissions as $permission) { + Permission::query()->updateOrCreate( + ['name' => $permission['name'], 'guard_name' => 'web'], + [ + 'group' => $permission['group'], + 'group_name' => $permission['group'], + 'description' => $permission['description'], + ], + ); + } + + $adminRole = Role::query()->firstOrCreate(['name' => 'Admin', 'guard_name' => 'web']); + Role::query()->firstOrCreate(['name' => 'Sales', 'guard_name' => 'web']); + Role::query()->firstOrCreate(['name' => 'Social Media Specialist', 'guard_name' => 'web']); + + $adminRole->syncPermissions(Permission::query()->pluck('name')->all()); + + app(PermissionRegistrar::class)->forgetCachedPermissions(); } } diff --git a/resources/js/forms/account/InvoiceForm.tsx b/resources/js/forms/account/InvoiceForm.tsx index 93938f1..a4ff965 100644 --- a/resources/js/forms/account/InvoiceForm.tsx +++ b/resources/js/forms/account/InvoiceForm.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react"; import { InertiaFormProps } from "@inertiajs/react"; import { route } from "ziggy-js"; import axios from "axios"; -import { Button, Stack, TextInput, NumberInput, Loader, Select, Switch, Text } from "@mantine/core"; +import { Button, Group, Stack, TextInput, NumberInput, Loader, Select, Switch, Text } from "@mantine/core"; import { DateInput } from "@mantine/dates"; import { IconDeviceFloppy } from "@tabler/icons-react"; import dayjs from "dayjs"; @@ -17,11 +17,16 @@ export interface InvoiceFormValues { end_date: string; amount: string; management_fee: string; + management_fee_amount?: string; + management_fee_tax?: string; media_fee: string; + media_fee_amount?: string; + media_fee_tax?: string; tax_percent: string; total_spending: string; client_id?: string; customer_id?: string; + nett_amount: string; } interface InvoiceOption { @@ -45,13 +50,30 @@ export default function InvoiceForm({ const formatDate = (value: string) => (value ? dayjs(value).toDate() : null); const [fetchingSpend, setFetchingSpend] = useState(false); + const parseAmount = (value?: string) => { + const parsed = Number.parseFloat(value ?? ""); + + return Number.isFinite(parsed) ? parsed : 0; + }; + + const formatAmount = (value: number) => value.toFixed(2); + + const calculateNettAmount = () => { + const mediaFeeAmount = form.data.media_fee; + const calculated = formatAmount( + parseAmount(mediaFeeAmount) / (1 + parseAmount(form.data.tax_percent) / 100) + ); + + form.setData("nett_amount", calculated); + }; + useEffect(() => { if (!form.data.is_credit_card) return; // Credit-card invoices can be fee-free; normalize fields to 0 for convenience. - if (form.data.management_fee !== "0") form.setData("management_fee", "0"); + // if (form.data.management_fee !== "0") form.setData("management_fee", "0"); if (form.data.media_fee !== "0") form.setData("media_fee", "0"); - if (form.data.tax_percent !== "0") form.setData("tax_percent", "0"); + // if (form.data.tax_percent !== "0") form.setData("tax_percent", "0"); }, [form.data.is_credit_card]); useEffect(() => { @@ -183,6 +205,21 @@ export default function InvoiceForm({ required /> + + form.setData("nett_amount", value?.toString() ?? "")} + error={form.errors.nett_amount} + required + style={{ flex: 1 }} + /> + + + Additional Info - form.setData("is_credit_card", event.currentTarget.checked)} - /> + + form.setData("is_credit_card", event.currentTarget.checked)} + /> + Credit card + - form.setData("is_paid", event.currentTarget.checked)} - /> + /> */} - )} + )} */}