Commit ac889b9d by Hannah Zahra

Fourth Update

parent 5961a3ce
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
@extends('ui::layouts.app') @extends('ui::layouts.app')
@push('style') @push('style')
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.9.3/semantic.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/semantic.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/components/calendar.min.css">
<style type="text/css"> <style type="text/css">
body { background-color: #f0f2f5; } body { background-color: #f0f2f5; }
...@@ -71,10 +72,29 @@ ...@@ -71,10 +72,29 @@
color: white; border-radius: 10px; color: white; border-radius: 10px;
padding: 10px 20px; font-weight: 600; padding: 10px 20px; font-weight: 600;
} }
.ui.calendar .disabled.day {
color: #ccc !important;
text-decoration: line-through;
}
</style> </style>
@endpush @endpush
@section('content') @section('content')
@if (session('error'))
<div class="ui negative message">
<i class="close icon"></i>
<div class="header">{{ session('error') }}</div>
</div>
@endif
@if (session('success'))
<div class="ui positive message">
<i class="close icon"></i>
<div class="header">{{ session('success') }}</div>
</div>
@endif
<div class="ui container"> <div class="ui container">
<div class="ui segments"> <div class="ui segments">
<div class="ui segment"> <div class="ui segment">
...@@ -179,9 +199,10 @@ ...@@ -179,9 +199,10 @@
<small>(Jumlah keseluruhan sebenar akan dikira di Senarai Tuntutan)</small> <small>(Jumlah keseluruhan sebenar akan dikira di Senarai Tuntutan)</small>
</td> </td>
<td> <td>
<strong id="total_claim">RM 0.00</strong> <strong id="total_claim_amount">RM 0.00</strong>
</td> </td>
</tr> </tbody> </tr>
</tbody>
</table> </table>
</div> </div>
</div> </div>
...@@ -199,11 +220,49 @@ ...@@ -199,11 +220,49 @@
@push('script') @push('script')
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.9.3/semantic.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/semantic.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/components/calendar.min.js"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
// --- Modal on load ---
// === Auto Calculation for Ringkasan Pengiraan ===
function updateSummary() {
const totalMileage = parseFloat($('#total_mileage').val()) || 0;
const toll = parseFloat($('#toll_amount').val()) || 0;
const others = parseFloat($('#others_amount').val()) || 0;
// Apply 40km daily deduction rule
let claimableMileage = 0;
if (totalMileage > 40) {
claimableMileage = totalMileage - 40;
}
// Mileage rate logic (RM0.55/km up to 500km, RM0.50 after that)
let rate = 0.55;
if (claimableMileage > 500) rate = 0.50;
// Total mileage claim
const mileageAmount = claimableMileage * rate;
// Total claim = mileage + toll + others
const totalClaim = mileageAmount + toll + others;
// Update display fields
$('#claimable_mileage_formula').text(`${totalMileage} - 40 = ${claimableMileage} KM`);
$('#toll_claim').text(`RM ${toll.toFixed(2)}`);
$('#others_claim').text(`RM ${others.toFixed(2)}`);
$('#total_claim_amount').text(`RM ${totalClaim.toFixed(2)}`);
// Store hidden claimable mileage input
$('#claimable_mileage_input').val(claimableMileage);
}
// Watch for input changes
$('#total_mileage, #toll_amount, #others_amount').on('input', updateSummary);
updateSummary(); // run once on page load
// === Modal Setup ===
const modalHtml = ` const modalHtml = `
<div class="ui basic modal" id="supportingDocsModal"> <div class="ui basic modal" id="supportingDocsModal">
<div class="ui icon header"> <div class="ui icon header">
...@@ -215,131 +274,50 @@ ...@@ -215,131 +274,50 @@
Jika <b>tidak</b>, tuntutan akan <b>DITOLAK</b>.</p> Jika <b>tidak</b>, tuntutan akan <b>DITOLAK</b>.</p>
</div> </div>
<div class="actions" style="text-align:center;"> <div class="actions" style="text-align:center;">
<div class="ui green ok inverted button"><i class="checkmark icon"></i> Saya Faham</div> <div class="ui green ok inverted button">
<i class="checkmark icon"></i> Saya Faham
</div>
</div> </div>
</div>`; </div>`;
$('body').append(modalHtml); $('body').append(modalHtml);
// Disable form until user clicks "Saya Faham"
$('#claimForm :input').prop('disabled', true); $('#claimForm :input').prop('disabled', true);
// Show modal
$('#supportingDocsModal').modal({ $('#supportingDocsModal').modal({
closable: false, closable: false,
onApprove: function() { onApprove: function() {
$('#claimForm :input').prop('disabled', false); $('#claimForm :input').prop('disabled', false);
$('.ui.dropdown').dropdown(); $('.ui.dropdown').dropdown();
$('#claim_date').calendar({
type: 'date', // Wait for modal to close before initializing calendar
maxDate: new Date(), setTimeout(() => {
formatter: { console.log('🟢 Initializing Fomantic calendar...');
date: function(date) { $('#claim_date').calendar({
if (!date) return ''; type: 'date',
let d = date.getDate(); startMode: 'day',
let m = date.getMonth() + 1; touchReadonly: true,
let y = date.getFullYear(); monthFirst: false,
return `${y}-${m<10?'0':''}${m}-${d<10?'0':''}${d}`; maxDate: new Date(),
disabledDates: [],
formatter: {
date: function(date) {
if (!date) return '';
const y = date.getFullYear();
const m = ('0' + (date.getMonth() + 1)).slice(-2);
const d = ('0' + date.getDate()).slice(-2);
return `${y}-${m}-${d}`;
}
},
onChange: function(date, text) {
console.log('📅 Date selected:', text);
} }
} });
}); }, 400);
} }
}).modal('show'); }).modal('show');
// --- Calculation ---
function calculateTotals() {
const mileage = parseFloat($('#total_mileage').val()) || 0;
const claimable = Math.max(0, mileage - 40);
const toll = parseFloat($('#toll_amount').val()) || 0;
const others = parseFloat($('#others_amount').val()) || 0;
const total = toll + others;
$('#claimable_mileage_formula').text(`${mileage.toFixed(2)} - 40 = ${claimable.toFixed(2)} KM`);
$('#toll_claim').text(`RM ${toll.toFixed(2)}`);
$('#others_claim').text(`RM ${others.toFixed(2)}`);
$('#total_claim').text(`RM ${total.toFixed(2)}`);
$('#claimable_mileage_input').val(claimable.toFixed(2));
}
$('#total_mileage, #toll_amount, #others_amount').on('input', function() {
calculateTotals();
const othersVal = parseFloat($('#others_amount').val()) || 0;
if (othersVal > 0) {
$('#others_description_wrapper').slideDown();
$('#others_description').prop('required', true);
} else {
$('#others_description_wrapper').slideUp();
$('#others_description').prop('required', false).val('');
}
});
// --- summary Modal ---
$('#claimForm').on('submit', function(e) {
e.preventDefault();
// ✅ Project validation check
const projectId = $('#project_id').val();
if (!projectId || projectId === "") {
$('body').toast({
class: 'error',
message: 'Sila pilih projek sebelum menghantar tuntutan.',
showProgress: 'bottom'
});
$('#project_id').closest('.field').addClass('error');
return false;
} else {
$('#project_id').closest('.field').removeClass('error');
}
const project = $('#project_id option:selected').text();
const claimDate = $('#date').val();
const vehicle = $('#jenis_kenderaan_id option:selected').text();
const desc = $('input[name="description"]').val();
const from = $('select[name="distance_from"] option:selected').text();
const to = $('input[name="distance_to"]').val();
const mileage = $('#total_mileage').val();
const claimable = $('#claimable_mileage_input').val();
const toll = $('#toll_amount').val() || 0;
const others = $('#others_amount').val() || 0;
const othersDesc = $('#others_description').val() || '-';
// Remove previous modal if any
$('#claimSummaryModal').remove();
const summaryModal = `
<div class="ui modal" id="claimSummaryModal">
<div class="header">Ringkasan Tuntutan Anda</div>
<div class="content">
<p><strong>Tarikh:</strong> ${claimDate}</p>
<p><strong>Jenis Kenderaan:</strong> ${vehicle}</p>
<p><strong>Nama Projek:</strong> ${project}</p>
<p><strong>Butiran:</strong> ${desc}</p>
<p><strong>Dari:</strong> ${from}</p>
<p><strong>Ke:</strong> ${to}</p>
<p><strong>Jumlah Perbatuan:</strong> ${mileage} KM</p>
<p><strong>Layak Dituntut:</strong> ${mileage} - 40 = ${claimable} KM</p>
<p><strong>Toll:</strong> RM ${parseFloat(toll).toFixed(2)}</p>
<p><strong>Lain-lain:</strong> RM ${parseFloat(others).toFixed(2)}</p>
<p><strong>Butiran Lain-lain:</strong> ${othersDesc}</p>
</div>
<div class="actions">
<div class="ui grey button" id="editClaim"><i class="arrow left icon"></i> Edit</div>
<div class="ui green approve button"><i class="check icon"></i> Hantar</div>
</div>
</div>`;
$('body').append(summaryModal);
$('#claimSummaryModal').modal({
closable: false,
onApprove: function() {
$('#claimForm')[0].submit();
return false;
}
}).modal('show');
$(document).off('click', '#editClaim').on('click', '#editClaim', function() {
$('#claimSummaryModal').modal('hide');
});
});
}); });
</script> </script>
@endpush @endpush
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
@extends('ui::layouts.app') @extends('ui::layouts.app')
@push('style') @push('style')
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.9.3/semantic.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/semantic.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/components/calendar.min.css">
<style type="text/css"> <style type="text/css">
body { background-color: #f0f2f5; } body { background-color: #f0f2f5; }
...@@ -71,10 +72,28 @@ ...@@ -71,10 +72,28 @@
color: white; border-radius: 10px; color: white; border-radius: 10px;
padding: 10px 20px; font-weight: 600; padding: 10px 20px; font-weight: 600;
} }
.ui.calendar .disabled.day {
color: #ccc !important;
text-decoration: line-through;
}
</style> </style>
@endpush @endpush
@section('content') @section('content')
@if (session('error'))
<div class="ui negative message">
<i class="close icon"></i>
<div class="header">{{ session('error') }}</div>
</div>
@endif
@if (session('success'))
<div class="ui positive message">
<i class="close icon"></i>
<div class="header">{{ session('success') }}</div>
</div>
@endif
<div class="ui container"> <div class="ui container">
<div class="ui segments"> <div class="ui segments">
<div class="ui segment"> <div class="ui segment">
...@@ -90,6 +109,7 @@ ...@@ -90,6 +109,7 @@
<p><strong>Maklumat Tuntutan</strong></p> <p><strong>Maklumat Tuntutan</strong></p>
<div class="ui segment"> <div class="ui segment">
<div class="ui form"> <div class="ui form">
<div class="inline field required"> <div class="inline field required">
<label class="three-wide field">Tarikh</label> <label class="three-wide field">Tarikh</label>
<div class="eight wide field ui calendar" id="claim_date"> <div class="eight wide field ui calendar" id="claim_date">
...@@ -111,13 +131,13 @@ ...@@ -111,13 +131,13 @@
</div> </div>
<div class="inline field required"> <div class="inline field required">
<label class="three-wide field">Butiran Tuntutan</label> <label class="three-wide field">Butiran</label>
<input class="eight wide field" name="description" type="text" placeholder="Cth: Mesyuarat Dalaman" required> <input class="eight wide field" name="description" type="text" placeholder="Cth: Mesyuarat Dalaman" required>
</div> </div>
<div class="inline field required"> <div class="inline field required">
<label class="three-wide field">Jarak Dari</label> <label class="three-wide field">Jarak Dari</label>
<select class="ui search dropdown eight wide field" name="distance_from"> <select class="ui search dropdown eight wide field" name="distance_from" required>
<option value="">Sila Pilih Lokasi</option> <option value="">Sila Pilih Lokasi</option>
<option value="Pejabat">Pejabat</option> <option value="Pejabat">Pejabat</option>
</select> </select>
...@@ -166,7 +186,7 @@ ...@@ -166,7 +186,7 @@
<small>(Jumlah keseluruhan sebenar akan dikira di Senarai Tuntutan)</small> <small>(Jumlah keseluruhan sebenar akan dikira di Senarai Tuntutan)</small>
</td> </td>
<td> <td>
<strong id="total_claim">RM 0.00</strong> <strong id="total_claim_amount">RM 0.00</strong>
</td> </td>
</tr> </tr>
</tbody> </tbody>
...@@ -187,11 +207,38 @@ ...@@ -187,11 +207,38 @@
@push('script') @push('script')
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.9.3/semantic.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/semantic.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/components/calendar.min.js"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
// --- Warning Modal on load ---
// === Auto Calculation for Ringkasan Pengiraan ===
function updateSummary() {
const totalMileage = parseFloat($('#total_mileage').val()) || 0;
const toll = parseFloat($('#toll_amount').val()) || 0;
const others = parseFloat($('#others_amount').val()) || 0;
let claimableMileage = 0;
if (totalMileage > 40) claimableMileage = totalMileage - 40;
let rate = 0.55;
if (claimableMileage > 500) rate = 0.50;
const mileageAmount = claimableMileage * rate;
const totalClaim = mileageAmount + toll + others;
$('#claimable_mileage_formula').text(`${totalMileage} - 40 = ${claimableMileage} KM`);
$('#toll_claim').text(`RM ${toll.toFixed(2)}`);
$('#others_claim').text(`RM ${others.toFixed(2)}`);
$('#total_claim_amount').text(`RM ${totalClaim.toFixed(2)}`);
$('#claimable_mileage_input').val(claimableMileage);
}
$('#total_mileage, #toll_amount, #others_amount').on('input', updateSummary);
updateSummary();
// === Modal Setup ===
const modalHtml = ` const modalHtml = `
<div class="ui basic modal" id="supportingDocsModal"> <div class="ui basic modal" id="supportingDocsModal">
<div class="ui icon header"> <div class="ui icon header">
...@@ -199,10 +246,8 @@ ...@@ -199,10 +246,8 @@
Peringatan Penting Peringatan Penting
</div> </div>
<div class="content" style="text-align:center;"> <div class="content" style="text-align:center;">
<p style="font-size:16px; line-height:1.5;"> <p>Dokumen sokongan seperti resit mesti dihantar kepada pihak Finance.<br>
Dokumen sokongan seperti resit mesti dihantar kepada pihak Finance sebagai bukti.<br> Jika <b>tidak</b>, tuntutan akan <b>DITOLAK</b>.</p>
Jika <b>tidak</b>, tuntutan akan <b>DITOLAK</b>.
</p>
</div> </div>
<div class="actions" style="text-align:center;"> <div class="actions" style="text-align:center;">
<div class="ui green ok inverted button"> <div class="ui green ok inverted button">
...@@ -212,7 +257,6 @@ ...@@ -212,7 +257,6 @@
</div>`; </div>`;
$('body').append(modalHtml); $('body').append(modalHtml);
// Disable inputs until user acknowledges
$('#claimForm :input').prop('disabled', true); $('#claimForm :input').prop('disabled', true);
$('#supportingDocsModal').modal({ $('#supportingDocsModal').modal({
...@@ -220,103 +264,29 @@ ...@@ -220,103 +264,29 @@
onApprove: function() { onApprove: function() {
$('#claimForm :input').prop('disabled', false); $('#claimForm :input').prop('disabled', false);
$('.ui.dropdown').dropdown(); $('.ui.dropdown').dropdown();
$('#claim_date').calendar({
type: 'date', setTimeout(() => {
maxDate: new Date(), $('#claim_date').calendar({
formatter: { type: 'date',
date: function(date) { startMode: 'day',
if (!date) return ''; touchReadonly: true,
let d = date.getDate(); monthFirst: false,
let m = date.getMonth() + 1; maxDate: new Date(),
let y = date.getFullYear(); disabledDates: [],
return `${y}-${m<10?'0':''}${m}-${d<10?'0':''}${d}`; formatter: {
date: function(date) {
if (!date) return '';
const y = date.getFullYear();
const m = ('0' + (date.getMonth() + 1)).slice(-2);
const d = ('0' + date.getDate()).slice(-2);
return `${y}-${m}-${d}`;
}
} }
} });
}); }, 400);
} }
}).modal('show'); }).modal('show');
// --- Calculation ---
function calculateTotals() {
const mileage = parseFloat($('#total_mileage').val()) || 0;
const claimable = Math.max(0, mileage - 40);
const toll = parseFloat($('#toll_amount').val()) || 0;
const others = parseFloat($('#others_amount').val()) || 0;
const total = toll + others;
$('#claimable_mileage_formula').text(`${mileage.toFixed(2)} - 40 = ${claimable.toFixed(2)} KM`);
$('#toll_claim').text(`RM ${toll.toFixed(2)}`);
$('#others_claim').text(`RM ${others.toFixed(2)}`);
$('#total_claim').text(`RM ${total.toFixed(2)}`);
$('#claimable_mileage_input').val(claimable.toFixed(2));
}
$('#total_mileage, #toll_amount, #others_amount').on('input', function() {
calculateTotals();
const othersVal = parseFloat($('#others_amount').val()) || 0;
if (othersVal > 0) {
$('#others_description_wrapper').slideDown();
$('#others_description').prop('required', true);
} else {
$('#others_description_wrapper').slideUp();
$('#others_description').prop('required', false).val('');
}
});
// --- Summary Modal ---
$('#claimForm').on('submit', function(e) {
e.preventDefault();
const claimDate = $('#date').val();
const vehicle = $('#jenis_kenderaan_id option:selected').text();
const desc = $('input[name="description"]').val();
const from = $('select[name="distance_from"] option:selected').text();
const to = $('input[name="distance_to"]').val();
const mileage = $('#total_mileage').val();
const claimable = $('#claimable_mileage_input').val();
const toll = $('#toll_amount').val() || 0;
const others = $('#others_amount').val() || 0;
const othersDesc = $('#others_description').val() || '-';
const subtotal = $('#total_claim').text() || '-';
$('#claimSummaryModal').remove();
const summaryModal = `
<div class="ui modal" id="claimSummaryModal">
<div class="header">Ringkasan Tuntutan Anda</div>
<div class="content">
<p><strong>Tarikh:</strong> ${claimDate}</p>
<p><strong>Jenis Kenderaan:</strong> ${vehicle}</p>
<p><strong>Butiran:</strong> ${desc}</p>
<p><strong>Dari:</strong> ${from}</p>
<p><strong>Ke:</strong> ${to}</p>
<p><strong>Jumlah Perbatuan:</strong> ${mileage} KM</p>
<p><strong>Layak Dituntut:</strong> ${mileage} - 40 = ${claimable} KM</p>
<p><strong>Toll:</strong> RM ${parseFloat(toll).toFixed(2)}</p>
<p><strong>Lain-lain:</strong> RM ${parseFloat(others).toFixed(2)}</p>
<p><strong>Butiran Lain-lain:</strong> ${othersDesc}</p>
<p><strong>Jumlah Tol dan Lain-lain (Jumlah Keseluruhan akan Dikira di Senarai Tuntutan):</strong> ${subtotal}</p>
</div>
<div class="actions">
<div class="ui grey button" id="editClaim"><i class="arrow left icon"></i> Edit</div>
<div class="ui green approve button"><i class="check icon"></i> Hantar</div>
</div>
</div>`;
$('body').append(summaryModal);
$('#claimSummaryModal').modal({
closable: false,
onApprove: function() {
$('#claimForm')[0].submit();
return false;
}
}).modal('show');
$(document).off('click', '#editClaim').on('click', '#editClaim', function() {
$('#claimSummaryModal').modal('hide');
});
});
}); });
</script> </script>
@endpush @endpush
...@@ -138,6 +138,7 @@ ...@@ -138,6 +138,7 @@
<br> <br>
@else @else
<div class="ui message">Tiada tuntutan untuk projek ini bulan ini.</div> <div class="ui message">Tiada tuntutan untuk projek ini bulan ini.</div>
<br>
@endif @endif
</div> </div>
@empty @empty
......
...@@ -21,8 +21,8 @@ function () { ...@@ -21,8 +21,8 @@ function () {
Route::prefix('applyform')->name('applyform')->group(function () { Route::prefix('applyform')->name('applyform')->group(function () {
Route::get('/', [ApplyformController::class, 'index'])->name('.index'); Route::get('/', [ApplyformController::class, 'index'])->name('.index');
Route::get('/noproject', [ApplyformController::class, 'noproject'])->name('.noproject'); Route::get('/noproject', [ApplyformController::class, 'noproject'])->name('.noproject');
Route::get('/applyform/getDates', [ApplyformController::class, 'getDates'])->name('.getDates');
}); });
// Route::resource('applyform', ApplyformController::class); // Route::resource('applyform', ApplyformController::class);
// Applications // Applications
...@@ -32,8 +32,6 @@ function () { ...@@ -32,8 +32,6 @@ function () {
Route::get('applications/view/claim/{id}', [ApplicationsController::class, 'viewEach'])->name('applications.viewEach'); Route::get('applications/view/claim/{id}', [ApplicationsController::class, 'viewEach'])->name('applications.viewEach');
Route::put('applications/{id}', [ApplicationsController::class, 'update']) Route::put('applications/{id}', [ApplicationsController::class, 'update'])
->name('applications.update'); ->name('applications.update');
Route::get('/applications/dates', [\Portal\Mileage\Http\Controllers\ApplicationsController::class, 'getClaimDates'])
->name('mileage::applications.getDates');
// Project Manager // Project Manager
Route::prefix('projectManager')->name('projectManager')->group(function () { Route::prefix('projectManager')->name('projectManager')->group(function () {
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
use Illuminate\Routing\Controller; use Illuminate\Routing\Controller;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Carbon\Carbon; use Carbon\Carbon;
...@@ -68,53 +69,29 @@ public function index(Request $request) ...@@ -68,53 +69,29 @@ public function index(Request $request)
public function store(Request $request) public function store(Request $request)
{ {
// Validate request data // your existing store logic
$validated = $request->validate([ $calculation = $this->calculateClaimAmount($request);
'claim_date' => 'required|date',
'jenis_kenderaan_id' => 'required|exists:lkp_jenis_kenderaans,id',
'project_id' => 'nullable|exists:lkp_project,id',
'description' => 'required',
'distance_from' => 'nullable',
'distance_to' => 'nullable',
'total_mileage' => 'required|numeric',
'toll_amount' => 'nullable|numeric',
'others_amount' => 'nullable|numeric',
'others_description' => 'nullable|string|max:255',
]);
$validated['user_id'] = auth()->id(); // Get the current authenticated user
// Calculate the total claim amount and mileage
$calculatedAmount = $this->calculateClaimAmount($validated);
$validated['calculated_amount'] = $calculatedAmount;
// Handle the status based on actions (e.g., project manager, director, finance)
$validated['status'] = 'Diproses'; // Initial status
// Store the claim in the database
$claim = Claim::create($validated);
// Now, we need to manage the role and verify the project
// Example: If project_id is set, link the claim with the project and handle roles
if ($claim->project) {
$project = $claim->project;
// Here, you can check if the claim should be verified by a Project Manager (HOD)
// For now, we’re assuming you use the role directly to set verified_by
if ($project->project_manager_id) {
$claim->verified_by = $project->project_manager_id;
}
// Similarly, you can handle who approves and reviews (e.g., Project Director or BOD)
if ($project->project_director_id) {
$claim->approved_by = $project->project_director_id;
}
$claim->save(); Claim::create([
} 'user_id' => Auth::id(),
'project_id' => $request->project_id,
'claim_date' => $request->claim_date,
'jenis_kenderaan_id' => $request->jenis_kenderaan_id,
'description' => $request->description,
'distance_from' => $request->distance_from,
'distance_to' => $request->distance_to,
'total_mileage' => $request->total_mileage,
'toll_amount' => $request->toll_amount ?? 0,
'others_amount' => $request->others_amount ?? 0,
'claimable_mileage' => $calculation['claimable_mileage'],
'rate' => $calculation['rate'],
'mileage_amount' => $calculation['mileage_amount'],
'total_claim_amount' => $calculation['total_claim'],
'status' => 'Diproses',
]);
return redirect()->route('mileage::applications.index')->with('success', 'Claim submitted successfully!'); return redirect()->route('mileage::applications.index')
->with('success', 'Tuntutan berjaya dihantar!');
} }
public function edit($id) public function edit($id)
...@@ -265,5 +242,26 @@ public function updateStatus(Request $request, $id) ...@@ -265,5 +242,26 @@ public function updateStatus(Request $request, $id)
return back()->with('success', 'Claim status updated to ' . $claim->status); return back()->with('success', 'Claim status updated to ' . $claim->status);
} }
private function calculateClaimAmount($request)
{
$totalMileage = (float) $request->total_mileage;
$toll = (float) $request->toll_amount;
$others = (float) $request->others_amount;
// Deduct first 40km
$claimableMileage = $totalMileage > 40 ? $totalMileage - 40 : 0;
// Apply rate logic
$rate = $claimableMileage > 500 ? 0.50 : 0.55;
$mileageAmount = $claimableMileage * $rate;
$totalClaim = $mileageAmount + $toll + $others;
return [
'claimable_mileage' => $claimableMileage,
'rate' => $rate,
'mileage_amount' => $mileageAmount,
'total_claim' => $totalClaim,
];
}
} }
...@@ -130,4 +130,15 @@ public function noproject() ...@@ -130,4 +130,15 @@ public function noproject()
return view('mileage::applyform.noproject', compact('jenisKenderaan')); return view('mileage::applyform.noproject', compact('jenisKenderaan'));
} }
public function getDates()
{
$userId = auth()->id();
$dates = Claim::where('user_id', $userId)
->pluck('claim_date') // get all submitted dates
->map(fn($d) => \Carbon\Carbon::parse($d)->format('Y-m-d')); // format to yyyy-mm-dd
return response()->json($dates);
}
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
class AclRole extends Model class AclRole extends Model
{ {
protected $table = 'acl_roles'; // ⚠️ must be your roles definition table protected $table = 'acl_roles'; // must be your roles definition table
protected $primaryKey = 'id'; protected $primaryKey = 'id';
public $timestamps = false; public $timestamps = false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment