Implement FlashesEntityMessage trait across multiple controllers for consistent flash messaging. Update flash messages in various methods to utilize the new trait, enhancing code maintainability and readability. Additionally, add attribute methods in request classes for improved validation feedback.
This commit is contained in:
parent
a6e8c67910
commit
eb2047a3e2
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\Account;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Account\UpdateAppearanceRequest;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@ -11,6 +12,8 @@
|
||||
|
||||
class AppearanceController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
|
||||
public function edit(): Response
|
||||
{
|
||||
return Inertia::render('admin/account/Appearance', [
|
||||
@ -22,7 +25,7 @@ public function update(UpdateAppearanceRequest $request): RedirectResponse
|
||||
{
|
||||
$appearance = $request->string('appearance')->toString();
|
||||
|
||||
Inertia::flash('success', 'Tampilan berhasil diperbarui.');
|
||||
$this->flashUpdated('Tampilan');
|
||||
|
||||
return redirect()
|
||||
->route('admin.account.appearance')
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\Account;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Account\UpdatePasswordRequest;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@ -11,6 +12,8 @@
|
||||
|
||||
class PasswordController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
|
||||
public function edit(): Response
|
||||
{
|
||||
return Inertia::render('admin/account/Password');
|
||||
@ -19,10 +22,10 @@ public function edit(): Response
|
||||
public function update(UpdatePasswordRequest $request): RedirectResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
$user->password = Hash::make($request->string('password')->toString());
|
||||
$user->password = Hash::make($request->validated('password'));
|
||||
$user->save();
|
||||
|
||||
Inertia::flash('success', 'Kata sandi berhasil diperbarui.');
|
||||
$this->flashUpdated('Kata sandi');
|
||||
|
||||
return redirect()->route('admin.account.password');
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Admin\Account;
|
||||
|
||||
use App\Enums\Gender;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Account\UpdateProfileRequest;
|
||||
use App\Services\Account\ProfileService;
|
||||
@ -12,6 +13,8 @@
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
|
||||
public function __construct(
|
||||
private readonly ProfileService $profileService,
|
||||
) {}
|
||||
@ -28,9 +31,9 @@ public function edit(): Response
|
||||
|
||||
public function update(UpdateProfileRequest $request): RedirectResponse
|
||||
{
|
||||
$this->profileService->update($request->validated());
|
||||
$this->profileService->update($request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Profil berhasil diperbarui.');
|
||||
$this->flashUpdated('Profil');
|
||||
|
||||
return redirect()->route('admin.account.profile');
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\Finance;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Finance\DepositCashRequest;
|
||||
@ -15,6 +16,7 @@
|
||||
|
||||
class CashController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -39,7 +41,7 @@ public function deposit(DepositCashRequest $request): RedirectResponse
|
||||
|
||||
$this->cashService->deposit($cashAccount, $request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Setor kas berhasil dicatat.');
|
||||
$this->flashSuccess('Setor kas berhasil dicatat.');
|
||||
|
||||
return redirect()->route('admin.finance.cash.index');
|
||||
}
|
||||
@ -48,7 +50,7 @@ public function update(UpdateCashTransactionRequest $request, CashTransaction $c
|
||||
{
|
||||
$this->cashService->updateDeposit($cashTransaction, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Setor kas berhasil diperbarui.');
|
||||
$this->flashSuccess('Setor kas berhasil diperbarui.');
|
||||
|
||||
return redirect()->route('admin.finance.cash.index');
|
||||
}
|
||||
@ -57,7 +59,7 @@ public function destroy(CashTransaction $cashTransaction): RedirectResponse
|
||||
{
|
||||
$this->cashService->deleteTransaction($cashTransaction);
|
||||
|
||||
Inertia::flash('success', 'Setor kas berhasil dihapus.');
|
||||
$this->flashSuccess('Setor kas berhasil dihapus.');
|
||||
|
||||
return redirect()->route('admin.finance.cash.index');
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Admin\Finance;
|
||||
|
||||
use App\Enums\Permission;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Finance\EmployeeAdvanceRequest;
|
||||
@ -16,6 +17,7 @@
|
||||
|
||||
class EmployeeAdvanceController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -25,7 +27,7 @@ public function __construct(
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$tableQuery = $this->parseDataTableQuery($request);
|
||||
$user = auth()->user();
|
||||
$user = $request->user();
|
||||
|
||||
return Inertia::render('admin/finance/employee-advances/Index', [
|
||||
'employeeAdvances' => $this->employeeAdvanceService->paginateForIndex($tableQuery),
|
||||
@ -40,18 +42,18 @@ public function index(Request $request): Response
|
||||
|
||||
public function store(EmployeeAdvanceRequest $request): RedirectResponse
|
||||
{
|
||||
$this->employeeAdvanceService->create($request->validated());
|
||||
$this->employeeAdvanceService->create($request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Kasbon berhasil diajukan.');
|
||||
$this->flashSuccess('Kasbon berhasil diajukan.');
|
||||
|
||||
return redirect()->route('admin.finance.employee-advances.index');
|
||||
}
|
||||
|
||||
public function update(EmployeeAdvanceRequest $request, EmployeeAdvance $employeeAdvance): RedirectResponse
|
||||
{
|
||||
$this->employeeAdvanceService->update($employeeAdvance, $request->validated());
|
||||
$this->employeeAdvanceService->update($employeeAdvance, $request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Kasbon berhasil diperbarui.');
|
||||
$this->flashUpdated('Kasbon');
|
||||
|
||||
return redirect()->route('admin.finance.employee-advances.index');
|
||||
}
|
||||
@ -60,18 +62,18 @@ public function destroy(EmployeeAdvance $employeeAdvance): RedirectResponse
|
||||
{
|
||||
abort_unless(! auth()->user()?->can(Permission::EMPLOYEE_ADVANCES_VERIFY->value), 403);
|
||||
|
||||
$this->employeeAdvanceService->delete($employeeAdvance);
|
||||
$this->employeeAdvanceService->delete($employeeAdvance, auth()->user());
|
||||
|
||||
Inertia::flash('success', 'Kasbon berhasil dihapus.');
|
||||
$this->flashDeleted('Kasbon');
|
||||
|
||||
return redirect()->route('admin.finance.employee-advances.index');
|
||||
}
|
||||
|
||||
public function approve(EmployeeAdvance $employeeAdvance): RedirectResponse
|
||||
{
|
||||
$this->employeeAdvanceService->approve($employeeAdvance);
|
||||
$this->employeeAdvanceService->approve($employeeAdvance, auth()->user());
|
||||
|
||||
Inertia::flash('success', 'Kasbon disetujui dan dicairkan dari kas.');
|
||||
$this->flashSuccess('Kasbon berhasil disetujui dan dicairkan dari kas.');
|
||||
|
||||
return redirect()->route('admin.finance.employee-advances.index');
|
||||
}
|
||||
@ -81,18 +83,19 @@ public function reject(RejectEmployeeAdvanceRequest $request, EmployeeAdvance $e
|
||||
$this->employeeAdvanceService->reject(
|
||||
$employeeAdvance,
|
||||
$request->validated('reason'),
|
||||
auth()->user(),
|
||||
);
|
||||
|
||||
Inertia::flash('success', 'Kasbon berhasil ditolak.');
|
||||
$this->flashSuccess('Kasbon berhasil ditolak.');
|
||||
|
||||
return redirect()->route('admin.finance.employee-advances.index');
|
||||
}
|
||||
|
||||
public function pay(EmployeeAdvance $employeeAdvance): RedirectResponse
|
||||
{
|
||||
$this->employeeAdvanceService->pay($employeeAdvance);
|
||||
$this->employeeAdvanceService->pay($employeeAdvance, auth()->user());
|
||||
|
||||
Inertia::flash('success', 'Kasbon berhasil dilunasi.');
|
||||
$this->flashSuccess('Kasbon berhasil dilunasi.');
|
||||
|
||||
return redirect()->route('admin.finance.employee-advances.index');
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\Finance;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Finance\ExpenseRequest;
|
||||
@ -14,6 +15,7 @@
|
||||
|
||||
class ExpenseController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -34,7 +36,7 @@ public function store(ExpenseRequest $request): RedirectResponse
|
||||
{
|
||||
$this->expenseService->create($request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Pengeluaran berhasil ditambahkan.');
|
||||
$this->flashCreated('Pengeluaran');
|
||||
|
||||
return redirect()->route('admin.finance.expenses.index');
|
||||
}
|
||||
@ -43,7 +45,7 @@ public function update(ExpenseRequest $request, Expense $expense): RedirectRespo
|
||||
{
|
||||
$this->expenseService->update($expense, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Pengeluaran berhasil diperbarui.');
|
||||
$this->flashUpdated('Pengeluaran');
|
||||
|
||||
return redirect()->route('admin.finance.expenses.index');
|
||||
}
|
||||
@ -52,7 +54,7 @@ public function destroy(Expense $expense): RedirectResponse
|
||||
{
|
||||
$this->expenseService->delete($expense);
|
||||
|
||||
Inertia::flash('success', 'Pengeluaran berhasil dihapus.');
|
||||
$this->flashDeleted('Pengeluaran');
|
||||
|
||||
return redirect()->route('admin.finance.expenses.index');
|
||||
}
|
||||
|
||||
@ -2,15 +2,17 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\Finance;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Finance\PayrollAdjustmentRequest;
|
||||
use App\Models\Payroll;
|
||||
use App\Services\Finance\PayrollService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class PayrollController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
|
||||
public function __construct(
|
||||
private readonly PayrollService $payrollService,
|
||||
) {}
|
||||
@ -19,7 +21,7 @@ public function pay(Payroll $payroll): RedirectResponse
|
||||
{
|
||||
$this->payrollService->pay($payroll, auth()->user());
|
||||
|
||||
Inertia::flash('success', 'Gaji berhasil dibayar.');
|
||||
$this->flashSuccess('Gaji berhasil dibayar.');
|
||||
|
||||
return redirect()->route('admin.finance.payroll.index', [
|
||||
'period_id' => $payroll->payroll_period_id,
|
||||
@ -34,7 +36,7 @@ public function storeAdjustment(PayrollAdjustmentRequest $request, Payroll $payr
|
||||
auth()->user(),
|
||||
);
|
||||
|
||||
Inertia::flash('success', 'Penyesuaian gaji berhasil ditambahkan.');
|
||||
$this->flashSuccess('Penyesuaian gaji berhasil ditambahkan.');
|
||||
|
||||
return redirect()->route('admin.finance.payroll.index', [
|
||||
'period_id' => $payroll->payroll_period_id,
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Admin\Finance;
|
||||
|
||||
use App\Enums\PayrollAdjustmentType;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\PayrollPeriod;
|
||||
@ -14,6 +15,7 @@
|
||||
|
||||
class PayrollPeriodController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -47,7 +49,7 @@ public function close(PayrollPeriod $payrollPeriod): RedirectResponse
|
||||
{
|
||||
$this->payrollService->closePeriod($payrollPeriod, auth()->user());
|
||||
|
||||
Inertia::flash('success', 'Periode gaji berhasil ditutup.');
|
||||
$this->flashSuccess('Periode gaji berhasil ditutup.');
|
||||
|
||||
return redirect()->route('admin.finance.payroll.index', [
|
||||
'period_id' => $payrollPeriod->id,
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Admin\Hr;
|
||||
|
||||
use App\Enums\Permission;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Hr\AttendanceCheckInRequest;
|
||||
use App\Http\Requests\Admin\Hr\AttendanceCheckOutRequest;
|
||||
@ -15,13 +16,15 @@
|
||||
|
||||
class AttendanceController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
|
||||
public function __construct(
|
||||
private readonly AttendanceService $attendanceService,
|
||||
) {}
|
||||
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$user = auth()->user();
|
||||
$user = $request->user();
|
||||
$employee = $user?->employee;
|
||||
$canManageAll = $user?->can(Permission::ATTENDANCES_MANAGE->value) ?? false;
|
||||
|
||||
@ -53,18 +56,18 @@ public function index(Request $request): Response
|
||||
|
||||
public function checkIn(AttendanceCheckInRequest $request): RedirectResponse
|
||||
{
|
||||
$this->attendanceService->checkIn($request->validated());
|
||||
$this->attendanceService->checkIn($request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Presensi masuk berhasil dicatat.');
|
||||
$this->flashSuccess('Presensi masuk berhasil dicatat.');
|
||||
|
||||
return redirect()->route('admin.hr.attendances.index');
|
||||
}
|
||||
|
||||
public function checkOut(AttendanceCheckOutRequest $request): RedirectResponse
|
||||
{
|
||||
$this->attendanceService->checkOut($request->validated());
|
||||
$this->attendanceService->checkOut($request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Presensi pulang berhasil dicatat.');
|
||||
$this->flashSuccess('Presensi pulang berhasil dicatat.');
|
||||
|
||||
return redirect()->route('admin.hr.attendances.index');
|
||||
}
|
||||
@ -73,7 +76,7 @@ public function destroy(Attendance $attendance): RedirectResponse
|
||||
{
|
||||
$this->attendanceService->delete($attendance);
|
||||
|
||||
Inertia::flash('success', 'Data presensi berhasil dihapus.');
|
||||
$this->flashDeleted('Data presensi');
|
||||
|
||||
return redirect()->route('admin.hr.attendances.index');
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
use App\Enums\EmploymentStatus;
|
||||
use App\Enums\Gender;
|
||||
use App\Enums\Role;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Hr\EmployeeRequest;
|
||||
@ -17,6 +18,7 @@
|
||||
|
||||
class EmployeeController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -50,7 +52,7 @@ public function store(EmployeeRequest $request): RedirectResponse
|
||||
{
|
||||
$this->employeeService->create($request->validated());
|
||||
|
||||
Inertia::flash('success', 'Pegawai berhasil ditambahkan.');
|
||||
$this->flashCreated('Pegawai');
|
||||
|
||||
return redirect()->route('admin.hr.employees.index');
|
||||
}
|
||||
@ -71,7 +73,7 @@ public function update(EmployeeRequest $request, User $user): RedirectResponse
|
||||
{
|
||||
$this->employeeService->update($user, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Data pegawai berhasil diperbarui.');
|
||||
$this->flashSuccess('Data pegawai berhasil diperbarui.');
|
||||
|
||||
return redirect()->route('admin.hr.employees.index');
|
||||
}
|
||||
@ -84,7 +86,7 @@ public function toggleStatus(Request $request, User $user): RedirectResponse
|
||||
|
||||
$this->employeeService->toggleStatus($user, $validated['is_active']);
|
||||
|
||||
Inertia::flash('success', 'Status pegawai berhasil diperbarui.');
|
||||
$this->flashStatusUpdated('pegawai');
|
||||
|
||||
return back();
|
||||
}
|
||||
@ -93,7 +95,7 @@ public function resetPassword(User $user): RedirectResponse
|
||||
{
|
||||
$this->employeeService->resetPassword($user);
|
||||
|
||||
Inertia::flash('success', 'Kata sandi berhasil direset. Pengguna telah logout dari semua sesi.');
|
||||
$this->flashSuccess('Kata sandi berhasil direset. Pengguna telah logout dari semua sesi.');
|
||||
|
||||
return back();
|
||||
}
|
||||
@ -102,7 +104,7 @@ public function destroy(User $user): RedirectResponse
|
||||
{
|
||||
$this->employeeService->delete($user);
|
||||
|
||||
Inertia::flash('success', 'Pegawai berhasil dihapus.');
|
||||
$this->flashDeleted('Pegawai');
|
||||
|
||||
return redirect()->route('admin.hr.employees.index');
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Admin\Hr;
|
||||
|
||||
use App\Enums\Permission;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Hr\RejectLeaveRequestRequest;
|
||||
@ -16,6 +17,7 @@
|
||||
|
||||
class LeaveRequestController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -25,7 +27,7 @@ public function __construct(
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$tableQuery = $this->parseDataTableQuery($request);
|
||||
$user = auth()->user();
|
||||
$user = $request->user();
|
||||
|
||||
return Inertia::render('admin/hr/leave-requests/Index', [
|
||||
'leaveRequests' => $this->leaveRequestService->paginateForIndex($tableQuery),
|
||||
@ -39,18 +41,18 @@ public function index(Request $request): Response
|
||||
|
||||
public function store(SubmitLeaveRequest $request): RedirectResponse
|
||||
{
|
||||
$this->leaveRequestService->create($request->validated());
|
||||
$this->leaveRequestService->create($request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Pengajuan cuti berhasil diajukan.');
|
||||
$this->flashSuccess('Pengajuan cuti berhasil diajukan.');
|
||||
|
||||
return redirect()->route('admin.hr.leave-requests.index');
|
||||
}
|
||||
|
||||
public function update(SubmitLeaveRequest $request, LeaveRequest $leaveRequest): RedirectResponse
|
||||
{
|
||||
$this->leaveRequestService->update($leaveRequest, $request->validated());
|
||||
$this->leaveRequestService->update($leaveRequest, $request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Pengajuan cuti berhasil diperbarui.');
|
||||
$this->flashUpdated('Pengajuan cuti');
|
||||
|
||||
return redirect()->route('admin.hr.leave-requests.index');
|
||||
}
|
||||
@ -59,18 +61,18 @@ public function destroy(LeaveRequest $leaveRequest): RedirectResponse
|
||||
{
|
||||
abort_unless(! auth()->user()?->can(Permission::LEAVE_REQUESTS_VERIFY->value), 403);
|
||||
|
||||
$this->leaveRequestService->delete($leaveRequest);
|
||||
$this->leaveRequestService->delete($leaveRequest, auth()->user());
|
||||
|
||||
Inertia::flash('success', 'Pengajuan cuti berhasil dihapus.');
|
||||
$this->flashDeleted('Pengajuan cuti');
|
||||
|
||||
return redirect()->route('admin.hr.leave-requests.index');
|
||||
}
|
||||
|
||||
public function approve(LeaveRequest $leaveRequest): RedirectResponse
|
||||
{
|
||||
$this->leaveRequestService->approve($leaveRequest);
|
||||
$this->leaveRequestService->approve($leaveRequest, auth()->user());
|
||||
|
||||
Inertia::flash('success', 'Pengajuan cuti disetujui.');
|
||||
$this->flashSuccess('Pengajuan cuti berhasil disetujui.');
|
||||
|
||||
return redirect()->route('admin.hr.leave-requests.index');
|
||||
}
|
||||
@ -80,9 +82,10 @@ public function reject(RejectLeaveRequestRequest $request, LeaveRequest $leaveRe
|
||||
$this->leaveRequestService->reject(
|
||||
$leaveRequest,
|
||||
$request->validated('reason'),
|
||||
auth()->user(),
|
||||
);
|
||||
|
||||
Inertia::flash('success', 'Pengajuan cuti berhasil ditolak.');
|
||||
$this->flashSuccess('Pengajuan cuti berhasil ditolak.');
|
||||
|
||||
return redirect()->route('admin.hr.leave-requests.index');
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Admin\Manage;
|
||||
|
||||
use App\Enums\CuttingStatus;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Manage\CuttingRequest;
|
||||
@ -16,6 +17,7 @@
|
||||
|
||||
class CuttingController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -44,7 +46,7 @@ public function store(CuttingRequest $request): RedirectResponse
|
||||
{
|
||||
$this->cuttingService->create($request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Cutting berhasil ditambahkan.');
|
||||
$this->flashCreated('Proses potong');
|
||||
|
||||
return redirect()->route('admin.manage.cuttings.index');
|
||||
}
|
||||
@ -52,7 +54,7 @@ public function store(CuttingRequest $request): RedirectResponse
|
||||
public function edit(Cutting $cutting): Response|RedirectResponse
|
||||
{
|
||||
if (! $cutting->status->isEditable()) {
|
||||
Inertia::flash('error', 'Cutting tidak dapat diubah.');
|
||||
$this->flashError('Proses potong tidak dapat diubah.');
|
||||
|
||||
return redirect()->route('admin.manage.cuttings.index');
|
||||
}
|
||||
@ -68,7 +70,7 @@ public function update(CuttingRequest $request, Cutting $cutting): RedirectRespo
|
||||
{
|
||||
$this->cuttingService->update($cutting, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Cutting berhasil diperbarui.');
|
||||
$this->flashUpdated('Proses potong');
|
||||
|
||||
return redirect()->route('admin.manage.cuttings.index');
|
||||
}
|
||||
@ -77,7 +79,7 @@ public function destroy(Cutting $cutting): RedirectResponse
|
||||
{
|
||||
$this->cuttingService->delete($cutting);
|
||||
|
||||
Inertia::flash('success', 'Cutting berhasil dihapus.');
|
||||
$this->flashDeleted('Proses potong');
|
||||
|
||||
return redirect()->route('admin.manage.cuttings.index');
|
||||
}
|
||||
@ -89,18 +91,19 @@ public function transitionStatus(CuttingStatusTransitionRequest $request, Cuttin
|
||||
$this->cuttingService->transitionStatus(
|
||||
$cutting,
|
||||
$status,
|
||||
$request->user(),
|
||||
$request->validated('reason'),
|
||||
);
|
||||
|
||||
$message = match ($status) {
|
||||
CuttingStatus::COMPLETED => 'Cutting berhasil diselesaikan. Menunggu verifikasi admin toko.',
|
||||
CuttingStatus::VERIFIED => 'Cutting berhasil diverifikasi. Stok produk telah diperbarui.',
|
||||
CuttingStatus::REJECTED => 'Cutting ditolak.',
|
||||
CuttingStatus::IN_PROGRESS => 'Cutting dikembalikan ke proses.',
|
||||
default => 'Status cutting berhasil diperbarui.',
|
||||
CuttingStatus::COMPLETED => 'Proses potong berhasil diselesaikan. Menunggu verifikasi admin toko.',
|
||||
CuttingStatus::VERIFIED => 'Proses potong berhasil diverifikasi. Stok produk telah diperbarui.',
|
||||
CuttingStatus::REJECTED => 'Proses potong berhasil ditolak.',
|
||||
CuttingStatus::IN_PROGRESS => 'Proses potong dikembalikan ke proses.',
|
||||
default => 'Status proses potong berhasil diperbarui.',
|
||||
};
|
||||
|
||||
Inertia::flash('success', $message);
|
||||
$this->flashSuccess($message);
|
||||
|
||||
return redirect()->route('admin.manage.cuttings.index');
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Enums\OrderChannel;
|
||||
use App\Enums\OrderStatus;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Manage\OrderRequest;
|
||||
@ -17,6 +18,7 @@
|
||||
|
||||
class OrderController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -47,7 +49,7 @@ public function store(OrderRequest $request): RedirectResponse
|
||||
{
|
||||
$this->orderService->create($request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Pesanan berhasil ditambahkan.');
|
||||
$this->flashCreated('Pesanan');
|
||||
|
||||
return redirect()->route('admin.manage.orders.index');
|
||||
}
|
||||
@ -55,7 +57,7 @@ public function store(OrderRequest $request): RedirectResponse
|
||||
public function edit(Order $order): Response|RedirectResponse
|
||||
{
|
||||
if (! $order->status->isEditable()) {
|
||||
Inertia::flash('error', 'Pesanan tidak dapat diubah.');
|
||||
$this->flashError('Pesanan tidak dapat diubah.');
|
||||
|
||||
return redirect()->route('admin.manage.orders.index');
|
||||
}
|
||||
@ -73,7 +75,7 @@ public function update(OrderRequest $request, Order $order): RedirectResponse
|
||||
{
|
||||
$this->orderService->update($order, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Pesanan berhasil diperbarui.');
|
||||
$this->flashUpdated('Pesanan');
|
||||
|
||||
return redirect()->route('admin.manage.orders.index');
|
||||
}
|
||||
@ -82,7 +84,7 @@ public function destroy(Order $order): RedirectResponse
|
||||
{
|
||||
$this->orderService->delete($order);
|
||||
|
||||
Inertia::flash('success', 'Pesanan berhasil dihapus.');
|
||||
$this->flashDeleted('Pesanan');
|
||||
|
||||
return redirect()->route('admin.manage.orders.index');
|
||||
}
|
||||
@ -100,7 +102,7 @@ public function transitionStatus(OrderStatusTransitionRequest $request, Order $o
|
||||
default => 'Status pesanan berhasil diperbarui.',
|
||||
};
|
||||
|
||||
Inertia::flash('success', $message);
|
||||
$this->flashSuccess($message);
|
||||
|
||||
return redirect()->route('admin.manage.orders.index');
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\Manage;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Manage\PurchaseRequest;
|
||||
@ -14,6 +15,7 @@
|
||||
|
||||
class PurchaseController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -42,7 +44,7 @@ public function store(PurchaseRequest $request): RedirectResponse
|
||||
{
|
||||
$this->purchaseService->create($request->validated(), $request->user());
|
||||
|
||||
Inertia::flash('success', 'Belanja berhasil ditambahkan.');
|
||||
$this->flashCreated('Belanja');
|
||||
|
||||
return redirect()->route('admin.manage.purchases.index');
|
||||
}
|
||||
@ -60,7 +62,7 @@ public function update(PurchaseRequest $request, Purchase $purchase): RedirectRe
|
||||
{
|
||||
$this->purchaseService->update($purchase, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Belanja berhasil diperbarui.');
|
||||
$this->flashUpdated('Belanja');
|
||||
|
||||
return redirect()->route('admin.manage.purchases.index');
|
||||
}
|
||||
@ -69,7 +71,7 @@ public function destroy(Purchase $purchase): RedirectResponse
|
||||
{
|
||||
$this->purchaseService->delete($purchase);
|
||||
|
||||
Inertia::flash('success', 'Belanja berhasil dihapus.');
|
||||
$this->flashDeleted('Belanja');
|
||||
|
||||
return redirect()->route('admin.manage.purchases.index');
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\Master;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Master\CategoryRequest;
|
||||
@ -14,6 +15,7 @@
|
||||
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -34,7 +36,7 @@ public function store(CategoryRequest $request): RedirectResponse
|
||||
{
|
||||
$this->categoryService->create($request->validated());
|
||||
|
||||
Inertia::flash('success', 'Kategori berhasil ditambahkan.');
|
||||
$this->flashCreated('Kategori');
|
||||
|
||||
return redirect()->route('admin.master.categories.index');
|
||||
}
|
||||
@ -43,7 +45,7 @@ public function update(CategoryRequest $request, Category $category): RedirectRe
|
||||
{
|
||||
$this->categoryService->update($category, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Kategori berhasil diperbarui.');
|
||||
$this->flashUpdated('Kategori');
|
||||
|
||||
return redirect()->route('admin.master.categories.index');
|
||||
}
|
||||
@ -52,7 +54,7 @@ public function destroy(Category $category): RedirectResponse
|
||||
{
|
||||
$this->categoryService->delete($category);
|
||||
|
||||
Inertia::flash('success', 'Kategori berhasil dihapus.');
|
||||
$this->flashDeleted('Kategori');
|
||||
|
||||
return redirect()->route('admin.master.categories.index');
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\Master;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Master\CustomerRequest;
|
||||
@ -14,6 +15,7 @@
|
||||
|
||||
class CustomerController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -34,7 +36,7 @@ public function store(CustomerRequest $request): RedirectResponse
|
||||
{
|
||||
$this->customerService->create($request->validated());
|
||||
|
||||
Inertia::flash('success', 'Customer berhasil ditambahkan.');
|
||||
$this->flashCreated('Pelanggan');
|
||||
|
||||
return redirect()->route('admin.master.customers.index');
|
||||
}
|
||||
@ -43,7 +45,7 @@ public function update(CustomerRequest $request, Customer $customer): RedirectRe
|
||||
{
|
||||
$this->customerService->update($customer, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Customer berhasil diperbarui.');
|
||||
$this->flashUpdated('Pelanggan');
|
||||
|
||||
return redirect()->route('admin.master.customers.index');
|
||||
}
|
||||
@ -52,7 +54,7 @@ public function destroy(Customer $customer): RedirectResponse
|
||||
{
|
||||
$this->customerService->delete($customer);
|
||||
|
||||
Inertia::flash('success', 'Customer berhasil dihapus.');
|
||||
$this->flashDeleted('Pelanggan');
|
||||
|
||||
return redirect()->route('admin.master.customers.index');
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Admin\Master;
|
||||
|
||||
use App\Enums\PriceType;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Master\ProductRequest;
|
||||
@ -17,6 +18,7 @@
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -48,7 +50,7 @@ public function store(ProductRequest $request): RedirectResponse
|
||||
{
|
||||
$this->productService->create($request->validated());
|
||||
|
||||
Inertia::flash('success', 'Produk berhasil ditambahkan.');
|
||||
$this->flashCreated('Produk');
|
||||
|
||||
return redirect()->route('admin.master.products.index');
|
||||
}
|
||||
@ -77,7 +79,7 @@ public function update(ProductRequest $request, Product $product): RedirectRespo
|
||||
{
|
||||
$this->productService->update($product, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Produk berhasil diperbarui.');
|
||||
$this->flashUpdated('Produk');
|
||||
|
||||
return redirect()->route('admin.master.products.index');
|
||||
}
|
||||
@ -90,7 +92,7 @@ public function toggleStatus(Request $request, Product $product): RedirectRespon
|
||||
|
||||
$this->productService->toggleStatus($product, $validated['is_active']);
|
||||
|
||||
Inertia::flash('success', 'Status produk berhasil diperbarui.');
|
||||
$this->flashStatusUpdated('produk');
|
||||
|
||||
return back();
|
||||
}
|
||||
@ -99,7 +101,7 @@ public function destroy(Product $product): RedirectResponse
|
||||
{
|
||||
$this->productService->delete($product);
|
||||
|
||||
Inertia::flash('success', 'Produk berhasil dihapus.');
|
||||
$this->flashDeleted('Produk');
|
||||
|
||||
return redirect()->route('admin.master.products.index');
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Admin\Master;
|
||||
|
||||
use App\Enums\RawMaterialUnit;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Master\RawMaterialRequest;
|
||||
@ -17,6 +18,7 @@
|
||||
|
||||
class RawMaterialController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -47,7 +49,7 @@ public function store(RawMaterialRequest $request): RedirectResponse
|
||||
{
|
||||
$this->rawMaterialService->create($request->validated());
|
||||
|
||||
Inertia::flash('success', 'Bahan baku berhasil ditambahkan.');
|
||||
$this->flashCreated('Bahan baku');
|
||||
|
||||
return redirect()->route('admin.master.raw-materials.index');
|
||||
}
|
||||
@ -72,7 +74,7 @@ public function update(RawMaterialRequest $request, RawMaterial $rawMaterial): R
|
||||
{
|
||||
$this->rawMaterialService->update($rawMaterial, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Bahan baku berhasil diperbarui.');
|
||||
$this->flashUpdated('Bahan baku');
|
||||
|
||||
return redirect()->route('admin.master.raw-materials.index');
|
||||
}
|
||||
@ -85,7 +87,7 @@ public function toggleStatus(Request $request, RawMaterial $rawMaterial): Redire
|
||||
|
||||
$this->rawMaterialService->toggleStatus($rawMaterial, $validated['is_active']);
|
||||
|
||||
Inertia::flash('success', 'Status bahan baku berhasil diperbarui.');
|
||||
$this->flashStatusUpdated('bahan baku');
|
||||
|
||||
return back();
|
||||
}
|
||||
@ -94,7 +96,7 @@ public function destroy(RawMaterial $rawMaterial): RedirectResponse
|
||||
{
|
||||
$this->rawMaterialService->delete($rawMaterial);
|
||||
|
||||
Inertia::flash('success', 'Bahan baku berhasil dihapus.');
|
||||
$this->flashDeleted('Bahan baku');
|
||||
|
||||
return redirect()->route('admin.master.raw-materials.index');
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\Master;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Master\SupplierRequest;
|
||||
@ -14,6 +15,7 @@
|
||||
|
||||
class SupplierController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
use ParsesDataTableQuery;
|
||||
|
||||
public function __construct(
|
||||
@ -34,7 +36,7 @@ public function store(SupplierRequest $request): RedirectResponse
|
||||
{
|
||||
$this->supplierService->create($request->validated());
|
||||
|
||||
Inertia::flash('success', 'Supplier berhasil ditambahkan.');
|
||||
$this->flashCreated('Pemasok');
|
||||
|
||||
return redirect()->route('admin.master.suppliers.index');
|
||||
}
|
||||
@ -43,7 +45,7 @@ public function update(SupplierRequest $request, Supplier $supplier): RedirectRe
|
||||
{
|
||||
$this->supplierService->update($supplier, $request->validated());
|
||||
|
||||
Inertia::flash('success', 'Supplier berhasil diperbarui.');
|
||||
$this->flashUpdated('Pemasok');
|
||||
|
||||
return redirect()->route('admin.master.suppliers.index');
|
||||
}
|
||||
@ -52,7 +54,7 @@ public function destroy(Supplier $supplier): RedirectResponse
|
||||
{
|
||||
$this->supplierService->delete($supplier);
|
||||
|
||||
Inertia::flash('success', 'Supplier berhasil dihapus.');
|
||||
$this->flashDeleted('Pemasok');
|
||||
|
||||
return redirect()->route('admin.master.suppliers.index');
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin\System;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\System\Setting\MarketplaceRequest;
|
||||
use App\Http\Requests\Admin\System\Setting\SocialMediaRequest;
|
||||
@ -15,6 +16,8 @@
|
||||
|
||||
class SettingController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
|
||||
public function __construct(
|
||||
private readonly SystemService $systemService,
|
||||
private readonly SocialMediaService $socialMediaService,
|
||||
@ -34,7 +37,7 @@ public function updateSystem(SystemRequest $request): RedirectResponse
|
||||
{
|
||||
$this->systemService->updateSystem($request->validated());
|
||||
|
||||
Inertia::flash('success', 'Pengaturan sistem berhasil disimpan.');
|
||||
$this->flashSuccess('Pengaturan sistem berhasil disimpan.');
|
||||
|
||||
return redirect()->route('admin.system.setting.index');
|
||||
}
|
||||
@ -43,7 +46,7 @@ public function updateSocialMedia(SocialMediaRequest $request): RedirectResponse
|
||||
{
|
||||
$this->socialMediaService->updateSocialMedia($request->validated());
|
||||
|
||||
Inertia::flash('success', 'Pengaturan media sosial berhasil disimpan.');
|
||||
$this->flashSuccess('Pengaturan media sosial berhasil disimpan.');
|
||||
|
||||
return redirect()->route('admin.system.setting.index');
|
||||
}
|
||||
@ -52,7 +55,7 @@ public function updateMarketplace(MarketplaceRequest $request): RedirectResponse
|
||||
{
|
||||
$this->marketplaceService->updateMarketplace($request->validated());
|
||||
|
||||
Inertia::flash('success', 'Pengaturan marketplace berhasil disimpan.');
|
||||
$this->flashSuccess('Pengaturan marketplace berhasil disimpan.');
|
||||
|
||||
return redirect()->route('admin.system.setting.index');
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Auth\LoginRequest;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@ -10,6 +11,8 @@
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
|
||||
public function index(): Response
|
||||
{
|
||||
return Inertia::render('auth/Login');
|
||||
@ -30,8 +33,8 @@ public function store(LoginRequest $request): RedirectResponse
|
||||
|
||||
$user?->update(['last_login_at' => now()]);
|
||||
|
||||
return redirect()
|
||||
->intended(route('admin.dashboard'))
|
||||
->with('success', 'Berhasil masuk. Selamat datang kembali!');
|
||||
$this->flashSuccess('Berhasil masuk. Selamat datang kembali!');
|
||||
|
||||
return redirect()->intended(route('admin.dashboard'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@ -9,6 +10,8 @@
|
||||
|
||||
class LogoutController extends Controller
|
||||
{
|
||||
use FlashesEntityMessage;
|
||||
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
if ($user = $request->user()) {
|
||||
@ -23,8 +26,8 @@ public function store(Request $request): RedirectResponse
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect()
|
||||
->route('login')
|
||||
->with('success', 'Anda berhasil keluar.');
|
||||
$this->flashSuccess('Anda berhasil keluar.');
|
||||
|
||||
return redirect()->route('login');
|
||||
}
|
||||
}
|
||||
|
||||
38
app/Http/Controllers/Concerns/FlashesEntityMessage.php
Normal file
38
app/Http/Controllers/Concerns/FlashesEntityMessage.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Concerns;
|
||||
|
||||
use Inertia\Inertia;
|
||||
|
||||
trait FlashesEntityMessage
|
||||
{
|
||||
protected function flashCreated(string $entity): void
|
||||
{
|
||||
Inertia::flash('success', "{$entity} berhasil ditambahkan.");
|
||||
}
|
||||
|
||||
protected function flashUpdated(string $entity): void
|
||||
{
|
||||
Inertia::flash('success', "{$entity} berhasil diperbarui.");
|
||||
}
|
||||
|
||||
protected function flashDeleted(string $entity): void
|
||||
{
|
||||
Inertia::flash('success', "{$entity} berhasil dihapus.");
|
||||
}
|
||||
|
||||
protected function flashStatusUpdated(string $entity): void
|
||||
{
|
||||
Inertia::flash('success', "Status {$entity} berhasil diperbarui.");
|
||||
}
|
||||
|
||||
protected function flashSuccess(string $message): void
|
||||
{
|
||||
Inertia::flash('success', $message);
|
||||
}
|
||||
|
||||
protected function flashError(string $message): void
|
||||
{
|
||||
Inertia::flash('error', $message);
|
||||
}
|
||||
}
|
||||
@ -12,10 +12,23 @@ public function authorize(): bool
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'appearance' => ['required', Rule::in(['light', 'dark', 'system'])],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'appearance' => 'tampilan',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,9 @@ public function authorize(): bool
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
@ -19,4 +22,16 @@ public function rules(): array
|
||||
'password' => ['required', 'confirmed', Password::defaults()],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'current_password' => 'kata sandi saat ini',
|
||||
'password' => 'kata sandi baru',
|
||||
'password_confirmation' => 'konfirmasi kata sandi baru',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,16 +13,35 @@ public function authorize(): bool
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'email' => ['required', 'email', 'max:100', Rule::unique('users', 'email')->ignore($this->user()?->id)],
|
||||
'username' => ['required', 'string', 'max:20', 'alpha_dash', Rule::unique('users', 'username')->ignore($this->user()?->id)],
|
||||
'full_name' => ['required', 'string', 'max:200'],
|
||||
'phone_number' => ['nullable', 'string', 'regex:/^08\d{8,11}$/'],
|
||||
'phone_number' => ['nullable', 'string', 'max:20', 'regex:/^08\d{8,11}$/'],
|
||||
'gender' => ['nullable', Rule::enum(Gender::class)],
|
||||
'birth_date' => ['nullable', 'date', 'before:today'],
|
||||
'address' => ['nullable', 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'email' => 'email',
|
||||
'username' => 'username',
|
||||
'full_name' => 'nama lengkap',
|
||||
'phone_number' => 'nomor telepon',
|
||||
'gender' => 'jenis kelamin',
|
||||
'birth_date' => 'tanggal lahir',
|
||||
'address' => 'alamat',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,12 +15,27 @@ public function authorize(): bool
|
||||
return $this->user()?->can(Permission::CASH_DEPOSIT->value) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'amount' => ['required', 'integer', 'min:1'],
|
||||
'description' => ['required', 'string', 'max:200'],
|
||||
'description' => ['required', 'string', 'max:100'],
|
||||
...$this->photoRules(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'amount' => 'jumlah',
|
||||
'description' => 'keterangan',
|
||||
...$this->photoUploadAttributes('foto bukti'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,9 +43,22 @@ public function rules(): array
|
||||
{
|
||||
return [
|
||||
'amount' => ['required', 'integer', 'min:1'],
|
||||
'description' => ['required', 'string', 'max:500'],
|
||||
'description' => ['required', 'string', 'max:100'],
|
||||
'due_date' => ['required', 'date'],
|
||||
...$this->photoRules(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'amount' => 'jumlah',
|
||||
'description' => 'keterangan',
|
||||
'due_date' => 'jatuh tempo',
|
||||
...$this->photoUploadAttributes('foto bukti'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,8 +26,20 @@ public function rules(): array
|
||||
{
|
||||
return [
|
||||
'amount' => ['required', 'integer', 'min:1'],
|
||||
'description' => ['required', 'string', 'max:500'],
|
||||
'description' => ['required', 'string', 'max:100'],
|
||||
...$this->photoRules(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'amount' => 'jumlah',
|
||||
'description' => 'keterangan',
|
||||
...$this->photoUploadAttributes('foto bukti'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,19 @@ public function rules(): array
|
||||
return [
|
||||
'type' => ['required', Rule::enum(PayrollAdjustmentType::class)],
|
||||
'amount' => ['required', 'integer', 'min:1'],
|
||||
'description' => ['required', 'string', 'max:500'],
|
||||
'description' => ['required', 'string', 'max:100'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'type' => 'jenis',
|
||||
'amount' => 'jumlah',
|
||||
'description' => 'keterangan',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,4 +21,14 @@ public function rules(): array
|
||||
'reason' => ['required', 'string', 'max:500'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'reason' => 'alasan penolakan',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,12 +18,27 @@ public function authorize(): bool
|
||||
&& $transaction?->reference_type === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'amount' => ['required', 'integer', 'min:1'],
|
||||
'description' => ['required', 'string', 'max:200'],
|
||||
'description' => ['required', 'string', 'max:100'],
|
||||
...$this->photoRules(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'amount' => 'jumlah',
|
||||
'description' => 'keterangan',
|
||||
...$this->photoUploadAttributes('foto bukti'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,10 +18,23 @@ public function authorize(): bool
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'photo' => ['required', 'string'],
|
||||
'latitude' => ['required', 'numeric', 'between:-90,90'],
|
||||
'longitude' => ['required', 'numeric', 'between:-180,180'],
|
||||
'photo' => ['required', 'string', 'max:255'],
|
||||
'latitude' => ['required', 'numeric', 'decimal:0,7', 'between:-90,90'],
|
||||
'longitude' => ['required', 'numeric', 'decimal:0,7', 'between:-180,180'],
|
||||
'location_tag' => ['required', 'string', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'photo' => 'foto',
|
||||
'latitude' => 'latitude',
|
||||
'longitude' => 'longitude',
|
||||
'location_tag' => 'lokasi',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,10 +18,23 @@ public function authorize(): bool
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'photo' => ['required', 'string'],
|
||||
'latitude' => ['required', 'numeric', 'between:-90,90'],
|
||||
'longitude' => ['required', 'numeric', 'between:-180,180'],
|
||||
'photo' => ['required', 'string', 'max:255'],
|
||||
'latitude' => ['required', 'numeric', 'decimal:0,7', 'between:-90,90'],
|
||||
'longitude' => ['required', 'numeric', 'decimal:0,7', 'between:-180,180'],
|
||||
'location_tag' => ['required', 'string', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'photo' => 'foto',
|
||||
'latitude' => 'latitude',
|
||||
'longitude' => 'longitude',
|
||||
'location_tag' => 'lokasi',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ public function rules(): array
|
||||
'email' => ['required', 'email', 'max:100', Rule::unique('users', 'email')->ignore($this->route('user')?->id)],
|
||||
'username' => ['required', 'string', 'max:20', 'alpha_dash', Rule::unique('users', 'username')->ignore($this->route('user')?->id)],
|
||||
'full_name' => ['required', 'string', 'max:200'],
|
||||
'phone_number' => ['nullable', 'string', 'regex:/^08\d{8,11}$/'],
|
||||
'phone_number' => ['nullable', 'string', 'max:20', 'regex:/^08\d{8,11}$/'],
|
||||
'gender' => ['nullable', Rule::enum(Gender::class)],
|
||||
'birth_date' => ['nullable', 'date', 'before:today'],
|
||||
'address' => ['nullable', 'string'],
|
||||
@ -39,4 +39,24 @@ public function rules(): array
|
||||
'role' => ['required', Rule::in(Role::assignableValues())],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'email' => 'email',
|
||||
'username' => 'username',
|
||||
'full_name' => 'nama lengkap',
|
||||
'phone_number' => 'nomor telepon',
|
||||
'gender' => 'jenis kelamin',
|
||||
'birth_date' => 'tanggal lahir',
|
||||
'address' => 'alamat',
|
||||
'join_date' => 'tanggal bergabung',
|
||||
'employment_status' => 'status kepegawaian',
|
||||
'base_salary' => 'gaji pokok',
|
||||
'role' => 'role',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,4 +21,14 @@ public function rules(): array
|
||||
'reason' => ['required', 'string', 'max:500'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'reason' => 'alasan penolakan',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,4 +43,15 @@ public function rules(): array
|
||||
'end_date' => ['required', 'date', 'after_or_equal:start_date'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'start_date' => 'tanggal mulai',
|
||||
'end_date' => 'tanggal selesai',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,8 @@ public function authorize(): bool
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'description' => ['nullable', 'string', 'max:500'],
|
||||
'description' => ['nullable', 'string', 'max:100'],
|
||||
|
||||
'materials' => ['required', 'array', 'min:1'],
|
||||
'materials.*.raw_material_price_id' => [
|
||||
'required',
|
||||
@ -31,8 +32,9 @@ public function rules(): array
|
||||
'distinct',
|
||||
Rule::exists('raw_material_prices', 'id')->whereNull('deleted_at'),
|
||||
],
|
||||
'materials.*.material_usage' => ['required', 'numeric', 'gt:0'],
|
||||
'materials.*.remaining_material' => ['required', 'numeric', 'gte:0'],
|
||||
'materials.*.material_usage' => ['required', 'numeric', 'decimal:0,4', 'gt:0'],
|
||||
'materials.*.remaining_material' => ['required', 'numeric', 'decimal:0,4', 'gte:0'],
|
||||
|
||||
'results' => ['required', 'array', 'min:1'],
|
||||
'results.*.product_variant_id' => [
|
||||
'required',
|
||||
@ -42,7 +44,26 @@ public function rules(): array
|
||||
],
|
||||
'results.*.cutting_result' => ['required', 'integer', 'min:1'],
|
||||
'results.*.warehouse_stock' => ['required', 'integer', 'min:0'],
|
||||
'results.*.cutting_reject' => ['nullable', 'integer', 'min:0'],
|
||||
'results.*.cutting_reject' => ['required', 'integer', 'min:0'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'description' => 'keterangan',
|
||||
'materials' => 'bahan baku',
|
||||
'materials.*.raw_material_price_id' => 'bahan baku',
|
||||
'materials.*.material_usage' => 'pemakaian',
|
||||
'materials.*.remaining_material' => 'sisa',
|
||||
'results' => 'hasil produk',
|
||||
'results.*.product_variant_id' => 'varian produk',
|
||||
'results.*.cutting_result' => 'hasil',
|
||||
'results.*.warehouse_stock' => 'gudang',
|
||||
'results.*.cutting_reject' => 'reject',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,11 +27,22 @@ public function authorize(): bool
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'status' => ['required', 'string', Rule::in(array_column(CuttingStatus::cases(), 'value'))],
|
||||
'status' => ['required', Rule::enum(CuttingStatus::class)],
|
||||
'reason' => ['nullable', 'string', 'max:500'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'status' => 'status',
|
||||
'reason' => 'alasan penolakan',
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(function (Validator $validator): void {
|
||||
|
||||
@ -28,11 +28,12 @@ public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'customer_id' => ['nullable', 'integer', Rule::exists('customers', 'id')->whereNull('deleted_at')],
|
||||
'channel' => ['required', 'string', Rule::in(array_column(OrderChannel::cases(), 'value'))],
|
||||
'price_type' => ['required', 'string', Rule::in(array_column(PriceType::cases(), 'value'))],
|
||||
'channel' => ['required', Rule::enum(OrderChannel::class)],
|
||||
'price_type' => ['required', Rule::enum(PriceType::class)],
|
||||
'discount' => ['nullable', 'integer', 'min:0'],
|
||||
'marketplace_fee' => ['nullable', 'integer', 'min:0'],
|
||||
'notes' => ['nullable', 'string', 'max:100'],
|
||||
'notes' => ['nullable', 'string'],
|
||||
|
||||
'items' => ['required', 'array', 'min:1'],
|
||||
'items.*.product_variant_id' => [
|
||||
'required',
|
||||
@ -45,6 +46,24 @@ public function rules(): array
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'customer_id' => 'pelanggan',
|
||||
'channel' => 'channel',
|
||||
'price_type' => 'tipe harga',
|
||||
'discount' => 'diskon',
|
||||
'marketplace_fee' => 'biaya marketplace',
|
||||
'notes' => 'keterangan',
|
||||
'items' => 'produk',
|
||||
'items.*.product_variant_id' => 'varian produk',
|
||||
'items.*.quantity' => 'jumlah',
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
if (! $this->isMethod('PUT') && ! $this->isMethod('PATCH')) {
|
||||
|
||||
@ -27,7 +27,17 @@ public function authorize(): bool
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'status' => ['required', 'string', Rule::in(array_column(OrderStatus::cases(), 'value'))],
|
||||
'status' => ['required', Rule::enum(OrderStatus::class)],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'status' => 'status',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -29,14 +29,31 @@ public function rules(): array
|
||||
'supplier_id' => ['required', 'integer', Rule::exists('suppliers', 'id')->whereNull('deleted_at')],
|
||||
'discount' => ['nullable', 'integer', 'min:0'],
|
||||
'notes' => ['nullable', 'string', 'max:100'],
|
||||
|
||||
'items' => ['required', 'array', 'min:1'],
|
||||
'items.*.raw_material_price_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists('raw_material_prices', 'id')->whereNull('deleted_at'),
|
||||
],
|
||||
'items.*.quantity' => ['required', 'numeric', 'gt:0'],
|
||||
'items.*.quantity' => ['required', 'numeric', 'decimal:0,4', 'gt:0'],
|
||||
...$this->photoRules(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'supplier_id' => 'supplier',
|
||||
'discount' => 'diskon',
|
||||
'notes' => 'keterangan',
|
||||
'items' => 'bahan baku',
|
||||
'items.*.raw_material_price_id' => 'bahan baku',
|
||||
'items.*.quantity' => 'jumlah',
|
||||
...$this->photoUploadAttributes('bukti transaksi'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,4 +25,14 @@ public function rules(): array
|
||||
'name' => ['required', 'string', 'max:50'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'nama',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,8 +23,20 @@ public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:200'],
|
||||
'address' => ['required', 'string'],
|
||||
'phone_number' => ['required', 'string', 'max:20'],
|
||||
'phone_number' => ['nullable', 'string', 'max:20'],
|
||||
'address' => ['nullable', 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'nama',
|
||||
'phone_number' => 'nomor telepon',
|
||||
'address' => 'alamat',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,8 +29,10 @@ public function rules(): array
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:200'],
|
||||
'description' => ['nullable', 'string'],
|
||||
|
||||
'category_ids' => ['required', 'array', 'min:1'],
|
||||
'category_ids.*' => ['integer', Rule::exists('categories', 'id')->whereNull('deleted_at')],
|
||||
|
||||
'variants' => ['required', 'array', 'min:1'],
|
||||
'variants.*.id' => [
|
||||
'nullable',
|
||||
@ -43,8 +45,28 @@ public function rules(): array
|
||||
'variants.*.stock' => ['required', 'integer', 'min:0'],
|
||||
'variants.*.prices' => ['required', 'array', 'min:1'],
|
||||
'variants.*.prices.*.type' => ['required', Rule::enum(PriceType::class)],
|
||||
'variants.*.prices.*.price' => ['required', 'numeric', 'gt:0'],
|
||||
'variants.*.prices.*.price' => ['required', 'numeric', 'decimal:0,2', 'gt:0'],
|
||||
...$this->variantImageRules(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'nama produk',
|
||||
'description' => 'deskripsi',
|
||||
'category_ids' => 'kategori',
|
||||
'category_ids.*' => 'kategori',
|
||||
'variants' => 'varian',
|
||||
'variants.*.name' => 'nama varian',
|
||||
'variants.*.stock' => 'stok',
|
||||
'variants.*.prices' => 'harga',
|
||||
'variants.*.prices.*.type' => 'tipe harga',
|
||||
'variants.*.prices.*.price' => 'harga',
|
||||
...$this->variantImageAttributes('variants', 'foto varian'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ public function rules(): array
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:200'],
|
||||
'unit' => ['required', Rule::enum(RawMaterialUnit::class)],
|
||||
|
||||
'prices' => ['required', 'array', 'min:1'],
|
||||
'prices.*.id' => [
|
||||
'nullable',
|
||||
@ -38,9 +39,25 @@ public function rules(): array
|
||||
->whereNull('deleted_at'),
|
||||
],
|
||||
'prices.*.variant' => ['required', 'string', 'max:200'],
|
||||
'prices.*.price' => ['required', 'numeric', 'gt:0'],
|
||||
'prices.*.stock' => ['required', 'numeric', 'min:0'],
|
||||
'prices.*.price' => ['required', 'numeric', 'decimal:0,2', 'gt:0'],
|
||||
'prices.*.stock' => ['required', 'numeric', 'decimal:0,4', 'min:0'],
|
||||
...$this->variantImageRules('prices'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'nama bahan baku',
|
||||
'unit' => 'satuan',
|
||||
'prices' => 'varian',
|
||||
'prices.*.variant' => 'nama varian',
|
||||
'prices.*.price' => 'harga',
|
||||
'prices.*.stock' => 'stok',
|
||||
...$this->variantImageAttributes('prices', 'foto varian'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,8 +23,20 @@ public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:200'],
|
||||
'address' => ['required', 'string'],
|
||||
'phone_number' => ['required', 'string', 'max:20'],
|
||||
'phone_number' => ['nullable', 'string', 'max:20'],
|
||||
'address' => ['nullable', 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'nama',
|
||||
'phone_number' => 'nomor telepon',
|
||||
'address' => 'alamat',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,9 @@ public function authorize(): bool
|
||||
return $this->user()?->can(Permission::SETTINGS_UPDATE->value) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
@ -33,4 +36,28 @@ public function rules(): array
|
||||
'shopee_voucher_fee' => ['required', 'numeric', 'min:0', 'max:100'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'tiktok_shop_enabled' => 'aktif',
|
||||
'tiktok_shop_admin_fee' => 'biaya admin TikTok Shop',
|
||||
'tiktok_shop_transaction_fee' => 'biaya transaksi TikTok Shop',
|
||||
'tiktok_shop_payment_fee' => 'biaya pembayaran TikTok Shop',
|
||||
'tiktok_shop_affiliate_commission' => 'komisi afiliasi TikTok Shop',
|
||||
'tiktok_shop_shipping_subsidy' => 'subsidi ongkir TikTok Shop',
|
||||
'tiktok_shop_vat_rate' => 'PPN / pajak TikTok Shop',
|
||||
'shopee_enabled' => 'aktif',
|
||||
'shopee_commission_fee' => 'komisi Shopee',
|
||||
'shopee_transaction_fee' => 'biaya transaksi Shopee',
|
||||
'shopee_service_fee' => 'biaya layanan Shopee',
|
||||
'shopee_payment_fee' => 'biaya pembayaran Shopee',
|
||||
'shopee_affiliate_commission' => 'komisi afiliasi Shopee',
|
||||
'shopee_shipping_subsidy' => 'subsidi ongkir Shopee',
|
||||
'shopee_voucher_fee' => 'biaya voucher / diskon Shopee',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,9 @@ public function authorize(): bool
|
||||
return $this->user()?->can(Permission::SETTINGS_UPDATE->value) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
@ -20,4 +23,16 @@ public function rules(): array
|
||||
'tiktok_url' => ['nullable', 'url', 'max:100'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'instagram_url' => 'Instagram',
|
||||
'facebook_url' => 'Facebook',
|
||||
'tiktok_url' => 'TikTok',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,9 @@ public function authorize(): bool
|
||||
return $this->user()?->can(Permission::SETTINGS_UPDATE->value) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
@ -24,4 +27,20 @@ public function rules(): array
|
||||
'login_cover' => ['required', 'image', 'max:5120'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'app_name' => 'nama aplikasi',
|
||||
'about_app' => 'tentang aplikasi',
|
||||
'email' => 'email',
|
||||
'phone' => 'nomor telepon',
|
||||
'address' => 'alamat',
|
||||
'logo' => 'logo',
|
||||
'login_cover' => 'cover login',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,17 @@ public function rules(): array
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'login' => 'email/username',
|
||||
'password' => 'kata sandi',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
|
||||
@ -29,4 +29,30 @@ protected function variantImageRules(string $variantsKey = 'variants', int $max
|
||||
"{$variantsKey}.*.remove_media_ids.*" => ['integer'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function photoUploadAttributes(string $label): array
|
||||
{
|
||||
return [
|
||||
'photos' => $label,
|
||||
'photos.*' => $label,
|
||||
'remove_media_ids' => 'media yang dihapus',
|
||||
'remove_media_ids.*' => 'media yang dihapus',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function variantImageAttributes(string $variantsKey, string $label): array
|
||||
{
|
||||
return [
|
||||
"{$variantsKey}.*.images" => $label,
|
||||
"{$variantsKey}.*.images.*" => $label,
|
||||
"{$variantsKey}.*.remove_media_ids" => 'media yang dihapus',
|
||||
"{$variantsKey}.*.remove_media_ids.*" => 'media yang dihapus',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
@ -25,20 +26,10 @@
|
||||
])]
|
||||
class Attendance extends Model implements HasMedia
|
||||
{
|
||||
use HasFactory;
|
||||
use HasModuleMedia;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return 'attendance';
|
||||
}
|
||||
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('checkin')->singleFile();
|
||||
$this->addMediaCollection('checkout')->singleFile();
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
@ -58,13 +49,6 @@ public function employee(): BelongsTo
|
||||
return $this->belongsTo(Employee::class);
|
||||
}
|
||||
|
||||
public function employeeName(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->employee?->user?->profile?->full_name,
|
||||
);
|
||||
}
|
||||
|
||||
public function attendanceDateFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -79,6 +63,17 @@ public function checkInAtFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function checkInPhotoUrl(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
$photo = MediaPresenter::first($this, 'checkin');
|
||||
|
||||
return $photo['url'] ?? null;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public function checkOutAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -86,6 +81,24 @@ public function checkOutAtFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function checkOutPhotoUrl(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
$photo = MediaPresenter::first($this, 'checkout');
|
||||
|
||||
return $photo['url'] ?? null;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public function employeeName(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->employee?->user?->profile?->full_name,
|
||||
);
|
||||
}
|
||||
|
||||
public function workDurationFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -106,25 +119,14 @@ public function workDurationFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function checkInPhotoUrl(): Attribute
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
$photo = MediaPresenter::first($this, 'checkin');
|
||||
|
||||
return $photo['url'] ?? null;
|
||||
},
|
||||
);
|
||||
return 'attendance';
|
||||
}
|
||||
|
||||
public function checkOutPhotoUrl(): Attribute
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
$photo = MediaPresenter::first($this, 'checkout');
|
||||
|
||||
return $photo['url'] ?? null;
|
||||
},
|
||||
);
|
||||
$this->addMediaCollection('checkin')->singleFile();
|
||||
$this->addMediaCollection('checkout')->singleFile();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
@ -13,6 +14,7 @@
|
||||
#[Appends(['balance_formatted'])]
|
||||
class CashAccount extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
protected function casts(): array
|
||||
@ -22,15 +24,15 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function transactions(): HasMany
|
||||
{
|
||||
return $this->hasMany(CashTransaction::class);
|
||||
}
|
||||
|
||||
public function balanceFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->balance, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function transactions(): HasMany
|
||||
{
|
||||
return $this->hasMany(CashTransaction::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
@ -24,20 +25,11 @@
|
||||
])]
|
||||
class CashTransaction extends Model implements HasMedia
|
||||
{
|
||||
use HasFactory;
|
||||
use HasModuleMedia;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return 'cash';
|
||||
}
|
||||
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('photos');
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
@ -46,6 +38,21 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function cashAccount(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CashAccount::class);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function reference(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function amountFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -60,6 +67,33 @@ public function balanceAfterFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function createdByName(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->createdBy?->profile?->full_name ?? $this->createdBy?->username,
|
||||
);
|
||||
}
|
||||
|
||||
public function isIncoming(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
if ($this->reference_type === EmployeeAdvance::class && $this->reference instanceof EmployeeAdvance) {
|
||||
return $this->reference->repayment_cash_transaction_id === $this->id;
|
||||
}
|
||||
|
||||
return self::isIncomingTransaction($this);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public function referenceLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -75,31 +109,14 @@ public function referenceLabel(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function isIncoming(): Attribute
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
if ($this->reference_type === EmployeeAdvance::class && $this->reference instanceof EmployeeAdvance) {
|
||||
return $this->reference->repayment_cash_transaction_id === $this->id;
|
||||
}
|
||||
|
||||
return self::isIncomingTransaction($this);
|
||||
},
|
||||
);
|
||||
return 'cash';
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function createdByName(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->createdBy?->profile?->full_name ?? $this->createdBy?->username,
|
||||
);
|
||||
$this->addMediaCollection('photos');
|
||||
}
|
||||
|
||||
public static function labelForReferenceType(?string $referenceType): string
|
||||
@ -135,19 +152,4 @@ public static function isIncomingTransaction(self $transaction): bool
|
||||
|
||||
return self::isIncomingReference($transaction->reference_type);
|
||||
}
|
||||
|
||||
public function cashAccount(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CashAccount::class);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function reference(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\Concerns\InteractsWithActivityLog;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -13,6 +14,7 @@
|
||||
#[Sluggable(from: 'name', to: 'slug')]
|
||||
class Category extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\Concerns\InteractsWithActivityLog;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -11,6 +12,7 @@
|
||||
#[Guarded(['id'])]
|
||||
class Customer extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -20,6 +21,7 @@
|
||||
])]
|
||||
class Cutting extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasRejection;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
@ -31,20 +33,6 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function statusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
@ -59,4 +47,18 @@ public function results(): HasMany
|
||||
{
|
||||
return $this->hasMany(CuttingResult::class);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function statusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status->label(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,8 +6,10 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
#[Guarded(['id'])]
|
||||
#[Appends([
|
||||
@ -19,7 +21,9 @@
|
||||
])]
|
||||
class CuttingMaterial extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
@ -29,6 +33,16 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function cutting(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Cutting::class);
|
||||
}
|
||||
|
||||
public function rawMaterialPrice(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(RawMaterialPrice::class);
|
||||
}
|
||||
|
||||
public function materialUsageFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -64,16 +78,6 @@ public function unitAbbreviation(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function cutting(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Cutting::class);
|
||||
}
|
||||
|
||||
public function rawMaterialPrice(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(RawMaterialPrice::class);
|
||||
}
|
||||
|
||||
private function formatQuantity(float|string|null $value): string
|
||||
{
|
||||
$formatted = rtrim(rtrim(number_format((float) $value, 4, ',', '.'), '0'), ',');
|
||||
|
||||
@ -4,13 +4,17 @@
|
||||
|
||||
use App\Models\Concerns\InteractsWithActivityLog;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
#[Guarded(['id'])]
|
||||
class CuttingResult extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Scope;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -19,6 +20,7 @@
|
||||
#[Appends(['base_salary_formatted', 'join_date_formatted', 'resign_date_formatted', 'join_date_input', 'employment_status_label'])]
|
||||
class Employee extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
@ -32,6 +34,13 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
public function contract(Builder $query): void
|
||||
{
|
||||
$query->where('employment_status', EmploymentStatus::CONTRACT->value);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
public function fullTime(Builder $query): void
|
||||
{
|
||||
$query->where('employment_status', EmploymentStatus::FULL_TIME->value);
|
||||
@ -43,68 +52,17 @@ public function partTime(Builder $query): void
|
||||
$query->where('employment_status', EmploymentStatus::PART_TIME->value);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
public function contract(Builder $query): void
|
||||
{
|
||||
$query->where('employment_status', EmploymentStatus::CONTRACT->value);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
public function temporary(Builder $query): void
|
||||
{
|
||||
$query->where('employment_status', EmploymentStatus::TEMPORARY->value);
|
||||
}
|
||||
|
||||
public function baseSalaryFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->base_salary, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function joinDateFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => Carbon::parse($this->join_date)->format('l, d F Y'),
|
||||
);
|
||||
}
|
||||
|
||||
public function resignDateFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->resign_date ? Carbon::parse($this->resign_date)->format('l, d F Y') : null,
|
||||
);
|
||||
}
|
||||
|
||||
public function joinDateInput(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->join_date?->format('Y-m-d'),
|
||||
);
|
||||
}
|
||||
|
||||
public function employmentStatusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->employment_status?->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function advances(): HasMany
|
||||
{
|
||||
return $this->hasMany(EmployeeAdvance::class);
|
||||
}
|
||||
|
||||
public function payrolls(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payroll::class);
|
||||
}
|
||||
|
||||
public function attendances(): HasMany
|
||||
{
|
||||
return $this->hasMany(Attendance::class);
|
||||
@ -114,4 +72,49 @@ public function leaveRequests(): HasMany
|
||||
{
|
||||
return $this->hasMany(LeaveRequest::class);
|
||||
}
|
||||
|
||||
public function payrolls(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payroll::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function baseSalaryFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->base_salary, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function employmentStatusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->employment_status?->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function joinDateFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => Carbon::parse($this->join_date)->format('l, d F Y'),
|
||||
);
|
||||
}
|
||||
|
||||
public function joinDateInput(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->join_date?->format('Y-m-d'),
|
||||
);
|
||||
}
|
||||
|
||||
public function resignDateFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->resign_date ? Carbon::parse($this->resign_date)->format('l, d F Y') : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
@ -28,20 +29,11 @@
|
||||
])]
|
||||
class EmployeeAdvance extends Model implements HasMedia
|
||||
{
|
||||
use HasFactory;
|
||||
use HasModuleMedia;
|
||||
use HasRejection;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return 'employee-advance';
|
||||
}
|
||||
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('photos');
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
@ -53,6 +45,31 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function cashTransaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class);
|
||||
}
|
||||
|
||||
public function employee(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Employee::class);
|
||||
}
|
||||
|
||||
public function paidBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'paid_by_id');
|
||||
}
|
||||
|
||||
public function repaymentCashTransaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class, 'repayment_cash_transaction_id');
|
||||
}
|
||||
|
||||
public function verifiedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'verified_by_id');
|
||||
}
|
||||
|
||||
public function amountFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -60,6 +77,27 @@ public function amountFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function canPay(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status === EmployeeAdvanceStatus::APPROVED,
|
||||
);
|
||||
}
|
||||
|
||||
public function canVerify(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status === EmployeeAdvanceStatus::PENDING,
|
||||
);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function dueDateFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -74,13 +112,6 @@ public function dueDateInput(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function statusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status?->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function employeeName(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -89,20 +120,6 @@ public function employeeName(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function rejectionReason(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->rejection?->reason,
|
||||
);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function isEditable(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -110,42 +127,27 @@ public function isEditable(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function canVerify(): Attribute
|
||||
public function rejectionReason(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status === EmployeeAdvanceStatus::PENDING,
|
||||
get: fn () => $this->rejection?->reason,
|
||||
);
|
||||
}
|
||||
|
||||
public function canPay(): Attribute
|
||||
public function statusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status === EmployeeAdvanceStatus::APPROVED,
|
||||
get: fn () => $this->status?->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function employee(): BelongsTo
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return $this->belongsTo(Employee::class);
|
||||
return 'employee-advance';
|
||||
}
|
||||
|
||||
public function cashTransaction(): BelongsTo
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class);
|
||||
}
|
||||
|
||||
public function repaymentCashTransaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class, 'repayment_cash_transaction_id');
|
||||
}
|
||||
|
||||
public function verifiedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'verified_by_id');
|
||||
}
|
||||
|
||||
public function paidBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'paid_by_id');
|
||||
$this->addMediaCollection('photos');
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -16,20 +17,11 @@
|
||||
#[Appends(['amount_formatted', 'created_at_formatted', 'created_by_name'])]
|
||||
class Expense extends Model implements HasMedia
|
||||
{
|
||||
use HasFactory;
|
||||
use HasModuleMedia;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return 'expense';
|
||||
}
|
||||
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('photos');
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
@ -37,6 +29,16 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function cashTransaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function amountFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -58,13 +60,13 @@ public function createdByName(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function cashTransaction(): BelongsTo
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class);
|
||||
return 'expense';
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
$this->addMediaCollection('photos');
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
@ -26,6 +27,7 @@
|
||||
])]
|
||||
class LeaveRequest extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasRejection;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
@ -40,38 +42,27 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function startDateFormatted(): Attribute
|
||||
public function employee(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Employee::class);
|
||||
}
|
||||
|
||||
public function verifiedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'verified_by_id');
|
||||
}
|
||||
|
||||
public function canVerify(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->start_date?->translatedFormat('l, d F Y'),
|
||||
get: fn () => $this->status === LeaveRequestStatus::PENDING,
|
||||
);
|
||||
}
|
||||
|
||||
public function endDateFormatted(): Attribute
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->end_date?->translatedFormat('l, d F Y'),
|
||||
);
|
||||
}
|
||||
|
||||
public function startDateInput(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->start_date?->format('Y-m-d'),
|
||||
);
|
||||
}
|
||||
|
||||
public function endDateInput(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->end_date?->format('Y-m-d'),
|
||||
);
|
||||
}
|
||||
|
||||
public function statusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status?->label(),
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
@ -83,17 +74,17 @@ public function employeeName(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function rejectionReason(): Attribute
|
||||
public function endDateFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->rejection?->reason,
|
||||
get: fn () => $this->end_date?->translatedFormat('l, d F Y'),
|
||||
);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
public function endDateInput(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
get: fn () => $this->end_date?->format('Y-m-d'),
|
||||
);
|
||||
}
|
||||
|
||||
@ -104,20 +95,31 @@ public function isEditable(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function canVerify(): Attribute
|
||||
public function rejectionReason(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status === LeaveRequestStatus::PENDING,
|
||||
get: fn () => $this->rejection?->reason,
|
||||
);
|
||||
}
|
||||
|
||||
public function employee(): BelongsTo
|
||||
public function startDateFormatted(): Attribute
|
||||
{
|
||||
return $this->belongsTo(Employee::class);
|
||||
return Attribute::make(
|
||||
get: fn () => $this->start_date?->translatedFormat('l, d F Y'),
|
||||
);
|
||||
}
|
||||
|
||||
public function verifiedBy(): BelongsTo
|
||||
public function startDateInput(): Attribute
|
||||
{
|
||||
return $this->belongsTo(User::class, 'verified_by_id');
|
||||
return Attribute::make(
|
||||
get: fn () => $this->start_date?->format('Y-m-d'),
|
||||
);
|
||||
}
|
||||
|
||||
public function statusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status?->label(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -27,6 +28,7 @@
|
||||
])]
|
||||
class Order extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
@ -43,10 +45,37 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function subtotalFormatted(): Attribute
|
||||
public function cashTransaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function customer(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Customer::class);
|
||||
}
|
||||
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
public function channelLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->subtotal, 0, ',', '.'),
|
||||
get: fn () => $this->channel->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
@ -71,20 +100,6 @@ public function netAmountFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function channelLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->channel->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function priceTypeLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -99,23 +114,10 @@ public function statusLabel(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function customer(): BelongsTo
|
||||
public function subtotalFormatted(): Attribute
|
||||
{
|
||||
return $this->belongsTo(Customer::class);
|
||||
}
|
||||
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
public function cashTransaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->subtotal, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,8 +6,10 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
#[Guarded(['id'])]
|
||||
#[Appends([
|
||||
@ -18,7 +20,9 @@
|
||||
])]
|
||||
class OrderItem extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
@ -29,6 +33,16 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function order(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Order::class);
|
||||
}
|
||||
|
||||
public function productVariant(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ProductVariant::class);
|
||||
}
|
||||
|
||||
public function quantityFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -43,13 +57,6 @@ public function quantityInput(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function unitPriceFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->unit_price, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function subtotalFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -57,13 +64,10 @@ public function subtotalFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function order(): BelongsTo
|
||||
public function unitPriceFormatted(): Attribute
|
||||
{
|
||||
return $this->belongsTo(Order::class);
|
||||
}
|
||||
|
||||
public function productVariant(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ProductVariant::class);
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->unit_price, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -27,6 +28,7 @@
|
||||
])]
|
||||
class Payroll extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
protected function casts(): array
|
||||
@ -41,6 +43,31 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function adjustments(): HasMany
|
||||
{
|
||||
return $this->hasMany(PayrollAdjustment::class);
|
||||
}
|
||||
|
||||
public function cashTransaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class);
|
||||
}
|
||||
|
||||
public function employee(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Employee::class);
|
||||
}
|
||||
|
||||
public function paidBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'paid_by_id');
|
||||
}
|
||||
|
||||
public function payrollPeriod(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(PayrollPeriod::class);
|
||||
}
|
||||
|
||||
public function baseSalaryFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -55,39 +82,12 @@ public function bonusAmountFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function deductionAmountFormatted(): Attribute
|
||||
public function canAdjust(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->deduction_amount, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function netAmountFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->net_amount, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function statusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status?->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function employeeName(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->employee?->user?->profile?->full_name
|
||||
?? $this->employee?->user?->username,
|
||||
);
|
||||
}
|
||||
|
||||
public function paidAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->paid_at?->translatedFormat('l, d F Y H:i'),
|
||||
get: fn () => $this->status === PayrollStatus::UNPAID
|
||||
&& $this->relationLoaded('payrollPeriod')
|
||||
&& $this->payrollPeriod?->isOpen(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -100,38 +100,52 @@ public function canPay(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function canAdjust(): Attribute
|
||||
public function deductionAmountFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status === PayrollStatus::UNPAID
|
||||
&& $this->relationLoaded('payrollPeriod')
|
||||
&& $this->payrollPeriod?->isOpen(),
|
||||
get: fn () => 'Rp '.number_format($this->deduction_amount, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function payrollPeriod(): BelongsTo
|
||||
public function employeeName(): Attribute
|
||||
{
|
||||
return $this->belongsTo(PayrollPeriod::class);
|
||||
return Attribute::make(
|
||||
get: fn () => $this->employee?->user?->profile?->full_name
|
||||
?? $this->employee?->user?->username,
|
||||
);
|
||||
}
|
||||
|
||||
public function employee(): BelongsTo
|
||||
public function netAmountFormatted(): Attribute
|
||||
{
|
||||
return $this->belongsTo(Employee::class);
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->net_amount, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function paidBy(): BelongsTo
|
||||
public function paidAtFormatted(): Attribute
|
||||
{
|
||||
return $this->belongsTo(User::class, 'paid_by_id');
|
||||
return Attribute::make(
|
||||
get: fn () => $this->paid_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function cashTransaction(): BelongsTo
|
||||
public function statusLabel(): Attribute
|
||||
{
|
||||
return $this->belongsTo(CashTransaction::class);
|
||||
return Attribute::make(
|
||||
get: fn () => $this->status?->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function adjustments(): HasMany
|
||||
public function calculateKasbonDeduction(): int
|
||||
{
|
||||
return $this->hasMany(PayrollAdjustment::class);
|
||||
$outstanding = (int) EmployeeAdvance::query()
|
||||
->where('employee_id', $this->employee_id)
|
||||
->where('status', EmployeeAdvanceStatus::APPROVED)
|
||||
->sum('amount');
|
||||
|
||||
return min($outstanding, $this->base_salary + (int) $this->adjustments()
|
||||
->where('type', PayrollAdjustmentType::BONUS)
|
||||
->sum('amount'));
|
||||
}
|
||||
|
||||
public function recalculateAmounts(): void
|
||||
@ -150,16 +164,4 @@ public function recalculateAmounts(): void
|
||||
$this->deduction_amount = $kasbonDeduction + $manualDeduction;
|
||||
$this->net_amount = max(0, $this->base_salary + $bonusAmount - $this->deduction_amount);
|
||||
}
|
||||
|
||||
public function calculateKasbonDeduction(): int
|
||||
{
|
||||
$outstanding = (int) EmployeeAdvance::query()
|
||||
->where('employee_id', $this->employee_id)
|
||||
->where('status', EmployeeAdvanceStatus::APPROVED)
|
||||
->sum('amount');
|
||||
|
||||
return min($outstanding, $this->base_salary + (int) $this->adjustments()
|
||||
->where('type', PayrollAdjustmentType::BONUS)
|
||||
->sum('amount'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
@ -14,6 +15,7 @@
|
||||
#[Appends(['amount_formatted', 'type_label', 'created_at_formatted', 'created_by_name'])]
|
||||
class PayrollAdjustment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
public $timestamps = false;
|
||||
@ -27,6 +29,16 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function payroll(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Payroll::class);
|
||||
}
|
||||
|
||||
public function amountFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -34,13 +46,6 @@ public function amountFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function typeLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->type?->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -55,13 +60,10 @@ public function createdByName(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function payroll(): BelongsTo
|
||||
public function typeLabel(): Attribute
|
||||
{
|
||||
return $this->belongsTo(Payroll::class);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
return Attribute::make(
|
||||
get: fn () => $this->type?->label(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -16,6 +17,7 @@
|
||||
#[Appends(['period_label', 'status_label', 'closed_at_formatted'])]
|
||||
class PayrollPeriod extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
protected function casts(): array
|
||||
@ -26,6 +28,23 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function closedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'closed_by_id');
|
||||
}
|
||||
|
||||
public function payrolls(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payroll::class);
|
||||
}
|
||||
|
||||
public function closedAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->closed_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function periodLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -40,23 +59,6 @@ public function statusLabel(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function closedAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->closed_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function payrolls(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payroll::class);
|
||||
}
|
||||
|
||||
public function closedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'closed_by_id');
|
||||
}
|
||||
|
||||
public function isOpen(): bool
|
||||
{
|
||||
return $this->status === PayrollPeriodStatus::OPEN;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\Concerns\InteractsWithActivityLog;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -14,6 +15,7 @@
|
||||
#[Sluggable(from: 'name', to: 'slug')]
|
||||
class Product extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
@ -14,6 +15,7 @@
|
||||
#[Appends(['price_formatted', 'price_input', 'type_label'])]
|
||||
class ProductPrice extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
protected function casts(): array
|
||||
@ -24,6 +26,11 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function variant(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ProductVariant::class, 'variant_id');
|
||||
}
|
||||
|
||||
public function priceFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -44,9 +51,4 @@ public function typeLabel(): Attribute
|
||||
get: fn () => $this->type->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function variant(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ProductVariant::class, 'variant_id');
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
use App\Models\Concerns\HasModuleMedia;
|
||||
use App\Models\Concerns\InteractsWithActivityLog;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -14,10 +15,38 @@
|
||||
#[Guarded(['id'])]
|
||||
class ProductVariant extends Model implements HasMedia
|
||||
{
|
||||
use HasFactory;
|
||||
use HasModuleMedia;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'stock' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function cuttingResults(): HasMany
|
||||
{
|
||||
return $this->hasMany(CuttingResult::class);
|
||||
}
|
||||
|
||||
public function orderItems(): HasMany
|
||||
{
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
public function prices(): HasMany
|
||||
{
|
||||
return $this->hasMany(ProductPrice::class, 'variant_id');
|
||||
}
|
||||
|
||||
public function product(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return 'product';
|
||||
@ -27,31 +56,4 @@ public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('images');
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'stock' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function product(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
|
||||
public function prices(): HasMany
|
||||
{
|
||||
return $this->hasMany(ProductPrice::class, 'variant_id');
|
||||
}
|
||||
|
||||
public function orderItems(): HasMany
|
||||
{
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
public function cuttingResults(): HasMany
|
||||
{
|
||||
return $this->hasMany(CuttingResult::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -22,20 +23,11 @@
|
||||
])]
|
||||
class Purchase extends Model implements HasMedia
|
||||
{
|
||||
use HasFactory;
|
||||
use HasModuleMedia;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return 'purchase';
|
||||
}
|
||||
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('photos');
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
@ -45,39 +37,6 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function subtotalFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->subtotal, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function discountFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->discount, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function totalFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->total, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function supplier(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Supplier::class);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
@ -87,4 +46,47 @@ public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(PurchaseItem::class);
|
||||
}
|
||||
|
||||
public function supplier(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Supplier::class);
|
||||
}
|
||||
|
||||
public function createdAtFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->created_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function discountFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->discount, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function subtotalFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->subtotal, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function totalFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->total, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return 'purchase';
|
||||
}
|
||||
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('photos');
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -20,6 +21,7 @@
|
||||
])]
|
||||
class PurchaseItem extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
@ -32,6 +34,16 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function purchase(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Purchase::class);
|
||||
}
|
||||
|
||||
public function rawMaterialPrice(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(RawMaterialPrice::class);
|
||||
}
|
||||
|
||||
public function quantityFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -50,13 +62,6 @@ public function quantityInput(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function unitPriceFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->unit_price, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function subtotalFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -71,13 +76,10 @@ public function unitAbbreviation(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function purchase(): BelongsTo
|
||||
public function unitPriceFormatted(): Attribute
|
||||
{
|
||||
return $this->belongsTo(Purchase::class);
|
||||
}
|
||||
|
||||
public function rawMaterialPrice(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(RawMaterialPrice::class);
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->unit_price, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Scope;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -17,6 +18,7 @@
|
||||
#[Appends(['unit_label', 'unit_abbreviation'])]
|
||||
class RawMaterial extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
@ -40,11 +42,9 @@ public function inactive(Builder $query): void
|
||||
$query->where('is_active', false);
|
||||
}
|
||||
|
||||
public function unitLabel(): Attribute
|
||||
public function prices(): HasMany
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->unit->label(),
|
||||
);
|
||||
return $this->hasMany(RawMaterialPrice::class);
|
||||
}
|
||||
|
||||
public function unitAbbreviation(): Attribute
|
||||
@ -54,8 +54,10 @@ public function unitAbbreviation(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function prices(): HasMany
|
||||
public function unitLabel(): Attribute
|
||||
{
|
||||
return $this->hasMany(RawMaterialPrice::class);
|
||||
return Attribute::make(
|
||||
get: fn () => $this->unit->label(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -17,20 +18,11 @@
|
||||
#[Appends(['price_formatted', 'stock_formatted', 'price_input', 'stock_input'])]
|
||||
class RawMaterialPrice extends Model implements HasMedia
|
||||
{
|
||||
use HasFactory;
|
||||
use HasModuleMedia;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return 'raw-material';
|
||||
}
|
||||
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('images');
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
@ -39,6 +31,16 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function cuttingMaterials(): HasMany
|
||||
{
|
||||
return $this->hasMany(CuttingMaterial::class);
|
||||
}
|
||||
|
||||
public function rawMaterial(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(RawMaterial::class);
|
||||
}
|
||||
|
||||
public function priceFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -46,6 +48,13 @@ public function priceFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function priceInput(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => (string) (int) $this->price,
|
||||
);
|
||||
}
|
||||
|
||||
public function stockFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -57,13 +66,6 @@ public function stockFormatted(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function priceInput(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => (string) (int) $this->price,
|
||||
);
|
||||
}
|
||||
|
||||
public function stockInput(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -71,13 +73,13 @@ public function stockInput(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function rawMaterial(): BelongsTo
|
||||
public static function mediaModuleName(): string
|
||||
{
|
||||
return $this->belongsTo(RawMaterial::class);
|
||||
return 'raw-material';
|
||||
}
|
||||
|
||||
public function cuttingMaterials(): HasMany
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
return $this->hasMany(CuttingMaterial::class);
|
||||
$this->addMediaCollection('images');
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\Concerns\InteractsWithActivityLog;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
@ -11,6 +12,7 @@
|
||||
#[Guarded(['id'])]
|
||||
class Rejection extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
public function rejectable(): MorphTo
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\Concerns\InteractsWithActivityLog;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -11,6 +12,7 @@
|
||||
#[Guarded(['id'])]
|
||||
class Supplier extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
|
||||
@ -5,12 +5,14 @@
|
||||
use App\Models\Concerns\HasModuleMedia;
|
||||
use App\Models\Concerns\InteractsWithActivityLog;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
|
||||
#[Guarded(['id'])]
|
||||
class SystemConfiguration extends Model implements HasMedia
|
||||
{
|
||||
use HasFactory;
|
||||
use HasModuleMedia;
|
||||
use InteractsWithActivityLog;
|
||||
|
||||
|
||||
@ -24,7 +24,12 @@
|
||||
#[Appends(['role_label'])]
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use CausesActivity, HasFactory, HasRoles, InteractsWithActivityLog, Notifiable, SoftDeletes;
|
||||
use CausesActivity;
|
||||
use HasFactory;
|
||||
use HasRoles;
|
||||
use InteractsWithActivityLog;
|
||||
use Notifiable;
|
||||
use SoftDeletes;
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
@ -47,6 +52,36 @@ public function inactive(Builder $query): void
|
||||
$query->where('is_active', false);
|
||||
}
|
||||
|
||||
public function cashTransactions(): HasMany
|
||||
{
|
||||
return $this->hasMany(CashTransaction::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function employee(): HasOne
|
||||
{
|
||||
return $this->hasOne(Employee::class);
|
||||
}
|
||||
|
||||
public function expenses(): HasMany
|
||||
{
|
||||
return $this->hasMany(Expense::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function orders(): HasMany
|
||||
{
|
||||
return $this->hasMany(Order::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function profile(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserProfile::class);
|
||||
}
|
||||
|
||||
public function purchases(): HasMany
|
||||
{
|
||||
return $this->hasMany(Purchase::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function roleLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -57,34 +92,4 @@ public function roleLabel(): Attribute
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public function profile(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserProfile::class);
|
||||
}
|
||||
|
||||
public function employee(): HasOne
|
||||
{
|
||||
return $this->hasOne(Employee::class);
|
||||
}
|
||||
|
||||
public function cashTransactions(): HasMany
|
||||
{
|
||||
return $this->hasMany(CashTransaction::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function expenses(): HasMany
|
||||
{
|
||||
return $this->hasMany(Expense::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function purchases(): HasMany
|
||||
{
|
||||
return $this->hasMany(Purchase::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function orders(): HasMany
|
||||
{
|
||||
return $this->hasMany(Order::class, 'created_by_id');
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -16,6 +17,7 @@
|
||||
#[Appends(['birth_date_formatted', 'birth_date_input', 'gender_label'])]
|
||||
class UserProfile extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use InteractsWithActivityLog;
|
||||
use SoftDeletes;
|
||||
|
||||
@ -27,29 +29,29 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
protected function birthDateFormatted(): Attribute
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function birthDateFormatted(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => Carbon::parse($this->birth_date)->format('l, d F Y'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function birthDateInput(): Attribute
|
||||
public function birthDateInput(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->birth_date?->format('Y-m-d'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function genderLabel(): Attribute
|
||||
public function genderLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->gender?->label(),
|
||||
);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,14 +2,16 @@
|
||||
|
||||
namespace App\Services\Account;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ProfileService
|
||||
{
|
||||
public function update(array $validated): void
|
||||
/**
|
||||
* @param array<string, mixed> $validated
|
||||
*/
|
||||
public function update(array $validated, User $user): void
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
DB::transaction(function () use ($user, $validated): void {
|
||||
$user->email = $validated['email'];
|
||||
$user->username = $validated['username'];
|
||||
|
||||
23
app/Services/Concerns/ResolvesAuthEmployee.php
Normal file
23
app/Services/Concerns/ResolvesAuthEmployee.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Concerns;
|
||||
|
||||
use App\Models\Employee;
|
||||
use App\Models\User;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
trait ResolvesAuthEmployee
|
||||
{
|
||||
private function resolveAuthEmployee(?User $user = null): Employee
|
||||
{
|
||||
$employee = ($user ?? auth()->user())?->employee;
|
||||
|
||||
if ($employee === null) {
|
||||
throw ValidationException::withMessages([
|
||||
'employee' => 'Akun Anda tidak terhubung ke data pegawai.',
|
||||
]);
|
||||
}
|
||||
|
||||
return $employee;
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@
|
||||
|
||||
use App\Enums\EmployeeAdvanceStatus;
|
||||
use App\Models\EmployeeAdvance;
|
||||
use App\Models\User;
|
||||
use App\Services\Concerns\ResolvesAuthEmployee;
|
||||
use App\Services\Media\MediaService;
|
||||
use App\Support\Media\MediaPresenter;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
@ -13,6 +15,8 @@
|
||||
|
||||
class EmployeeAdvanceService
|
||||
{
|
||||
use ResolvesAuthEmployee;
|
||||
|
||||
private const MAX_PHOTOS = 1;
|
||||
|
||||
public function __construct(
|
||||
@ -75,15 +79,9 @@ public function paginateForIndex(array $tableQuery): LengthAwarePaginator
|
||||
/**
|
||||
* @param array{amount: int, description: string, due_date: string} $validated
|
||||
*/
|
||||
public function create(array $validated): void
|
||||
public function create(array $validated, User $user): void
|
||||
{
|
||||
$employee = auth()->user()?->employee;
|
||||
|
||||
if ($employee === null) {
|
||||
throw ValidationException::withMessages([
|
||||
'employee' => 'Akun Anda tidak terhubung ke data pegawai.',
|
||||
]);
|
||||
}
|
||||
$employee = $this->resolveAuthEmployee($user);
|
||||
|
||||
DB::transaction(function () use ($validated, $employee): void {
|
||||
$employeeAdvance = EmployeeAdvance::create([
|
||||
@ -101,9 +99,9 @@ public function create(array $validated): void
|
||||
/**
|
||||
* @param array{amount: int, description: string, due_date: string} $validated
|
||||
*/
|
||||
public function update(EmployeeAdvance $employeeAdvance, array $validated): void
|
||||
public function update(EmployeeAdvance $employeeAdvance, array $validated, User $user): void
|
||||
{
|
||||
$this->ensureOwnedBySubmitter($employeeAdvance);
|
||||
$this->ensureOwnedBySubmitter($employeeAdvance, $user);
|
||||
$this->ensurePending($employeeAdvance, 'Kasbon hanya dapat diubah saat status menunggu.');
|
||||
|
||||
DB::transaction(function () use ($employeeAdvance, $validated): void {
|
||||
@ -116,21 +114,19 @@ public function update(EmployeeAdvance $employeeAdvance, array $validated): void
|
||||
});
|
||||
}
|
||||
|
||||
public function delete(EmployeeAdvance $employeeAdvance): void
|
||||
public function delete(EmployeeAdvance $employeeAdvance, User $user): void
|
||||
{
|
||||
$this->ensureOwnedBySubmitter($employeeAdvance);
|
||||
$this->ensureOwnedBySubmitter($employeeAdvance, $user);
|
||||
$this->ensurePending($employeeAdvance, 'Kasbon hanya dapat dihapus saat status menunggu.');
|
||||
|
||||
$employeeAdvance->clearMediaCollection('photos');
|
||||
$employeeAdvance->delete();
|
||||
}
|
||||
|
||||
public function approve(EmployeeAdvance $employeeAdvance): void
|
||||
public function approve(EmployeeAdvance $employeeAdvance, User $user): void
|
||||
{
|
||||
$this->ensurePending($employeeAdvance, 'Kasbon ini sudah diverifikasi.');
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
DB::transaction(function () use ($employeeAdvance, $user): void {
|
||||
$employeeAdvance->loadMissing('employee.user.profile');
|
||||
|
||||
@ -154,12 +150,10 @@ public function approve(EmployeeAdvance $employeeAdvance): void
|
||||
});
|
||||
}
|
||||
|
||||
public function reject(EmployeeAdvance $employeeAdvance, string $reason): void
|
||||
public function reject(EmployeeAdvance $employeeAdvance, string $reason, User $user): void
|
||||
{
|
||||
$this->ensurePending($employeeAdvance, 'Kasbon ini sudah diverifikasi.');
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
DB::transaction(function () use ($employeeAdvance, $user, $reason): void {
|
||||
$employeeAdvance->status = EmployeeAdvanceStatus::REJECTED;
|
||||
$employeeAdvance->verified_at = now();
|
||||
@ -173,7 +167,7 @@ public function reject(EmployeeAdvance $employeeAdvance, string $reason): void
|
||||
});
|
||||
}
|
||||
|
||||
public function pay(EmployeeAdvance $employeeAdvance): void
|
||||
public function pay(EmployeeAdvance $employeeAdvance, User $user): void
|
||||
{
|
||||
if ($employeeAdvance->status !== EmployeeAdvanceStatus::APPROVED) {
|
||||
throw ValidationException::withMessages([
|
||||
@ -181,8 +175,6 @@ public function pay(EmployeeAdvance $employeeAdvance): void
|
||||
]);
|
||||
}
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
DB::transaction(function () use ($employeeAdvance, $user): void {
|
||||
$employeeAdvance->loadMissing('employee.user.profile');
|
||||
|
||||
@ -222,9 +214,9 @@ private function syncPhotos(EmployeeAdvance $employeeAdvance, array $validated):
|
||||
);
|
||||
}
|
||||
|
||||
private function ensureOwnedBySubmitter(EmployeeAdvance $employeeAdvance): void
|
||||
private function ensureOwnedBySubmitter(EmployeeAdvance $employeeAdvance, User $user): void
|
||||
{
|
||||
if (auth()->user()?->employee?->id !== $employeeAdvance->employee_id) {
|
||||
if ($user->employee?->id !== $employeeAdvance->employee_id) {
|
||||
throw ValidationException::withMessages([
|
||||
'employee_advance' => 'Anda tidak memiliki akses untuk mengubah kasbon ini.',
|
||||
]);
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
|
||||
use App\Models\Attendance;
|
||||
use App\Models\Employee;
|
||||
use App\Models\User;
|
||||
use App\Services\Concerns\ResolvesAuthEmployee;
|
||||
use App\Services\Media\MediaService;
|
||||
use Carbon\CarbonInterface;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
@ -13,6 +15,8 @@
|
||||
|
||||
class AttendanceService
|
||||
{
|
||||
use ResolvesAuthEmployee;
|
||||
|
||||
public function __construct(
|
||||
private readonly MediaService $mediaService,
|
||||
) {}
|
||||
@ -55,9 +59,9 @@ public function todayAttendanceForEmployee(Employee $employee): ?array
|
||||
/**
|
||||
* @param array{photo: string, latitude: float, longitude: float, location_tag: string} $validated
|
||||
*/
|
||||
public function checkIn(array $validated): void
|
||||
public function checkIn(array $validated, User $user): void
|
||||
{
|
||||
$employee = $this->resolveAuthEmployee();
|
||||
$employee = $this->resolveAuthEmployee($user);
|
||||
|
||||
$existing = Attendance::query()
|
||||
->where('employee_id', $employee->id)
|
||||
@ -96,9 +100,9 @@ public function checkIn(array $validated): void
|
||||
/**
|
||||
* @param array{photo: string, latitude: float, longitude: float, location_tag: string} $validated
|
||||
*/
|
||||
public function checkOut(array $validated): void
|
||||
public function checkOut(array $validated, User $user): void
|
||||
{
|
||||
$employee = $this->resolveAuthEmployee();
|
||||
$employee = $this->resolveAuthEmployee($user);
|
||||
|
||||
$attendance = Attendance::query()
|
||||
->where('employee_id', $employee->id)
|
||||
@ -148,19 +152,6 @@ public function delete(Attendance $attendance): void
|
||||
$attendance->delete();
|
||||
}
|
||||
|
||||
private function resolveAuthEmployee(): Employee
|
||||
{
|
||||
$employee = auth()->user()?->employee;
|
||||
|
||||
if ($employee === null) {
|
||||
throw ValidationException::withMessages([
|
||||
'employee' => 'Akun Anda tidak terhubung ke data pegawai.',
|
||||
]);
|
||||
}
|
||||
|
||||
return $employee;
|
||||
}
|
||||
|
||||
private function resolveLocationTag(string $clientTag, float $latitude, float $longitude): string
|
||||
{
|
||||
if ($clientTag !== '') {
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
|
||||
use App\Enums\LeaveRequestStatus;
|
||||
use App\Models\LeaveRequest;
|
||||
use App\Models\User;
|
||||
use App\Services\Concerns\ResolvesAuthEmployee;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
@ -12,6 +14,8 @@
|
||||
|
||||
class LeaveRequestService
|
||||
{
|
||||
use ResolvesAuthEmployee;
|
||||
|
||||
/**
|
||||
* @param array{search: string, sort: string, direction: 'asc'|'desc'} $tableQuery
|
||||
*/
|
||||
@ -38,15 +42,9 @@ public function paginateForIndex(array $tableQuery): LengthAwarePaginator
|
||||
/**
|
||||
* @param array{start_date: string, end_date: string} $validated
|
||||
*/
|
||||
public function create(array $validated): void
|
||||
public function create(array $validated, User $user): void
|
||||
{
|
||||
$employee = auth()->user()?->employee;
|
||||
|
||||
if ($employee === null) {
|
||||
throw ValidationException::withMessages([
|
||||
'employee' => 'Akun Anda tidak terhubung ke data pegawai.',
|
||||
]);
|
||||
}
|
||||
$employee = $this->resolveAuthEmployee($user);
|
||||
|
||||
$startDate = Carbon::parse($validated['start_date'])->startOfDay();
|
||||
$endDate = Carbon::parse($validated['end_date'])->startOfDay();
|
||||
@ -66,9 +64,9 @@ public function create(array $validated): void
|
||||
/**
|
||||
* @param array{start_date: string, end_date: string} $validated
|
||||
*/
|
||||
public function update(LeaveRequest $leaveRequest, array $validated): void
|
||||
public function update(LeaveRequest $leaveRequest, array $validated, User $user): void
|
||||
{
|
||||
$this->ensureOwnedBySubmitter($leaveRequest);
|
||||
$this->ensureOwnedBySubmitter($leaveRequest, $user);
|
||||
$this->ensurePending($leaveRequest, 'Pengajuan cuti hanya dapat diubah saat status menunggu.');
|
||||
|
||||
$startDate = Carbon::parse($validated['start_date'])->startOfDay();
|
||||
@ -83,20 +81,18 @@ public function update(LeaveRequest $leaveRequest, array $validated): void
|
||||
$leaveRequest->save();
|
||||
}
|
||||
|
||||
public function delete(LeaveRequest $leaveRequest): void
|
||||
public function delete(LeaveRequest $leaveRequest, User $user): void
|
||||
{
|
||||
$this->ensureOwnedBySubmitter($leaveRequest);
|
||||
$this->ensureOwnedBySubmitter($leaveRequest, $user);
|
||||
$this->ensurePending($leaveRequest, 'Pengajuan cuti hanya dapat dihapus saat status menunggu.');
|
||||
|
||||
$leaveRequest->delete();
|
||||
}
|
||||
|
||||
public function approve(LeaveRequest $leaveRequest): void
|
||||
public function approve(LeaveRequest $leaveRequest, User $user): void
|
||||
{
|
||||
$this->ensurePending($leaveRequest, 'Pengajuan cuti ini sudah diverifikasi.');
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
DB::transaction(function () use ($leaveRequest, $user): void {
|
||||
$leaveRequest->status = LeaveRequestStatus::APPROVED;
|
||||
$leaveRequest->verified_at = now();
|
||||
@ -105,12 +101,10 @@ public function approve(LeaveRequest $leaveRequest): void
|
||||
});
|
||||
}
|
||||
|
||||
public function reject(LeaveRequest $leaveRequest, string $reason): void
|
||||
public function reject(LeaveRequest $leaveRequest, string $reason, User $user): void
|
||||
{
|
||||
$this->ensurePending($leaveRequest, 'Pengajuan cuti ini sudah diverifikasi.');
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
DB::transaction(function () use ($leaveRequest, $user, $reason): void {
|
||||
$leaveRequest->status = LeaveRequestStatus::REJECTED;
|
||||
$leaveRequest->verified_at = now();
|
||||
@ -149,9 +143,9 @@ private function ensureValidDateRange(Carbon $startDate, Carbon $endDate): void
|
||||
}
|
||||
}
|
||||
|
||||
private function ensureOwnedBySubmitter(LeaveRequest $leaveRequest): void
|
||||
private function ensureOwnedBySubmitter(LeaveRequest $leaveRequest, User $user): void
|
||||
{
|
||||
if (auth()->user()?->employee?->id !== $leaveRequest->employee_id) {
|
||||
if ($user->employee?->id !== $leaveRequest->employee_id) {
|
||||
throw ValidationException::withMessages([
|
||||
'leave_request' => 'Anda tidak memiliki akses untuk mengubah pengajuan cuti ini.',
|
||||
]);
|
||||
|
||||
@ -209,7 +209,7 @@ public function update(Cutting $cutting, array $validated): void
|
||||
{
|
||||
if (! $cutting->status->isEditable()) {
|
||||
throw ValidationException::withMessages([
|
||||
'status' => 'Cutting tidak dapat diubah.',
|
||||
'status' => 'Proses potong tidak dapat diubah.',
|
||||
]);
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ public function delete(Cutting $cutting): void
|
||||
{
|
||||
if ($cutting->status !== CuttingStatus::IN_PROGRESS) {
|
||||
throw ValidationException::withMessages([
|
||||
'status' => 'Cutting hanya dapat dihapus saat masih proses.',
|
||||
'status' => 'Proses potong hanya dapat dihapus saat masih proses.',
|
||||
]);
|
||||
}
|
||||
|
||||
@ -252,15 +252,15 @@ public function delete(Cutting $cutting): void
|
||||
});
|
||||
}
|
||||
|
||||
public function transitionStatus(Cutting $cutting, CuttingStatus $status, ?string $reason = null): void
|
||||
public function transitionStatus(Cutting $cutting, CuttingStatus $status, User $user, ?string $reason = null): void
|
||||
{
|
||||
if (! $cutting->status->canTransitionTo($status)) {
|
||||
throw ValidationException::withMessages([
|
||||
'status' => 'Status cutting tidak dapat diubah.',
|
||||
'status' => 'Status proses potong tidak dapat diubah.',
|
||||
]);
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($cutting, $status, $reason): void {
|
||||
DB::transaction(function () use ($cutting, $status, $reason, $user): void {
|
||||
$cutting->load(['materials', 'results']);
|
||||
|
||||
if ($status === CuttingStatus::COMPLETED) {
|
||||
@ -273,7 +273,7 @@ public function transitionStatus(Cutting $cutting, CuttingStatus $status, ?strin
|
||||
|
||||
if ($status === CuttingStatus::REJECTED) {
|
||||
$this->reverseMaterialStock($cutting);
|
||||
$this->storeRejection($cutting, $reason);
|
||||
$this->storeRejection($cutting, $reason, $user);
|
||||
}
|
||||
|
||||
if ($status === CuttingStatus::IN_PROGRESS && $cutting->status === CuttingStatus::REJECTED) {
|
||||
@ -347,7 +347,7 @@ private function buildResults(array $results): array
|
||||
|
||||
if ($cuttingResult < 1) {
|
||||
throw ValidationException::withMessages([
|
||||
"results.{$index}.cutting_result" => 'Hasil cutting minimal 1 pcs.',
|
||||
"results.{$index}.cutting_result" => 'Hasil potong minimal 1 pcs.',
|
||||
]);
|
||||
}
|
||||
|
||||
@ -365,7 +365,7 @@ private function buildResults(array $results): array
|
||||
|
||||
if (($warehouseStock + $cuttingReject) !== $cuttingResult) {
|
||||
throw ValidationException::withMessages([
|
||||
"results.{$index}.cutting_result" => 'Hasil cutting harus sama dengan stok gudang ditambah reject.',
|
||||
"results.{$index}.cutting_result" => 'Hasil potong harus sama dengan stok gudang ditambah reject.',
|
||||
]);
|
||||
}
|
||||
|
||||
@ -427,7 +427,7 @@ private function applyProductStockOnVerify(Cutting $cutting): void
|
||||
}
|
||||
}
|
||||
|
||||
private function storeRejection(Cutting $cutting, ?string $reason): void
|
||||
private function storeRejection(Cutting $cutting, ?string $reason, User $user): void
|
||||
{
|
||||
if ($reason === null || trim($reason) === '') {
|
||||
throw ValidationException::withMessages([
|
||||
@ -435,8 +435,6 @@ private function storeRejection(Cutting $cutting, ?string $reason): void
|
||||
]);
|
||||
}
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
$cutting->rejection()?->delete();
|
||||
|
||||
$cutting->rejection()->create([
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
class PurchaseService
|
||||
{
|
||||
private const MAX_PHOTOS_FILES = 1;
|
||||
private const MAX_PHOTOS = 1;
|
||||
|
||||
public function __construct(
|
||||
private readonly MediaService $mediaService,
|
||||
@ -262,7 +262,7 @@ private function syncPhotos(Purchase $purchase, array $validated): void
|
||||
'photos',
|
||||
$validated['photos'] ?? null,
|
||||
$validated['remove_media_ids'] ?? null,
|
||||
self::MAX_PHOTOS_FILES,
|
||||
self::MAX_PHOTOS,
|
||||
required: false,
|
||||
errorKey: 'photos',
|
||||
);
|
||||
|
||||
@ -41,8 +41,7 @@ public function create(array $validated): void
|
||||
*/
|
||||
public function update(Category $category, array $validated): void
|
||||
{
|
||||
$category->name = $validated['name'];
|
||||
$category->save();
|
||||
$category->fill($validated)->save();
|
||||
}
|
||||
|
||||
public function delete(Category $category): void
|
||||
|
||||
@ -43,10 +43,7 @@ public function create(array $validated): void
|
||||
*/
|
||||
public function update(Customer $customer, array $validated): void
|
||||
{
|
||||
$customer->name = $validated['name'];
|
||||
$customer->phone_number = $validated['phone_number'];
|
||||
$customer->address = $validated['address'];
|
||||
$customer->save();
|
||||
$customer->fill($validated)->save();
|
||||
}
|
||||
|
||||
public function delete(Customer $customer): void
|
||||
|
||||
@ -43,10 +43,7 @@ public function create(array $validated): void
|
||||
*/
|
||||
public function update(Supplier $supplier, array $validated): void
|
||||
{
|
||||
$supplier->name = $validated['name'];
|
||||
$supplier->phone_number = $validated['phone_number'];
|
||||
$supplier->address = $validated['address'];
|
||||
$supplier->save();
|
||||
$supplier->fill($validated)->save();
|
||||
}
|
||||
|
||||
public function delete(Supplier $supplier): void
|
||||
|
||||
47
database/factories/AttendanceFactory.php
Normal file
47
database/factories/AttendanceFactory.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Attendance;
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<Attendance>
|
||||
*/
|
||||
class AttendanceFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
$checkInAt = fake()->dateTimeBetween('-30 days', 'now');
|
||||
$checkOutAt = (clone $checkInAt)->modify('+'.fake()->numberBetween(4, 9).' hours');
|
||||
|
||||
return [
|
||||
'employee_id' => Employee::factory(),
|
||||
'attendance_date' => $checkInAt->format('Y-m-d'),
|
||||
'check_in_at' => $checkInAt,
|
||||
'check_out_at' => $checkOutAt,
|
||||
'check_in_photo_path' => 'attendance/checkin/'.fake()->uuid().'.jpg',
|
||||
'check_out_photo_path' => 'attendance/checkout/'.fake()->uuid().'.jpg',
|
||||
'check_in_latitude' => fake()->latitude(-7, -6),
|
||||
'check_in_longitude' => fake()->longitude(106, 107),
|
||||
'check_out_latitude' => fake()->latitude(-7, -6),
|
||||
'check_out_longitude' => fake()->longitude(106, 107),
|
||||
'check_in_location_tag' => fake()->optional()->city(),
|
||||
'check_out_location_tag' => fake()->optional()->city(),
|
||||
'work_duration_minutes' => fake()->numberBetween(240, 540),
|
||||
];
|
||||
}
|
||||
|
||||
public function checkedInOnly(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'check_out_at' => null,
|
||||
'check_out_photo_path' => null,
|
||||
'check_out_latitude' => null,
|
||||
'check_out_longitude' => null,
|
||||
'check_out_location_tag' => null,
|
||||
'work_duration_minutes' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
22
database/factories/CashAccountFactory.php
Normal file
22
database/factories/CashAccountFactory.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\CashAccount;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<CashAccount>
|
||||
*/
|
||||
class CashAccountFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'created_by_id' => User::factory(),
|
||||
'name' => fake()->randomElement(['Kas Toko', 'Kas Operasional', 'Kas Utama']),
|
||||
'balance' => 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
37
database/factories/CashTransactionFactory.php
Normal file
37
database/factories/CashTransactionFactory.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\CashAccount;
|
||||
use App\Models\CashTransaction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<CashTransaction>
|
||||
*/
|
||||
class CashTransactionFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
$amount = fake()->numberBetween(10_000, 5_000_000);
|
||||
|
||||
return [
|
||||
'cash_account_id' => CashAccount::factory(),
|
||||
'created_by_id' => User::factory(),
|
||||
'reference_type' => null,
|
||||
'reference_id' => null,
|
||||
'amount' => $amount,
|
||||
'balance_after' => $amount,
|
||||
'description' => fake()->sentence(3),
|
||||
];
|
||||
}
|
||||
|
||||
public function deposit(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'reference_type' => null,
|
||||
'reference_id' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
23
database/factories/CategoryFactory.php
Normal file
23
database/factories/CategoryFactory.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Category;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends Factory<Category>
|
||||
*/
|
||||
class CategoryFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
$name = fake()->unique()->words(2, true);
|
||||
|
||||
return [
|
||||
'name' => Str::limit($name, 50, ''),
|
||||
'slug' => Str::slug($name),
|
||||
];
|
||||
}
|
||||
}
|
||||
21
database/factories/CustomerFactory.php
Normal file
21
database/factories/CustomerFactory.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<Customer>
|
||||
*/
|
||||
class CustomerFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->name(),
|
||||
'phone_number' => fake()->numerify('08##########'),
|
||||
'address' => fake()->optional()->address(),
|
||||
];
|
||||
}
|
||||
}
|
||||
37
database/factories/CuttingFactory.php
Normal file
37
database/factories/CuttingFactory.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Enums\CuttingStatus;
|
||||
use App\Models\Cutting;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<Cutting>
|
||||
*/
|
||||
class CuttingFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'status' => CuttingStatus::IN_PROGRESS->value,
|
||||
'description' => fake()->optional()->sentence(3),
|
||||
'created_by_id' => User::factory(),
|
||||
];
|
||||
}
|
||||
|
||||
public function completed(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'status' => CuttingStatus::COMPLETED->value,
|
||||
]);
|
||||
}
|
||||
|
||||
public function verified(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'status' => CuttingStatus::VERIFIED->value,
|
||||
]);
|
||||
}
|
||||
}
|
||||
27
database/factories/CuttingMaterialFactory.php
Normal file
27
database/factories/CuttingMaterialFactory.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Cutting;
|
||||
use App\Models\CuttingMaterial;
|
||||
use App\Models\RawMaterialPrice;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<CuttingMaterial>
|
||||
*/
|
||||
class CuttingMaterialFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
$materialUsage = fake()->randomFloat(4, 1, 25);
|
||||
$remainingMaterial = fake()->randomFloat(4, 0, 10);
|
||||
|
||||
return [
|
||||
'cutting_id' => Cutting::factory(),
|
||||
'raw_material_price_id' => RawMaterialPrice::factory(),
|
||||
'material_usage' => $materialUsage,
|
||||
'remaining_material' => $remainingMaterial,
|
||||
];
|
||||
}
|
||||
}
|
||||
28
database/factories/CuttingResultFactory.php
Normal file
28
database/factories/CuttingResultFactory.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Cutting;
|
||||
use App\Models\CuttingResult;
|
||||
use App\Models\ProductVariant;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<CuttingResult>
|
||||
*/
|
||||
class CuttingResultFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
$cuttingResult = fake()->numberBetween(10, 200);
|
||||
$cuttingReject = fake()->numberBetween(0, (int) ($cuttingResult * 0.1));
|
||||
|
||||
return [
|
||||
'cutting_id' => Cutting::factory(),
|
||||
'product_variant_id' => ProductVariant::factory(),
|
||||
'cutting_result' => $cuttingResult,
|
||||
'warehouse_stock' => $cuttingResult - $cuttingReject,
|
||||
'cutting_reject' => $cuttingReject,
|
||||
];
|
||||
}
|
||||
}
|
||||
50
database/factories/EmployeeAdvanceFactory.php
Normal file
50
database/factories/EmployeeAdvanceFactory.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Enums\EmployeeAdvanceStatus;
|
||||
use App\Models\Employee;
|
||||
use App\Models\EmployeeAdvance;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<EmployeeAdvance>
|
||||
*/
|
||||
class EmployeeAdvanceFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'employee_id' => Employee::factory(),
|
||||
'amount' => fake()->numberBetween(100_000, 3_000_000),
|
||||
'description' => fake()->sentence(3),
|
||||
'due_date' => fake()->dateTimeBetween('now', '+3 months'),
|
||||
'status' => EmployeeAdvanceStatus::PENDING->value,
|
||||
'cash_transaction_id' => null,
|
||||
'repayment_cash_transaction_id' => null,
|
||||
'verified_at' => null,
|
||||
'verified_by_id' => null,
|
||||
'paid_at' => null,
|
||||
'paid_by_id' => null,
|
||||
];
|
||||
}
|
||||
|
||||
public function approved(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'status' => EmployeeAdvanceStatus::APPROVED->value,
|
||||
'verified_at' => now(),
|
||||
'verified_by_id' => User::factory(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function rejected(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'status' => EmployeeAdvanceStatus::REJECTED->value,
|
||||
'verified_at' => now(),
|
||||
'verified_by_id' => User::factory(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user