Initial commit - expense
Deploy to VPS (PAT over HTTPS) / deploy (push) Has been cancelled

This commit is contained in:
root
2026-06-01 15:01:03 +07:00
parent 9e9fab4a3f
commit 1c1418f3e0
123 changed files with 18622 additions and 10376 deletions
+51 -21
View File
@@ -4,29 +4,59 @@ namespace App\Helpers;
use Illuminate\Support\Facades\Auth;
use App\Models\AuditTrail;
use Illuminate\Support\Facades\Request;
class AuditTrailHelper
{
public static function AddAuditTrail($action, $activity)
{
$audit = new AuditTrail();
$audit->user_id = Auth::user()->id;
$audit->ip_address = request()->ip();
$audit->activity = $activity;
$audit->action = $action;
$audit->user_agent = request()->userAgent();
$audit->browser = substr($audit->user_agent, 0, strpos($audit->user_agent, '/'));
$audit->save();
}
/**
* Mencatat aktivitas umum (Insert, Update, Delete, Approve, Reject)
*/
public static function AddAuditTrail($action, $activity)
{
// Menggunakan guard 'admin' sesuai spesifikasi login aplikasi Anda
$user = Auth::guard('admin')->user();
public static function AuthAttempt($action, $activity)
{
$audit = new AuditTrail();
$audit->ip_address = request()->ip();
$audit->activity = $activity;
$audit->action = $action;
$audit->user_agent = request()->userAgent();
$audit->browser = substr($audit->user_agent, 0, strpos($audit->user_agent, '/'));
$audit->save();
}
$audit = new AuditTrail();
$audit->user_id = $user ? $user->id : null;
$audit->ip_address = Request::ip();
$audit->activity = $activity;
$audit->action = $action;
$audit->user_agent = Request::userAgent();
$audit->browser = self::getBrowserName(Request::userAgent());
$audit->save();
}
/**
* Mencatat percobaan otentikasi (Login/Logout)
*/
public static function AuthAttempt($action, $activity)
{
$audit = new AuditTrail();
$audit->user_id = Auth::guard('admin')->id(); // Tetap coba ambil ID jika ada (misal saat logout)
$audit->ip_address = Request::ip();
$audit->activity = $activity;
$audit->action = $action;
$audit->user_agent = Request::userAgent();
$audit->browser = self::getBrowserName(Request::userAgent());
$audit->save();
}
/**
* Helper internal untuk deteksi browser yang lebih bersih
*/
private static function getBrowserName($userAgent)
{
if (!$userAgent) return 'Unknown';
if (strpos($userAgent, 'Opera') || strpos($userAgent, 'OPR')) return 'Opera';
if (strpos($userAgent, 'Edge')) return 'Edge';
if (strpos($userAgent, 'Chrome')) return 'Chrome';
if (strpos($userAgent, 'Safari')) return 'Safari';
if (strpos($userAgent, 'Firefox')) return 'Firefox';
if (strpos($userAgent, 'MSIE') || strpos($userAgent, 'Trident/7')) return 'Internet Explorer';
return explode('/', $userAgent)[0] ?? 'Unknown';
}
}
+317 -70
View File
@@ -2,97 +2,344 @@
namespace App\Helpers;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Str;
use App\Models\Kategori;
use App\Models\BudgetControl;
use App\Models\FormUpCountry;
use App\Models\FormMeetingSeminar;
use App\Models\FormOthers;
use App\Models\FormEntertaimentPresentation;
use App\Models\FormVehicleRunningCost;
use App\Helpers\FormHelper;
use App\Models\UserHasCabang;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class BudgetHelper
{
/**
* Cache memori sementara untuk fungsi jurnal agar loading halaman riwayat tidak berat.
*/
private static $jurnalCache = [];
/**
* Daftar status yang akan memotong (menge-hold) sisa budget secara real-time.
*/
const HOLD_STATUSES = [
'Approved 1',
'Approved 2',
'Waiting Approval',
'Validated',
'Approved',
'Closed',
'Completed'
];
public static function getBulkAvailableBudget($budgetControls)
{
if ($budgetControls->isEmpty()) return [];
$cabangIds = $budgetControls->pluck('cabang_id')->unique()->toArray();
// 1. Mapping User per Cabang
$branchUsers = UserHasCabang::whereIn('cabang_id', $cabangIds)
->get()
->groupBy('cabang_id')
->map(fn($item) => $item->pluck('user_id')->toArray());
$allUserIds = $branchUsers->flatten()->unique()->toArray();
$resultsMap = [];
if (empty($allUserIds)) return [];
$formModels = [
'tanggal' => [
FormUpCountry::class,
FormVehicleRunningCost::class,
FormEntertaimentPresentation::class,
FormOthers::class
],
'created_at' => [
FormMeetingSeminar::class
]
];
// 2. Tarik data pengeluaran sekaligus dari semua tabel form
foreach ($formModels as $dateColumn => $models) {
foreach ($models as $model) {
$query = $model::whereIn('user_id', $allUserIds)
->whereIn('status', self::HOLD_STATUSES)
->select(
'user_id',
DB::raw("MONTH($dateColumn) as month"),
DB::raw("YEAR($dateColumn) as year"),
DB::raw("SUM(approved_total) as total")
)
->groupBy('user_id', 'month', 'year')
->get();
// 3. Masukkan ke Map berdasarkan Cabang_Bulan_Tahun
foreach ($query as $row) {
foreach ($branchUsers as $cabangId => $userIds) {
if (in_array($row->user_id, $userIds)) {
$monthName = strtolower(date('F', mktime(0, 0, 0, $row->month, 10)));
$key = "{$cabangId}_{$monthName}_{$row->year}";
$resultsMap[$key] = ($resultsMap[$key] ?? 0) + $row->total;
}
}
}
}
}
return $resultsMap;
}
/**
* Menghitung sisa budget (Pagu - Total Hold/Terpakai).
* Tetap menggunakan kolom tanggal/created_at karena pengajuan yang baru
* dibuat (Approved 1) belum memiliki final_approved_at.
*/
public static function getAvailableBudget($cabang_id, $periode_month, $periode_year)
{
// Validasi & normalisasi
$periode_month = strtolower($periode_month);
$periode_year = (int) $periode_year;
{
$periode_month = strtolower($periode_month);
$periode_year = (int) $periode_year;
// Ambil budget sesuai cabang dan periode
$budget = BudgetControl::where('cabang_id', $cabang_id)
->where('periode_month', $periode_month)
->where('periode_year', $periode_year)
->with(['user.cabang'])
->get();
$totalPagu = BudgetControl::where('cabang_id', $cabang_id)
->where('periode_month', $periode_month)
->where('periode_year', $periode_year)
->sum('amount');
$usedBudget = 0;
if ($totalPagu <= 0) return 0;
$users = UserHasCabang::where('cabang_id', $cabang_id)->get();
$userIds = $users->pluck('user_id')->toArray();
$userIds = UserHasCabang::where('cabang_id', $cabang_id)->pluck('user_id')->toArray();
$forms = FormHelper::getTotalAmount($userIds, $periode_month, $periode_year)
->sortByDesc('tanggal')
->sortByDesc('created_at');
if (empty($userIds)) return $totalPagu;
$usedBudget += $forms->sum('approved_total');
$usedBudget = 0;
$monthNumeric = date('m', strtotime($periode_month));
$availableBudget = $budget->sum('amount') - $usedBudget;
$formModels = [
FormUpCountry::class,
FormVehicleRunningCost::class,
FormEntertaimentPresentation::class,
FormMeetingSeminar::class,
FormOthers::class
];
return $availableBudget;
}
foreach ($formModels as $model) {
$query = $model::whereIn('user_id', $userIds)
->whereIn('status', self::HOLD_STATUSES);
public static function getNominalByFormType($userIds, $type, $type_id, $month, $year)
{
if ($type == 'Up Country') {
$form = FormUpCountry::select('approved_total')
->whereIn('user_id', $userIds)
->whereMonth('tanggal', '=', date('m', strtotime($month)))
->whereYear('tanggal', '=', $year)
->whereIn('status', ['Approved', 'Closed'])
->get();
} elseif ($type == 'Vehicle Running Cost') {
$form = FormVehicleRunningCost::select('approved_total')
->whereIn('user_id', $userIds)
->whereMonth('tanggal', '=', date('m', strtotime($month)))
->whereYear('tanggal', '=', $year)
->whereIn('status', ['Approved', 'Closed'])
->get();
} elseif ($type == 'Entertainment') {
$form = FormEntertaimentPresentation::select('approved_total')
->whereIn('user_id', $userIds)
->whereMonth('tanggal', '=', date('m', strtotime($month)))
->whereYear('tanggal', '=', $year)
->whereIn('status', ['Approved', 'Closed'])
->get();
} elseif ($type == 'Meeting / Seminar') {
$form = FormMeetingSeminar::select('approved_total')
->whereIn('user_id', $userIds)
->whereMonth('created_at', '=', date('m', strtotime($month)))
->whereYear('created_at', '=', $year)
->whereIn('status', ['Approved', 'Closed'])
->get();
} else {
$form = FormOthers::select('approved_total')
->whereIn('user_id', $userIds)
->whereMonth('tanggal', '=', date('m', strtotime($month)))
->whereYear('tanggal', '=', $year)
->where('kategori_id', $type_id)
->whereIn('status', ['Approved', 'Closed'])
->get();
}
if ($model === FormMeetingSeminar::class) {
$query->whereMonth('created_at', $monthNumeric)
->whereYear('created_at', $periode_year);
} else {
$query->whereMonth('tanggal', $monthNumeric)
->whereYear('tanggal', $periode_year);
}
return $form->sum('approved_total');
}
$usedBudget += $query->sum('approved_total');
}
public static function getClosingDate($cabang_id)
{
$budget = BudgetControl::where('cabang_id', $cabang_id)->orderBy('created_at', 'desc')->first();
return $totalPagu - $usedBudget;
}
return $budget->closing_at;
}
/**
* Memvalidasi apakah tanggal expense yang diinput user berada dalam
* rentang periode aktif (Tanggal 11 s/d 10).
*/
public static function checkExpenseInputWindow($tanggal_expense)
{
$inputDate = \Carbon\Carbon::parse($tanggal_expense)->startOfDay();
$today = \Carbon\Carbon::now();
$startDay = 11;
$endDay = 10;
// Menentukan jendela periode yang sedang aktif hari ini
if ($today->day >= $startDay) {
// Jika hari ini tgl 11 atau lebih: Jendela aktif adalah Tgl 11 bulan ini s/d Tgl 10 bulan depan
$periodStart = \Carbon\Carbon::create($today->year, $today->month, $startDay)->startOfDay();
$periodEnd = \Carbon\Carbon::create($today->year, $today->month, $endDay)->addMonth()->endOfDay();
} else {
// Jika hari ini tgl 1-10: Jendela aktif adalah Tgl 11 bulan lalu s/d Tgl 10 bulan ini
$periodStart = \Carbon\Carbon::create($today->year, $today->month, $startDay)->subMonth()->startOfDay();
$periodEnd = \Carbon\Carbon::create($today->year, $today->month, $endDay)->endOfDay();
}
// Jika tanggal form yang diinput user berada di luar jendela aktif
if ($inputDate->lt($periodStart) || $inputDate->gt($periodEnd)) {
return [
'is_valid' => false,
'message' => "Gagal! Batas input expense untuk periode aktif saat ini adalah {$periodStart->format('d M Y')} s/d {$periodEnd->format('d M Y')}. Tanggal {$inputDate->format('d M Y')} sudah ditutup atau belum dibuka."
];
}
return ['is_valid' => true];
}
/**
* Mengambil nominal per tipe form.
*/
public static function getNominalByFormType($userIds, $type, $type_id, $month, $year)
{
$monthNumeric = date('m', strtotime($month));
$used = 0;
if ($type == 'Up Country') {
$used = FormUpCountry::whereIn('user_id', $userIds)
->whereMonth('tanggal', $monthNumeric)->whereYear('tanggal', $year)
->whereIn('status', self::HOLD_STATUSES)->sum('approved_total');
} elseif ($type == 'Vehicle Running Cost') {
$used = FormVehicleRunningCost::whereIn('user_id', $userIds)
->whereMonth('tanggal', $monthNumeric)->whereYear('tanggal', $year)
->whereIn('status', self::HOLD_STATUSES)->sum('approved_total');
} elseif ($type == 'Entertainment') {
$used = FormEntertaimentPresentation::whereIn('user_id', $userIds)
->whereMonth('tanggal', $monthNumeric)->whereYear('tanggal', $year)
->whereIn('status', self::HOLD_STATUSES)->sum('approved_total');
} elseif ($type == 'Meeting / Seminar') {
$used = FormMeetingSeminar::whereIn('user_id', $userIds)
->whereMonth('created_at', $monthNumeric)->whereYear('created_at', $year)
->whereIn('status', self::HOLD_STATUSES)->sum('approved_total');
} else {
$used = FormOthers::whereIn('user_id', $userIds)
->where('kategori_id', $type_id)
->whereMonth('tanggal', $monthNumeric)->whereYear('tanggal', $year)
->whereIn('status', self::HOLD_STATUSES)->sum('approved_total');
}
return $used;
}
/**
* Mengambil tanggal closing.
*/
public static function getClosingDate($cabang_id)
{
return BudgetControl::where('cabang_id', $cabang_id)
->orderBy('created_at', 'desc')
->value('closing_at');
}
/**
* KALKULASI JURNAL AKUNTANSI
* Berlaku seragam menggunakan kolom final_approved_at untuk semua form
* Cut-off Date: Tgl 11 s/d Tgl 13 Bulan Berikutnya
*/
/**
* KALKULASI JURNAL AKUNTANSI (Log & Report)
* Sinkron dengan 12 Kategori Utama & Akun 800xxx
*/
// public static function getKalkulasiJurnal($cabang_id, $periode_month, $periode_year)
// {
// $periode_month = strtolower($periode_month);
// $periode_year = (int) $periode_year;
// $cacheKey = "{$cabang_id}_{$periode_month}_{$periode_year}";
// if (isset(self::$jurnalCache[$cacheKey])) return self::$jurnalCache[$cacheKey];
// $userIds = UserHasCabang::where('cabang_id', $cabang_id)->pluck('user_id')->toArray();
// $totalDebet = 0;
// if (!empty($userIds)) {
// // Ambil Range Tanggal (Contoh: 11 Maret - 13 April)
// $startDay = env('STARTING_DATE', 11);
// $closeDay = env('CLOSING_DATE', 13);
// $monthNumeric = date('m', strtotime($periode_month));
// $startDate = Carbon::create($periode_year, $monthNumeric, $startDay)->startOfDay();
// $endDate = Carbon::create($periode_year, $monthNumeric, $closeDay)->addMonth()->endOfDay();
// // Mapping Model dengan pengamanan Typo
// $formModels = [
// 'Up Country' => FormUpCountry::class,
// 'Vehicle Running Cost' => FormVehicleRunningCost::class,
// 'Entertainment' => FormEntertaimentPresentation::class,
// 'Entertaiment' => FormEntertaimentPresentation::class,
// 'Presentation' => FormEntertaimentPresentation::class,
// 'Meeting / Seminar' => FormMeetingSeminar::class,
// ];
// // Ambil kategori yang punya account_number dan tidak dikecualikan
// $kategoris = \App\Models\Kategori::whereNotIn('name', ['Cash in Bank BCA', 'Donasi/Gift', 'PPn Masukan', 'Sponsorship'])
// ->whereNotNull('account_number')
// ->where('account_number', '!=', '')
// ->get();
// foreach ($kategoris as $kat) {
// $katName = trim($kat->name);
// if (isset($formModels[$katName])) {
// $model = $formModels[$katName];
// $query = $model::whereIn('user_id', $userIds)
// ->whereIn('status', ['Closed', 'Final Approved'])
// ->whereBetween('final_approved_at', [$startDate, $endDate]);
// // PENTING: Filter berdasarkan kategori_id agar data tidak tertukar di tabel yang sama
// if (\Illuminate\Support\Facades\Schema::hasColumn((new $model)->getTable(), 'kategori_id')) {
// $query->where('kategori_id', $kat->id);
// }
// $totalDebet += $query->sum('approved_total');
// } else {
// // Masuk ke Form Others
// $totalDebet += FormOthers::whereIn('user_id', $userIds)
// ->where('kategori_id', $kat->id)
// ->whereIn('status', ['Closed', 'Final Approved'])
// ->whereBetween('final_approved_at', [$startDate, $endDate])
// ->sum('approved_total');
// }
// }
// }
// self::$jurnalCache[$cacheKey] = $totalDebet;
// return $totalDebet;
// }
public static function getBulkKalkulasiJurnal(array $lookups)
{
if (empty($lookups)) return [];
$resultsMap = [];
$startDay = 11; // Batas awal periode (Contoh: tgl 11)
$closeDay = 13; // Batas akhir approval (Contoh: tgl 13 bulan depan)
foreach ($lookups as $item) {
$cabId = $item['cabang_id'];
$monthNumeric = date('m', strtotime($item['month']));
$year = (int) $item['year'];
$key = $cabId . '_' . strtolower($item['month']) . '_' . $year;
// Penentuan Rentang Tanggal Cut-off Akuntansi
$startDate = \Illuminate\Support\Carbon::create($year, $monthNumeric, $startDay)->startOfDay();
$endDate = $startDate->copy()->addMonth()->day($closeDay)->endOfDay();
$userIds = \App\Models\UserHasCabang::where('cabang_id', $cabId)->pluck('user_id')->toArray();
if (empty($userIds)) {
$resultsMap[$key] = 0;
continue;
}
// Menghitung Total Pengeluaran Riil (Status: Closed / Final Approved)
$tables = ['form_up_country', 'form_vehicle_running_cost', 'form_entertainment_presentation', 'form_meeting_seminar', 'form_others'];
$totalExpense = 0;
foreach ($tables as $table) {
$totalExpense += \Illuminate\Support\Facades\DB::table($table)
->whereIn('user_id', $userIds)
->whereIn('status', ['Closed', 'Final Approved'])
->whereBetween('final_approved_at', [$startDate, $endDate])
->sum('approved_total');
}
$resultsMap[$key] = $totalExpense;
}
return $resultsMap;
}
}
+366
View File
@@ -0,0 +1,366 @@
<?php
namespace App\Helpers;
use App\Models\Admin;
use App\Models\FormEntertaimentPresentation;
use App\Models\FormMeetingSeminar;
use App\Models\FormOthers;
use App\Models\FormUpCountry;
use App\Models\FormVehicleRunningCost;
use Illuminate\Support\Facades\DB;
use App\Models\UserHasCabang;
class FormHelper
{
public static function getFormsByUserIds($userIds, $month, $year) {
$monthNumber = date('m', strtotime($month . ' 1'));
$startDate = "$year-$monthNumber-" . env('STARTING_DATE');
$nextMonthTimestamp = strtotime("first day of next month", strtotime("$year-$monthNumber-01"));
$closingDateNextMonth = date('Y-m-', $nextMonthTimestamp) . env('CLOSING_DATE');
$users = Admin::with(['region', 'cabang'])
->whereIn('id', $userIds)
->get();
$formUpCountryQuery = FormUpCountry::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Up Country' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Vehicle Running Cost' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Entertainment Presentation' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formMeetingSeminarQuery = FormMeetingSeminar::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Meeting Seminar' as type")
)->whereIn('user_id', $userIds)
->whereBetween('created_at', [$startDate, $closingDateNextMonth]);
$formOthersQuery = FormOthers::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Others' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
// Use union to combine queries
$forms = $formUpCountryQuery
->union($formVehicleRunningCostQuery)
->union($formEntertaimentPresentationQuery)
->union($formMeetingSeminarQuery)
->union($formOthersQuery)
->get();
// Return forms with eager loaded user details
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
public static function getAllForms($month, $year) {
$monthNumber = date('m', strtotime($month . ' 1'));
$startDate = "$year-$monthNumber-" . env('STARTING_DATE');
$nextMonthTimestamp = strtotime("first day of next month", strtotime("$year-$monthNumber-01"));
$closingDateNextMonth = date('Y-m-', $nextMonthTimestamp) . env('CLOSING_DATE');
$users = Admin::with(['region', 'cabang'])
->get();
$formUpCountryQuery = FormUpCountry::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Up Country' as type")
)->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Vehicle Running Cost' as type")
)->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Entertainment Presentation' as type")
)->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formMeetingSeminarQuery = FormMeetingSeminar::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Meeting Seminar' as type")
)->whereBetween('created_at', [$startDate, $closingDateNextMonth]);
$formOthersQuery = FormOthers::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Others' as type")
)->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
// Combine queries using union
$forms = $formUpCountryQuery
->union($formVehicleRunningCostQuery)
->union($formEntertaimentPresentationQuery)
->union($formMeetingSeminarQuery)
->union($formOthersQuery)
->get();
// Map users to the forms with eager loaded data
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
public static function getAllForms2() {
// Get all users with eager loading for 'region' and 'cabang'
$users = Admin::with(['region', 'cabang'])
->get();
$formUpCountryQuery = FormUpCountry::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Up Country' as type")
);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Vehicle Running Cost' as type")
);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Entertainment Presentation' as type")
);
$formMeetingSeminarQuery = FormMeetingSeminar::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Meeting Seminar' as type")
);
$formOthersQuery = FormOthers::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Others' as type")
);
// Combine queries using union
$forms = $formUpCountryQuery
->union($formVehicleRunningCostQuery)
->union($formEntertaimentPresentationQuery)
->union($formMeetingSeminarQuery)
->union($formOthersQuery)
->get();
// Map users to the forms with eager loaded data
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
public static function getNominalByFormType($cabang_id, $type, $type_id, $month, $year) {
$users = UserHasCabang::where('cabang_id', $cabang_id)->get();
$userIds = $users->pluck('user_id')->toArray();
if($type == 'Up Country') {
$form = FormUpCountry::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('tanggal', '=', date('m', strtotime($month)))->whereYear('tanggal', '=', $year)->where('status', ['Approved', 'Closed'])->get();
} else if($type == 'Vehicle Running Cost') {
$form = FormVehicleRunningCost::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('tanggal', '=', date('m', strtotime($month)))->whereYear('tanggal', '=', $year)->where('status', ['Approved', 'Closed'])->get();
} else if($type == 'Entertainment') {
$form = FormEntertaimentPresentation::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('tanggal', '=', date('m', strtotime($month)))->whereYear('tanggal', '=', $year)->where('status', ['Approved', 'Closed'])->get();
} else if($type == 'Meeting / Seminar') {
$form = FormMeetingSeminar::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('created_at', '=', date('m', strtotime($month)))->whereYear('created_at', '=', $year)->where('status', ['Approved', 'Closed'])->get();
} else {
$form = FormOthers::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('tanggal', '=', date('m', strtotime($month)))->whereYear('tanggal', '=', $year)->where('kategori_id', $type_id)->where('status', ['Approved', 'Closed'])->get();
}
$nominal = $form->sum('approved_total');
return $nominal;
}
public static function getTotalAmount($userIds, $month, $year) {
$monthNumber = date('m', strtotime($month . ' 1'));
$startDate = "$year-$monthNumber-" . env('STARTING_DATE');
$nextMonthTimestamp = strtotime("first day of next month", strtotime("$year-$monthNumber-01"));
$closingDateNextMonth = date('Y-m-', $nextMonthTimestamp) . env('CLOSING_DATE');
$users = Admin::with(['region', 'cabang'])
->whereIn('id', $userIds)
->get();
$formUpCountryQuery = FormUpCountry::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Up Country' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Vehicle Running Cost' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Entertainment Presentation' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
$formMeetingSeminarQuery = FormMeetingSeminar::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Meeting Seminar' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
$formOthersQuery = FormOthers::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Others' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
// Use union to combine queries
$forms = $formUpCountryQuery
->union($formVehicleRunningCostQuery)
->union($formEntertaimentPresentationQuery)
->union($formMeetingSeminarQuery)
->union($formOthersQuery)
->get();
// Return forms with eager loaded user details
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
}
+193 -347
View File
@@ -10,357 +10,203 @@ use App\Models\FormUpCountry;
use App\Models\FormVehicleRunningCost;
use Illuminate\Support\Facades\DB;
use App\Models\UserHasCabang;
use Illuminate\Support\Carbon;
class FormHelper
{
public static function getFormsByUserIds($userIds, $month, $year) {
$monthNumber = date('m', strtotime($month . ' 1'));
$startDate = "$year-$monthNumber-" . env('STARTING_DATE');
/**
* Helper internal untuk menghitung rentang siklus tanggal
* Menghasilkan: Start (11), Max Input (10 bln depan), Closing (13 bln depan)
*/
private static function getCycleRange($month, $year)
{
// Pastikan di-cast ke (int) agar Carbon tidak error
$startDay = (int) env('STARTING_DATE', 11);
$maxInputDay = (int) env('INPUT_MAX_DATE', 10);
$closingDay = (int) env('CLOSING_DATE', 13);
$nextMonthTimestamp = strtotime("first day of next month", strtotime("$year-$monthNumber-01"));
$closingDateNextMonth = date('Y-m-', $nextMonthTimestamp) . env('CLOSING_DATE');
// Mengambil nomor bulan sebagai integer
$monthNumber = (int) date('m', strtotime($month . ' 1'));
// Pastikan $year juga integer
$year = (int) $year;
$users = Admin::with(['region', 'cabang'])
->whereIn('id', $userIds)
->get();
// Carbon::createFromDate membutuhkan integer
$startDate = \Illuminate\Support\Carbon::createFromDate($year, $monthNumber, $startDay)->startOfDay();
// Input maksimal dan Closing menggunakan method ->day() yang butuh integer
$maxInputDate = $startDate->copy()->addMonth()->day($maxInputDay)->endOfDay();
$closingDate = $startDate->copy()->addMonth()->day($closingDay)->endOfDay();
$formUpCountryQuery = FormUpCountry::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Up Country' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Vehicle Running Cost' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Entertainment Presentation' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formMeetingSeminarQuery = FormMeetingSeminar::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Meeting Seminar' as type")
)->whereIn('user_id', $userIds)
->whereBetween('created_at', [$startDate, $closingDateNextMonth]);
$formOthersQuery = FormOthers::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Others' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
// Use union to combine queries
$forms = $formUpCountryQuery
->union($formVehicleRunningCostQuery)
->union($formEntertaimentPresentationQuery)
->union($formMeetingSeminarQuery)
->union($formOthersQuery)
->get();
// Return forms with eager loaded user details
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
public static function getAllForms($month, $year) {
$monthNumber = date('m', strtotime($month . ' 1'));
$startDate = "$year-$monthNumber-" . env('STARTING_DATE');
$nextMonthTimestamp = strtotime("first day of next month", strtotime("$year-$monthNumber-01"));
$closingDateNextMonth = date('Y-m-', $nextMonthTimestamp) . env('CLOSING_DATE');
$users = Admin::with(['region', 'cabang'])
->get();
$formUpCountryQuery = FormUpCountry::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Up Country' as type")
)->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Vehicle Running Cost' as type")
)->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Entertainment Presentation' as type")
)->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
$formMeetingSeminarQuery = FormMeetingSeminar::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Meeting Seminar' as type")
)->whereBetween('created_at', [$startDate, $closingDateNextMonth]);
$formOthersQuery = FormOthers::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Others' as type")
)->whereBetween('tanggal', [$startDate, $closingDateNextMonth]);
// Combine queries using union
$forms = $formUpCountryQuery
->union($formVehicleRunningCostQuery)
->union($formEntertaimentPresentationQuery)
->union($formMeetingSeminarQuery)
->union($formOthersQuery)
->get();
// Map users to the forms with eager loaded data
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
public static function getAllForms2() {
// Get all users with eager loading for 'region' and 'cabang'
$users = Admin::with(['region', 'cabang'])
->get();
$formUpCountryQuery = FormUpCountry::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Up Country' as type")
);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Vehicle Running Cost' as type")
);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Entertainment Presentation' as type")
);
$formMeetingSeminarQuery = FormMeetingSeminar::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Meeting Seminar' as type")
);
$formOthersQuery = FormOthers::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Others' as type")
);
// Combine queries using union
$forms = $formUpCountryQuery
->union($formVehicleRunningCostQuery)
->union($formEntertaimentPresentationQuery)
->union($formMeetingSeminarQuery)
->union($formOthersQuery)
->get();
// Map users to the forms with eager loaded data
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
public static function getNominalByFormType($cabang_id, $type, $type_id, $month, $year) {
$users = UserHasCabang::where('cabang_id', $cabang_id)->get();
$userIds = $users->pluck('user_id')->toArray();
if($type == 'Up Country') {
$form = FormUpCountry::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('tanggal', '=', date('m', strtotime($month)))->whereYear('tanggal', '=', $year)->where('status', ['Approved', 'Closed'])->get();
} else if($type == 'Vehicle Running Cost') {
$form = FormVehicleRunningCost::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('tanggal', '=', date('m', strtotime($month)))->whereYear('tanggal', '=', $year)->where('status', ['Approved', 'Closed'])->get();
} else if($type == 'Entertainment') {
$form = FormEntertaimentPresentation::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('tanggal', '=', date('m', strtotime($month)))->whereYear('tanggal', '=', $year)->where('status', ['Approved', 'Closed'])->get();
} else if($type == 'Meeting / Seminar') {
$form = FormMeetingSeminar::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('created_at', '=', date('m', strtotime($month)))->whereYear('created_at', '=', $year)->where('status', ['Approved', 'Closed'])->get();
} else {
$form = FormOthers::select('approved_total')->whereIn('user_id', $userIds)->whereMonth('tanggal', '=', date('m', strtotime($month)))->whereYear('tanggal', '=', $year)->where('kategori_id', $type_id)->where('status', ['Approved', 'Closed'])->get();
}
$nominal = $form->sum('approved_total');
return $nominal;
}
public static function getTotalAmount($userIds, $month, $year) {
$monthNumber = date('m', strtotime($month . ' 1'));
$startDate = "$year-$monthNumber-" . env('STARTING_DATE');
$nextMonthTimestamp = strtotime("first day of next month", strtotime("$year-$monthNumber-01"));
$closingDateNextMonth = date('Y-m-', $nextMonthTimestamp) . env('CLOSING_DATE');
$users = Admin::with(['region', 'cabang'])
->whereIn('id', $userIds)
->get();
$formUpCountryQuery = FormUpCountry::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Up Country' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Vehicle Running Cost' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Entertainment Presentation' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
$formMeetingSeminarQuery = FormMeetingSeminar::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Meeting Seminar' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
$formOthersQuery = FormOthers::select(
'expense_number',
'user_id',
'total',
'approved_total',
'status',
'account_number',
'created_at',
DB::raw("'Others' as type")
)->whereIn('user_id', $userIds)
->whereBetween('final_approved_at', [$startDate, $closingDateNextMonth]);
// Use union to combine queries
$forms = $formUpCountryQuery
->union($formVehicleRunningCostQuery)
->union($formEntertaimentPresentationQuery)
->union($formMeetingSeminarQuery)
->union($formOthersQuery)
->get();
// Return forms with eager loaded user details
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
return [
'start' => $startDate->toDateTimeString(),
'input_max' => $maxInputDate->toDateTimeString(),
'closing' => $closingDate->toDateTimeString(),
'display_label' => $startDate->format('d M') . ' - ' . $maxInputDate->format('d M Y')
];
}
public static function getFormsByUserIds($userIds, $month, $year) {
$dates = self::getCycleRange($month, $year);
$startDate = $dates['start'];
$closingDate = $dates['closing']; // Mengacu ke Closing Date (13)
$users = Admin::with(['region', 'cabang'])
->whereIn('id', $userIds)
->get();
$formUpCountryQuery = FormUpCountry::select(
'expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at',
DB::raw("'Up Country' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDate]);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select(
'expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at',
DB::raw("'Vehicle Running Cost' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDate]);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select(
'expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at',
DB::raw("'Entertainment Presentation' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDate]);
$formMeetingSeminarQuery = FormMeetingSeminar::select(
'expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at',
DB::raw("'Meeting Seminar' as type")
)->whereIn('user_id', $userIds)
->whereBetween('created_at', [$startDate, $closingDate]);
$formOthersQuery = FormOthers::select(
'expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at',
DB::raw("'Others' as type")
)->whereIn('user_id', $userIds)
->whereBetween('tanggal', [$startDate, $closingDate]);
$forms = $formUpCountryQuery
->union($formVehicleRunningCostQuery)
->union($formEntertaimentPresentationQuery)
->union($formMeetingSeminarQuery)
->union($formOthersQuery)
->get();
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
public static function getAllForms($month, $year) {
$dates = self::getCycleRange($month, $year);
$startDate = $dates['start'];
$closingDate = $dates['closing'];
$users = Admin::with(['region', 'cabang'])->get();
$commonSelect = ['expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at'];
$queries = [
FormUpCountry::select(array_merge($commonSelect, [DB::raw("'Up Country' as type")]))->whereBetween('tanggal', [$startDate, $closingDate]),
FormVehicleRunningCost::select(array_merge($commonSelect, [DB::raw("'Vehicle Running Cost' as type")]))->whereBetween('tanggal', [$startDate, $closingDate]),
FormEntertaimentPresentation::select(array_merge($commonSelect, [DB::raw("'Entertainment Presentation' as type")]))->whereBetween('tanggal', [$startDate, $closingDate]),
FormMeetingSeminar::select(array_merge($commonSelect, [DB::raw("'Meeting Seminar' as type")]))->whereBetween('created_at', [$startDate, $closingDate]),
FormOthers::select(array_merge($commonSelect, [DB::raw("'Others' as type")]))->whereBetween('tanggal', [$startDate, $closingDate]),
];
$mainQuery = array_shift($queries);
foreach ($queries as $q) { $mainQuery->union($q); }
$forms = $mainQuery->get();
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
/**
* Dashboard Info: Menghasilkan label periode input (11-10)
*/
public static function getDashboardPeriodLabel($month, $year) {
return self::getCycleRange($month, $year)['display_label'];
}
public static function getNominalByFormType($cabang_id, $type, $type_id, $month, $year) {
$users = UserHasCabang::where('cabang_id', $cabang_id)->get();
$userIds = $users->pluck('user_id')->toArray();
// Menggunakan logika cycle agar nominal yang muncul sinkron dengan cutoff
$dates = self::getCycleRange($month, $year);
$start = $dates['start'];
$end = $dates['closing'];
$query = null;
if($type == 'Up Country') {
$query = FormUpCountry::whereIn('user_id', $userIds)->whereBetween('tanggal', [$start, $end]);
} else if($type == 'Vehicle Running Cost') {
$query = FormVehicleRunningCost::whereIn('user_id', $userIds)->whereBetween('tanggal', [$start, $end]);
} else if($type == 'Entertainment') {
$query = FormEntertaimentPresentation::whereIn('user_id', $userIds)->whereBetween('tanggal', [$start, $end]);
} else if($type == 'Meeting / Seminar') {
$query = FormMeetingSeminar::whereIn('user_id', $userIds)->whereBetween('created_at', [$start, $end]);
} else {
$query = FormOthers::whereIn('user_id', $userIds)->whereBetween('tanggal', [$start, $end])->where('kategori_id', $type_id);
}
return $query->whereIn('status', ['Approved', 'Closed'])->sum('approved_total');
}
public static function getTotalAmount($userIds, $month, $year) {
$dates = self::getCycleRange($month, $year);
$startDate = $dates['start'];
$closingDate = $dates['closing'];
$users = Admin::with(['region', 'cabang'])->whereIn('id', $userIds)->get();
$formUpCountryQuery = FormUpCountry::select('expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at', DB::raw("'Up Country' as type"))
->whereIn('user_id', $userIds)->whereBetween('final_approved_at', [$startDate, $closingDate]);
$formVehicleRunningCostQuery = FormVehicleRunningCost::select('expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at', DB::raw("'Vehicle Running Cost' as type"))
->whereIn('user_id', $userIds)->whereBetween('final_approved_at', [$startDate, $closingDate]);
$formEntertaimentPresentationQuery = FormEntertaimentPresentation::select('expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at', DB::raw("'Entertainment Presentation' as type"))
->whereIn('user_id', $userIds)->whereBetween('final_approved_at', [$startDate, $closingDate]);
$formMeetingSeminarQuery = FormMeetingSeminar::select('expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at', DB::raw("'Meeting Seminar' as type"))
->whereIn('user_id', $userIds)->whereBetween('final_approved_at', [$startDate, $closingDate]);
$formOthersQuery = FormOthers::select('expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at', DB::raw("'Others' as type"))
->whereIn('user_id', $userIds)->whereBetween('final_approved_at', [$startDate, $closingDate]);
$forms = $formUpCountryQuery->union($formVehicleRunningCostQuery)->union($formEntertaimentPresentationQuery)->union($formMeetingSeminarQuery)->union($formOthersQuery)->get();
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
public static function getAllForms2() {
// Fungsi ini tetap dipertahankan sesuai request (tanpa filter tanggal)
$users = Admin::with(['region', 'cabang'])->get();
$commonSelect = ['expense_number', 'user_id', 'total', 'approved_total', 'status', 'account_number', 'created_at'];
$forms = FormUpCountry::select(array_merge($commonSelect, [DB::raw("'Up Country' as type")]))
->union(FormVehicleRunningCost::select(array_merge($commonSelect, [DB::raw("'Vehicle Running Cost' as type")])))
->union(FormEntertaimentPresentation::select(array_merge($commonSelect, [DB::raw("'Entertainment Presentation' as type")])))
->union(FormMeetingSeminar::select(array_merge($commonSelect, [DB::raw("'Meeting Seminar' as type")])))
->union(FormOthers::select(array_merge($commonSelect, [DB::raw("'Others' as type")])))
->get();
return $forms->map(function ($form) use ($users) {
$user = $users->firstWhere('id', $form->user_id);
$form->user = $user;
return $form;
});
}
}
+14 -10
View File
@@ -1,19 +1,23 @@
<?php
namespace App\Helpers;
use Illuminate\Support\Carbon;
class PeriodeHelper
{
public static function getPeriodeRange($month, $year)
{
$month = (int) date('m', strtotime($month));
$year = (int) $year;
/**
* Mendapatkan rentang tanggal fisik pengakuan untuk sebuah periode akuntansi (Bulan & Tahun)
* Contoh: Periode "april 2026" -> Start: 11 April 2026, End: 13 Mei 2026 (Closing Date)
*/
public static function getPeriodeRange(string $month, int $year): array
{
// 1. Tentukan tanggal 11 di bulan dan tahun yang dipilih
$startDate = Carbon::parse("11 $month $year")->startOfDay()->toDateTimeString();
// Jika Januari, periode dimulai dari 11 Januari hingga 10 Februari
$start = Carbon::create($year, $month, 11)->startOfDay();
$end = $start->copy()->addMonth()->subDay()->endOfDay();
// 2. Tentukan tanggal 13 di bulan berikutnya (Bulan berjalan + 1)
$endDate = Carbon::parse("13 $month $year")->addMonth()->endOfDay()->toDateTimeString();
return [$start, $end];
}
}
return [$startDate, $endDate];
}
}