diff --git a/app/Console/Commands/GeneratePayrollCommand.php b/app/Console/Commands/GeneratePayrollCommand.php index 30f8d04..82d0630 100644 --- a/app/Console/Commands/GeneratePayrollCommand.php +++ b/app/Console/Commands/GeneratePayrollCommand.php @@ -32,8 +32,8 @@ public function handle(): int return Command::FAILURE; } - $employees = Employee::whereHas('user', fn($q) => $q->where('is_active', true)) - ->where(fn($q) => $q->whereNull('resign_date')->orWhere('resign_date', '>=', $now->toDateString())) + $employees = Employee::whereHas('user', fn ($q) => $q->where('is_active', true)) + ->where(fn ($q) => $q->whereNull('resign_date')->orWhere('resign_date', '>=', $now->toDateString())) ->get(); $existingPayrollEmployeeIds = Payroll::where('payroll_period_id', $period->id) diff --git a/app/Http/Controllers/Admin/AdminSettingsController.php b/app/Http/Controllers/Admin/AdminSettingsController.php index be19eb0..77bac79 100644 --- a/app/Http/Controllers/Admin/AdminSettingsController.php +++ b/app/Http/Controllers/Admin/AdminSettingsController.php @@ -3,8 +3,8 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; -use App\Http\Requests\Admin\Settings\UpdateHRRequest; use App\Http\Requests\Admin\Settings\UpdateHomepageRequest; +use App\Http\Requests\Admin\Settings\UpdateHRRequest; use App\Http\Requests\Admin\Settings\UpdateMarketplaceRequest; use App\Http\Requests\Admin\Settings\UpdateSocialMediaRequest; use App\Http\Requests\Admin\Settings\UpdateSystemRequest; diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php index da23f55..a4fe56c 100644 --- a/app/Http/Controllers/Admin/RoleController.php +++ b/app/Http/Controllers/Admin/RoleController.php @@ -33,7 +33,7 @@ public function create(): Response public function store(RoleRequest $request): RedirectResponse { return $this->handleAction( - fn() => $this->service->create($request->validated()), + fn () => $this->service->create($request->validated()), 'Role berhasil ditambahkan.', 'admin.settings.roles.index' ); @@ -50,7 +50,7 @@ public function edit(Role $role): Response public function update(RoleRequest $request, Role $role): RedirectResponse { return $this->handleAction( - fn() => $this->service->update($role, $request->validated()), + fn () => $this->service->update($role, $request->validated()), 'Role berhasil diperbarui.', 'admin.settings.roles.index' ); diff --git a/app/Http/Controllers/Settings/SecurityController.php b/app/Http/Controllers/Settings/SecurityController.php index 9c11218..c4a9773 100644 --- a/app/Http/Controllers/Settings/SecurityController.php +++ b/app/Http/Controllers/Settings/SecurityController.php @@ -34,7 +34,6 @@ public function update(PasswordUpdateRequest $request): RedirectResponse Inertia::flash('toast', ['type' => 'success', 'message' => 'Kata sandi berhasil diperbarui.']); - return back(); } } diff --git a/app/Http/Requests/Admin/HR/AttendanceRequest.php b/app/Http/Requests/Admin/HR/AttendanceRequest.php index 06f86d1..361bce2 100644 --- a/app/Http/Requests/Admin/HR/AttendanceRequest.php +++ b/app/Http/Requests/Admin/HR/AttendanceRequest.php @@ -3,7 +3,6 @@ namespace App\Http\Requests\Admin\HR; use Illuminate\Foundation\Http\FormRequest; -use Override; class AttendanceRequest extends FormRequest { diff --git a/app/Http/Requests/Settings/ProfileUpdateRequest.php b/app/Http/Requests/Settings/ProfileUpdateRequest.php index 78e2bca..3616520 100644 --- a/app/Http/Requests/Settings/ProfileUpdateRequest.php +++ b/app/Http/Requests/Settings/ProfileUpdateRequest.php @@ -2,6 +2,7 @@ namespace App\Http\Requests\Settings; +use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; @@ -10,7 +11,7 @@ class ProfileUpdateRequest extends FormRequest /** * Get the validation rules that apply to the request. * - * @return array|string> + * @return array|string> */ public function rules(): array { diff --git a/app/Models/CashTransaction.php b/app/Models/CashTransaction.php index 33e0a23..8de7549 100644 --- a/app/Models/CashTransaction.php +++ b/app/Models/CashTransaction.php @@ -18,7 +18,7 @@ #[Guarded(['id'])] class CashTransaction extends Model implements HasMedia { - use HasFactory, SoftDeletes, InteractsWithMedia; + use HasFactory, InteractsWithMedia, SoftDeletes; protected function casts(): array { diff --git a/app/Models/Expense.php b/app/Models/Expense.php index acc9251..2f5ddd8 100644 --- a/app/Models/Expense.php +++ b/app/Models/Expense.php @@ -13,7 +13,7 @@ #[Guarded(['id'])] class Expense extends Model implements HasMedia { - use HasFactory, SoftDeletes, InteractsWithMedia; + use HasFactory, InteractsWithMedia, SoftDeletes; protected function casts(): array { diff --git a/app/Models/User.php b/app/Models/User.php index 9e77400..13b46e9 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -42,14 +42,14 @@ protected function active(Builder $query): void protected function name(): Attribute { return Attribute::make( - get: fn() => $this->userProfile?->full_name ?? '', + get: fn () => $this->userProfile?->full_name ?? '', ); } protected function fullName(): Attribute { return Attribute::make( - get: fn() => $this->userProfile?->full_name ?? '', + get: fn () => $this->userProfile?->full_name ?? '', ); } diff --git a/app/Services/Admin/AdminSettingsService.php b/app/Services/Admin/AdminSettingsService.php index 311f6b2..de925c8 100644 --- a/app/Services/Admin/AdminSettingsService.php +++ b/app/Services/Admin/AdminSettingsService.php @@ -3,8 +3,8 @@ namespace App\Services\Admin; use App\Services\S3PresignedService; -use App\Settings\HRSettings; use App\Settings\HomepageSettings; +use App\Settings\HRSettings; use App\Settings\MarketplaceSettings; use App\Settings\SocialMediaSettings; use App\Settings\SystemSettings; diff --git a/app/Services/Admin/HR/AttendanceService.php b/app/Services/Admin/HR/AttendanceService.php index 8072408..e8671bb 100644 --- a/app/Services/Admin/HR/AttendanceService.php +++ b/app/Services/Admin/HR/AttendanceService.php @@ -2,7 +2,6 @@ namespace App\Services\Admin\HR; -use App\Enums\LeaveRequestStatus; use App\Models\Attendance; use App\Models\LeaveRequest; use App\Services\S3PresignedService; @@ -76,6 +75,7 @@ public function getMonthStats(int $year, int $month): array $leaveStart = max($leave->start_date->timestamp, $startOfMonth->timestamp); $leaveEnd = min($leave->end_date->timestamp, $endOfMonth->timestamp); $days = Carbon::createFromTimestamp($leaveStart)->diffInDays(Carbon::createFromTimestamp($leaveEnd)) + 1; + return $carry + max(0, $days); }, 0); @@ -140,7 +140,7 @@ private function formatAttendance(Attendance $attendance): array $toArray = $attendance->toArray(); if (is_null($toArray['work_duration_minutes']) && $attendance->check_in_at) { - $checkIn = \Carbon\Carbon::parse($attendance->check_in_at); + $checkIn = Carbon::parse($attendance->check_in_at); $end = $checkIn->toDateString() === now()->toDateString() ? now() : $checkIn->copy()->endOfDay(); @@ -166,8 +166,8 @@ private function registerMedia(Attendance $attendance, string $photo, string $ty if (str_starts_with($photo, 'data:image')) { $base64 = explode(',', $photo)[1]; $imageData = base64_decode($base64); - $filename = $type . '_' . time() . '_' . uniqid() . '.jpg'; - $s3Key = 'attendances/' . $filename; + $filename = $type.'_'.time().'_'.uniqid().'.jpg'; + $s3Key = 'attendances/'.$filename; app('filesystem')->disk('s3')->put($s3Key, $imageData); $mimeType = 'image/jpeg'; diff --git a/app/Settings/HRSettings.php b/app/Settings/HRSettings.php index bb17062..2fb86e5 100644 --- a/app/Settings/HRSettings.php +++ b/app/Settings/HRSettings.php @@ -7,8 +7,11 @@ class HRSettings extends Settings { public string $scheduled_check_in_time; + public string $scheduled_check_out_time; + public int $late_penalty_amount; + public int $absent_penalty_amount; public static function group(): string diff --git a/app/Settings/HomepageSettings.php b/app/Settings/HomepageSettings.php index 59100e6..d851f7c 100644 --- a/app/Settings/HomepageSettings.php +++ b/app/Settings/HomepageSettings.php @@ -7,45 +7,71 @@ class HomepageSettings extends Settings { public string $hero_badge; + public string $hero_title_line1; + public string $hero_title_line2; + public string $hero_title_highlight; + public string $hero_description; + public string $hero_cta_primary_text; + public string $hero_cta_secondary_text; + public ?string $hero_image_url; + public string $hero_bg_text_left; + public string $hero_bg_text_right; public string $scroll_hashtag; + public string $scroll_tagline; public string $catalog_badge; + public string $catalog_title; + public string $catalog_description; + public string $catalog_search_placeholder; public string $gallery_badge; + public string $gallery_title; + public string $gallery_description; + public array $gallery_images; public string $order_guide_badge; + public string $order_guide_title; + public string $order_guide_description; + public array $order_steps; public string $about_badge; + public string $about_title; + public ?string $about_image_url; + public array $about_features; public string $contact_badge; + public string $contact_title; + public string $contact_description; + public string $contact_form_title; public string $footer_description; + public string $footer_copyright; public static function group(): string diff --git a/app/Settings/MarketplaceSettings.php b/app/Settings/MarketplaceSettings.php index b11e5e1..d79df0d 100644 --- a/app/Settings/MarketplaceSettings.php +++ b/app/Settings/MarketplaceSettings.php @@ -8,20 +8,33 @@ class MarketplaceSettings extends Settings { public MarketplaceFeeRule $tiktok_shop_platform_commission; + public MarketplaceFeeRule $tiktok_shop_logistics_service_fee; + public MarketplaceFeeRule $tiktok_shop_dynamic_commission; + public MarketplaceFeeRule $tiktok_shop_order_processing_fee; + public MarketplaceFeeRule $tiktok_shop_affiliate; + public MarketplaceFeeRule $tiktok_shop_pre_order_service_fee; public MarketplaceFeeRule $shopee_admin_fee; + public MarketplaceFeeRule $shopee_program_fee; + public MarketplaceFeeRule $shopee_shipping_savings; + public MarketplaceFeeRule $shopee_premium; + public MarketplaceFeeRule $shopee_service_fee; + public MarketplaceFeeRule $shopee_order_processing_fee; + public MarketplaceFeeRule $shopee_ams_commission_fee; + public MarketplaceFeeRule $shopee_pre_order; + public MarketplaceFeeRule $shopee_live_extra; public static function group(): string diff --git a/app/Settings/SocialMediaSettings.php b/app/Settings/SocialMediaSettings.php index 252fdb5..5255ae0 100644 --- a/app/Settings/SocialMediaSettings.php +++ b/app/Settings/SocialMediaSettings.php @@ -7,7 +7,9 @@ class SocialMediaSettings extends Settings { public ?string $instagram_url; + public ?string $facebook_url; + public ?string $tiktok_url; public static function group(): string diff --git a/app/Settings/SystemSettings.php b/app/Settings/SystemSettings.php index d3cd7ce..aa4f1d6 100644 --- a/app/Settings/SystemSettings.php +++ b/app/Settings/SystemSettings.php @@ -7,9 +7,13 @@ class SystemSettings extends Settings { public string $app_name; + public ?string $address; + public ?string $about_app; + public ?string $email; + public ?string $phone; public static function group(): string diff --git a/bootstrap/app.php b/bootstrap/app.php index 9836e43..aebdfb1 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -7,15 +7,15 @@ use Illuminate\Foundation\Configuration\Middleware; use Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets; use Illuminate\Http\Request; -use Spatie\Permission\Middleware\RoleMiddleware; use Spatie\Permission\Middleware\PermissionMiddleware; +use Spatie\Permission\Middleware\RoleMiddleware; use Spatie\Permission\Middleware\RoleOrPermissionMiddleware; return Application::configure(basePath: dirname(__DIR__)) ->withRouting( - web: __DIR__ . '/../routes/web.php', - api: __DIR__ . '/../routes/api.php', - commands: __DIR__ . '/../routes/console.php', + web: __DIR__.'/../routes/web.php', + api: __DIR__.'/../routes/api.php', + commands: __DIR__.'/../routes/console.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware): void { @@ -35,6 +35,6 @@ }) ->withExceptions(function (Exceptions $exceptions): void { $exceptions->shouldRenderJsonWhen( - fn(Request $request) => $request->is('api/*') || $request->expectsJson(), + fn (Request $request) => $request->is('api/*') || $request->expectsJson(), ); })->create(); diff --git a/config/settings.php b/config/settings.php index b6e0266..c5045c4 100644 --- a/config/settings.php +++ b/config/settings.php @@ -1,5 +1,12 @@ [ 'database' => [ - 'type' => Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'type' => DatabaseSettingsRepository::class, 'model' => null, 'table' => null, 'connection' => null, ], 'redis' => [ - 'type' => Spatie\LaravelSettings\SettingsRepositories\RedisSettingsRepository::class, + 'type' => RedisSettingsRepository::class, 'connection' => null, 'prefix' => null, ], @@ -61,7 +68,7 @@ * additional prefix. */ 'cache' => [ - 'enabled' => (bool)env('SETTINGS_CACHE_ENABLED', false), + 'enabled' => (bool) env('SETTINGS_CACHE_ENABLED', false), 'store' => null, 'prefix' => null, 'ttl' => null, @@ -78,10 +85,10 @@ * your settings class isn't a default PHP type. */ 'global_casts' => [ - DateTimeInterface::class => Spatie\LaravelSettings\SettingsCasts\DateTimeInterfaceCast::class, - DateTimeZone::class => Spatie\LaravelSettings\SettingsCasts\DateTimeZoneCast::class, -// Spatie\DataTransferObject\DataTransferObject::class => Spatie\LaravelSettings\SettingsCasts\DtoCast::class, - Spatie\LaravelData\Data::class => Spatie\LaravelSettings\SettingsCasts\DataCast::class, + DateTimeInterface::class => DateTimeInterfaceCast::class, + DateTimeZone::class => DateTimeZoneCast::class, + // Spatie\DataTransferObject\DataTransferObject::class => Spatie\LaravelSettings\SettingsCasts\DtoCast::class, + Data::class => DataCast::class, ], /* diff --git a/database/seeders/RolePermissionSeeder.php b/database/seeders/RolePermissionSeeder.php index 0a47f8b..8f4cc3e 100644 --- a/database/seeders/RolePermissionSeeder.php +++ b/database/seeders/RolePermissionSeeder.php @@ -5,12 +5,13 @@ use Illuminate\Database\Seeder; use Spatie\Permission\Models\Permission; use Spatie\Permission\Models\Role; +use Spatie\Permission\PermissionRegistrar; class RolePermissionSeeder extends Seeder { public function run(): void { - app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions(); + app()[PermissionRegistrar::class]->forgetCachedPermissions(); $permissions = [ 'user' => ['view', 'create', 'update', 'delete', 'toggle-active', 'reset-password'], @@ -39,7 +40,7 @@ public function run(): void $rolePermissions = [ 'Developer' => $allPermissions, - 'Owner' => array_filter($allPermissions, fn($p) => !str_starts_with($p, 'settings.update-')), + 'Owner' => array_filter($allPermissions, fn ($p) => ! str_starts_with($p, 'settings.update-')), 'Direktur' => array_filter($allPermissions, function ($p) { return str_ends_with($p, '.view') @@ -106,7 +107,7 @@ public function run(): void || $p === 'attendance.check-out'; }), - 'Non Operator' => array_filter($allPermissions, fn($p) => str_ends_with($p, '.view')), + 'Non Operator' => array_filter($allPermissions, fn ($p) => str_ends_with($p, '.view')), ]; foreach ($rolePermissions as $roleName => $perms) { diff --git a/routes/web.php b/routes/web.php index c3df9ce..c7fe746 100644 --- a/routes/web.php +++ b/routes/web.php @@ -7,13 +7,12 @@ use App\Http\Controllers\Admin\Finance\PayrollAdjustmentController; use App\Http\Controllers\Admin\Finance\PayrollController; use App\Http\Controllers\Admin\Finance\PayrollPeriodController; -use App\Http\Controllers\Admin\Master\CategoryController; -use App\Http\Controllers\Admin\Master\CustomerController; -use App\Http\Controllers\Admin\Master\ProductController; -use App\Http\Controllers\Admin\Master\SupplierController; use App\Http\Controllers\Admin\HR\AttendanceController; use App\Http\Controllers\Admin\HR\EmployeeController; use App\Http\Controllers\Admin\HR\LeaveRequestController; +use App\Http\Controllers\Admin\Master\CategoryController; +use App\Http\Controllers\Admin\Master\CustomerController; +use App\Http\Controllers\Admin\Master\SupplierController; use App\Http\Controllers\Admin\RoleController; use Illuminate\Support\Facades\Route; diff --git a/tests/Feature/Admin/Finance/PayrollTest.php b/tests/Feature/Admin/Finance/PayrollTest.php index f19ede9..a93ba5e 100644 --- a/tests/Feature/Admin/Finance/PayrollTest.php +++ b/tests/Feature/Admin/Finance/PayrollTest.php @@ -4,7 +4,6 @@ use App\Enums\PayrollPeriodStatus; use App\Enums\PayrollStatus; use App\Models\CashAccount; -use App\Models\CashTransaction; use App\Models\Employee; use App\Models\Payroll; use App\Models\PayrollAdjustment; diff --git a/tests/Feature/Admin/HR/EmployeeTest.php b/tests/Feature/Admin/HR/EmployeeTest.php index 2a5c14b..0f0a59c 100644 --- a/tests/Feature/Admin/HR/EmployeeTest.php +++ b/tests/Feature/Admin/HR/EmployeeTest.php @@ -1,8 +1,6 @@ create(); $this->actingAs($user); - $response = $this->post(route('admin.master.categories.store'), ['name' => "ABCDE"]); + $response = $this->post(route('admin.master.categories.store'), ['name' => 'ABCDE']); $response->assertSessionHasNoErrors(); }); @@ -1710,7 +1710,7 @@ $user = User::factory()->create(); $this->actingAs($user); - $response = $this->post(route('admin.master.categories.store'), ['name' => "()【】"]); + $response = $this->post(route('admin.master.categories.store'), ['name' => '()【】']); $response->assertSessionHasNoErrors(); }); diff --git a/tests/Feature/Admin/Master/CustomerTest.php b/tests/Feature/Admin/Master/CustomerTest.php index 5455863..6f2f5ea 100644 --- a/tests/Feature/Admin/Master/CustomerTest.php +++ b/tests/Feature/Admin/Master/CustomerTest.php @@ -1,7 +1,7 @@ create(); $this->actingAs($user); - $response = $this->post(route('admin.master.customers.store'), ['name' => "ABCDE"]); + $response = $this->post(route('admin.master.customers.store'), ['name' => 'ABCDE']); $response->assertSessionHasNoErrors(); }); @@ -1683,7 +1683,7 @@ $user = User::factory()->create(); $this->actingAs($user); - $response = $this->post(route('admin.master.customers.store'), ['name' => "()【】"]); + $response = $this->post(route('admin.master.customers.store'), ['name' => '()【】']); $response->assertSessionHasNoErrors(); }); @@ -1786,14 +1786,14 @@ foreach ($phones as $phone) { $response = $this->post(route('admin.master.customers.store'), [ - 'name' => 'Customer ' . $phone, + 'name' => 'Customer '.$phone, 'phone_number' => $phone, ]); $response->assertSessionHasNoErrors(); $this->assertDatabaseHas('customers', [ - 'name' => 'Customer ' . $phone, + 'name' => 'Customer '.$phone, 'phone_number' => $phone, ]); } diff --git a/tests/Feature/Admin/Master/SupplierTest.php b/tests/Feature/Admin/Master/SupplierTest.php index 3353fbf..0b8d131 100644 --- a/tests/Feature/Admin/Master/SupplierTest.php +++ b/tests/Feature/Admin/Master/SupplierTest.php @@ -1675,7 +1675,7 @@ $user = User::factory()->create(); $this->actingAs($user); - $response = $this->post(route('admin.master.suppliers.store'), ['name' => "ABCDE"]); + $response = $this->post(route('admin.master.suppliers.store'), ['name' => 'ABCDE']); $response->assertSessionHasNoErrors(); }); @@ -1683,7 +1683,7 @@ $user = User::factory()->create(); $this->actingAs($user); - $response = $this->post(route('admin.master.suppliers.store'), ['name' => "()【】"]); + $response = $this->post(route('admin.master.suppliers.store'), ['name' => '()【】']); $response->assertSessionHasNoErrors(); }); @@ -1786,14 +1786,14 @@ foreach ($phones as $phone) { $response = $this->post(route('admin.master.suppliers.store'), [ - 'name' => 'Supplier ' . $phone, + 'name' => 'Supplier '.$phone, 'phone_number' => $phone, ]); $response->assertSessionHasNoErrors(); $this->assertDatabaseHas('suppliers', [ - 'name' => 'Supplier ' . $phone, + 'name' => 'Supplier '.$phone, 'phone_number' => $phone, ]); } diff --git a/tests/Feature/Admin/Settings/AdminSettingsTest.php b/tests/Feature/Admin/Settings/AdminSettingsTest.php index d1dcf37..13c5480 100644 --- a/tests/Feature/Admin/Settings/AdminSettingsTest.php +++ b/tests/Feature/Admin/Settings/AdminSettingsTest.php @@ -1,8 +1,8 @@ forgetCachedPermissions(); + app()[PermissionRegistrar::class]->forgetCachedPermissions(); $modules = [ 'user' => ['view', 'create', 'update', 'delete', 'toggle-active', 'reset-password'], diff --git a/tests/Feature/Settings/ProfileUpdateTest.php b/tests/Feature/Settings/ProfileUpdateTest.php index f906369..743e494 100644 --- a/tests/Feature/Settings/ProfileUpdateTest.php +++ b/tests/Feature/Settings/ProfileUpdateTest.php @@ -275,7 +275,7 @@ $response = $this ->actingAs($user) ->patch(route('profile.update'), [ - 'email' => str_repeat('a', 246) . '@example.com', + 'email' => str_repeat('a', 246).'@example.com', 'username' => 'emailmax', 'full_name' => 'Test', ]);