DONE: use full name for date in letter, include password in email after membership is done, block ic_number to exclude -
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->date('leave_date')->nullable()->after('join_date');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('leave_date');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -44,7 +44,7 @@ class UserController extends BaseCrudController
|
||||
$validated['uuid'] = Str::uuid();
|
||||
$validated['password'] = Hash::make('suteraselamanya');
|
||||
|
||||
return $validated;
|
||||
return $this->applyLeaveDateForStatus($validated);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,6 +58,25 @@ class UserController extends BaseCrudController
|
||||
unset($validated['email']);
|
||||
}
|
||||
|
||||
return $this->applyLeaveDateForStatus($validated, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or clear leave_date based on membership status transitions.
|
||||
*/
|
||||
protected function applyLeaveDateForStatus(array $validated, ?User $user = null): array
|
||||
{
|
||||
$newStatus = $validated['status'] ?? $user?->status;
|
||||
$currentStatus = $user?->status;
|
||||
|
||||
if ($newStatus === 'inactive') {
|
||||
if ($currentStatus !== 'inactive') {
|
||||
$validated['leave_date'] = $validated['leave_date'] ?? now()->toDateString();
|
||||
}
|
||||
} elseif (in_array($newStatus, ['active', 'pending'], true)) {
|
||||
$validated['leave_date'] = null;
|
||||
}
|
||||
|
||||
return $validated;
|
||||
}
|
||||
|
||||
@@ -171,13 +190,27 @@ class UserController extends BaseCrudController
|
||||
$this->authorize('viewAny', $this->modelClass);
|
||||
|
||||
try {
|
||||
$request->validate([
|
||||
'join_date_from' => 'nullable|date',
|
||||
'join_date_to' => 'nullable|date',
|
||||
'leave_date_from' => 'nullable|date',
|
||||
'leave_date_to' => 'nullable|date',
|
||||
]);
|
||||
|
||||
$perPage = min((int) $request->get('per_page', 10), 500);
|
||||
$dateFilters = array_filter([
|
||||
'join_date_from' => $request->get('join_date_from'),
|
||||
'join_date_to' => $request->get('join_date_to'),
|
||||
'leave_date_from' => $request->get('leave_date_from'),
|
||||
'leave_date_to' => $request->get('leave_date_to'),
|
||||
]);
|
||||
$items = $this->userService->getPaginatedList(
|
||||
$perPage,
|
||||
$request->get('search', ''),
|
||||
$request->get('status', ''),
|
||||
$request->get('sort_by', 'id'),
|
||||
$request->get('sort_order', 'asc')
|
||||
$request->get('sort_order', 'asc'),
|
||||
$dateFilters
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
|
||||
@@ -44,6 +44,7 @@ class UserRequest extends FormRequest
|
||||
'member_number' => 'required|integer',
|
||||
'member_type' => 'required|string|max:255',
|
||||
'join_date' => 'nullable|date',
|
||||
'leave_date' => 'nullable|date',
|
||||
'birth_date' => 'nullable|date',
|
||||
'birth_place' => 'nullable|string|max:255',
|
||||
];
|
||||
@@ -74,6 +75,7 @@ class UserRequest extends FormRequest
|
||||
'member_number' => 'required|integer',
|
||||
'member_type' => 'required|string|max:255',
|
||||
'join_date' => 'nullable|date',
|
||||
'leave_date' => 'nullable|date',
|
||||
'birth_date' => 'nullable|date',
|
||||
'birth_place' => 'nullable|string|max:255',
|
||||
];
|
||||
@@ -100,6 +102,7 @@ class UserRequest extends FormRequest
|
||||
'member_number' => 'required|integer',
|
||||
'member_type' => 'required|string|max:255',
|
||||
'join_date' => 'required|date',
|
||||
'leave_date' => 'nullable|date',
|
||||
'birth_date' => 'required|date',
|
||||
'birth_place' => 'required|string|max:255',
|
||||
];
|
||||
@@ -136,6 +139,7 @@ class UserRequest extends FormRequest
|
||||
'member_type.max' => 'Jenis anggota tidak boleh melebihi 255 aksara.',
|
||||
'join_date.required' => 'Tarikh join diperlukan.',
|
||||
'join_date.date' => 'Tarikh join tidak sah.',
|
||||
'leave_date.date' => 'Tarikh berhenti tidak sah.',
|
||||
'birth_date.required' => 'Tarikh lahir diperlukan.',
|
||||
'birth_date.date' => 'Tarikh lahir tidak sah.',
|
||||
'birth_place.required' => 'Tempat lahir diperlukan.',
|
||||
|
||||
@@ -20,7 +20,8 @@ interface UserRepositoryInterface
|
||||
string $search = '',
|
||||
string $status = '',
|
||||
string $sortBy = 'name',
|
||||
string $sortOrder = 'asc'
|
||||
string $sortOrder = 'asc',
|
||||
array $dateFilters = []
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,25 @@ class UserRepository implements UserRepositoryInterface
|
||||
});
|
||||
}
|
||||
|
||||
private function applyDateRangeFilters($query, array $dateFilters): void
|
||||
{
|
||||
if (! empty($dateFilters['join_date_from'])) {
|
||||
$query->whereDate('join_date', '>=', $dateFilters['join_date_from']);
|
||||
}
|
||||
|
||||
if (! empty($dateFilters['join_date_to'])) {
|
||||
$query->whereDate('join_date', '<=', $dateFilters['join_date_to']);
|
||||
}
|
||||
|
||||
if (! empty($dateFilters['leave_date_from'])) {
|
||||
$query->whereDate('leave_date', '>=', $dateFilters['leave_date_from']);
|
||||
}
|
||||
|
||||
if (! empty($dateFilters['leave_date_to'])) {
|
||||
$query->whereDate('leave_date', '<=', $dateFilters['leave_date_to']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Users with pagination and search
|
||||
*/
|
||||
@@ -46,7 +65,8 @@ class UserRepository implements UserRepositoryInterface
|
||||
string $search = '',
|
||||
string $status = '',
|
||||
string $sortBy = 'name',
|
||||
string $sortOrder = 'asc'
|
||||
string $sortOrder = 'asc',
|
||||
array $dateFilters = []
|
||||
) {
|
||||
$allowedSortColumns = [
|
||||
'id',
|
||||
@@ -55,6 +75,8 @@ class UserRepository implements UserRepositoryInterface
|
||||
'position',
|
||||
'status',
|
||||
'member_number',
|
||||
'join_date',
|
||||
'leave_date',
|
||||
'created_at',
|
||||
'deleted_at',
|
||||
];
|
||||
@@ -73,6 +95,8 @@ class UserRepository implements UserRepositoryInterface
|
||||
$query->where('status', $status);
|
||||
}
|
||||
|
||||
$this->applyDateRangeFilters($query, $dateFilters);
|
||||
|
||||
return $query->paginate($perPage);
|
||||
}
|
||||
|
||||
@@ -93,6 +117,8 @@ class UserRepository implements UserRepositoryInterface
|
||||
'position',
|
||||
'status',
|
||||
'member_number',
|
||||
'join_date',
|
||||
'leave_date',
|
||||
'created_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
@@ -21,14 +21,16 @@ class UserService
|
||||
string $search,
|
||||
string $status,
|
||||
string $sortBy,
|
||||
string $sortOrder
|
||||
string $sortOrder,
|
||||
array $dateFilters = []
|
||||
): LengthAwarePaginator {
|
||||
return $this->repository->getAllWithRelationsPaginated(
|
||||
$perPage,
|
||||
$search,
|
||||
$status,
|
||||
$sortBy,
|
||||
$sortOrder
|
||||
$sortOrder,
|
||||
$dateFilters
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ class UserListResource extends JsonResource
|
||||
'member_number' => $this->member_number,
|
||||
'member_type' => $this->member_type,
|
||||
'join_date' => $this->join_date,
|
||||
'leave_date' => $this->leave_date,
|
||||
'birth_date' => $this->birth_date,
|
||||
'birth_place' => $this->birth_place,
|
||||
'created_at' => $this->created_at,
|
||||
|
||||
Reference in New Issue
Block a user