3361 lines
151 KiB
PHP
Executable File
3361 lines
151 KiB
PHP
Executable File
@extends('layouts.frontapp')
|
|
|
|
@php
|
|
use App\Models\Dealer;
|
|
use Illuminate\Support\Facades\Auth;
|
|
@endphp
|
|
|
|
{{-- @section('contentHead')
|
|
<div class="kt-subheader kt-grid__item" id="kt_subheader">
|
|
<div class="kt-container kt-container--fluid ">
|
|
<div class="kt-subheader__main">
|
|
<h3 class="kt-subheader__title"> Transaksi </h3>
|
|
</div>
|
|
<div class="kt-subheader__toolbar" style="width: 1000px;">
|
|
<a href="{{ route('transaction.create') }}" id="addBtn" class="btn btn-label-success btn-bold" data-url="" data-redirect="">Tambah Transaksi</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection --}}
|
|
|
|
@section('styles')
|
|
<style>
|
|
button.disabled {
|
|
cursor: not-allowed !important;
|
|
pointer-events: none;
|
|
}
|
|
.table-responsive {
|
|
max-height: 100%;
|
|
overflow-y: auto;
|
|
}
|
|
.text-success {
|
|
color: #28a745 !important;
|
|
}
|
|
.text-danger {
|
|
color: #dc3545 !important;
|
|
}
|
|
.text-bold {
|
|
font-weight: bold;
|
|
}
|
|
.system-stock {
|
|
font-weight: 600;
|
|
color: #007bff;
|
|
}
|
|
.table-bordered th,
|
|
.table-bordered td {
|
|
border: 1px solid #dee2e6;
|
|
vertical-align: middle;
|
|
padding: 12px 8px;
|
|
}
|
|
.table thead th {
|
|
background-color: #f8f9fa;
|
|
color: #495057;
|
|
font-weight: 600;
|
|
font-size: 14px;
|
|
border-bottom: 2px solid #dee2e6;
|
|
}
|
|
.table-striped tbody tr:nth-of-type(odd) {
|
|
background-color: rgba(0,0,0,.02);
|
|
}
|
|
.physical-stock {
|
|
font-weight: 500;
|
|
border: 2px solid #e9ecef;
|
|
transition: border-color 0.15s ease-in-out;
|
|
}
|
|
.physical-stock:focus {
|
|
border-color: #ffc107;
|
|
box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.25);
|
|
}
|
|
.difference {
|
|
font-size: 14px;
|
|
padding: 4px 8px;
|
|
border-radius: 4px;
|
|
background-color: #f8f9fa;
|
|
display: inline-block;
|
|
min-width: 60px;
|
|
}
|
|
.btn-lg {
|
|
padding: 12px 20px;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.5px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
|
transition: all 0.3s ease;
|
|
}
|
|
.btn-lg:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
|
|
}
|
|
|
|
.quantity-input-mutasi.is-invalid {
|
|
border-color: #dc3545;
|
|
background-color: #fff5f5;
|
|
}
|
|
.quantity-input-mutasi.is-invalid:focus {
|
|
border-color: #dc3545;
|
|
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
|
|
}
|
|
.available-stock-mutasi {
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* Styles for receive mutations table */
|
|
#receiveMutationsTable {
|
|
font-size: 14px;
|
|
}
|
|
|
|
#receiveMutationsTable th {
|
|
background-color: #f8f9fa;
|
|
font-weight: 600;
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
#receiveMutationsTable td {
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.btn-detail {
|
|
font-size: 12px;
|
|
padding: 4px 8px;
|
|
}
|
|
|
|
.status-badge {
|
|
font-size: 11px;
|
|
padding: 4px 8px;
|
|
border-radius: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.mutation-detail-table {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.mutation-detail-table th {
|
|
background-color: #f8f9fa;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.quantity-approved-input {
|
|
text-align: center;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.quantity-approved-input.is-invalid {
|
|
border-color: #dc3545;
|
|
background-color: #fff5f5;
|
|
}
|
|
|
|
.mutation-detail-table textarea {
|
|
font-size: 12px;
|
|
resize: vertical;
|
|
}
|
|
|
|
.mutation-detail-table input {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.bg-warning-light {
|
|
background-color: #fff3cd !important;
|
|
border: 1px solid #ffeaa7;
|
|
}
|
|
|
|
.form-control-plaintext.border {
|
|
background-color: #f8f9fa;
|
|
font-style: normal;
|
|
}
|
|
|
|
.alert ul {
|
|
padding-left: 1.2rem;
|
|
}
|
|
|
|
.alert ul li {
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
/* Select2 styling for mutasi form */
|
|
.select2-container {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.select2-container--default .select2-selection--single {
|
|
height: 38px;
|
|
border: 1px solid #e2e5ec;
|
|
border-radius: 4px;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0;
|
|
}
|
|
|
|
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
|
line-height: 36px;
|
|
padding-left: 12px;
|
|
padding-right: 30px;
|
|
color: #74788d;
|
|
display: block;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
max-width: calc(100% - 30px);
|
|
}
|
|
|
|
.select2-container--default .select2-selection--single .select2-selection__placeholder {
|
|
color: #74788d;
|
|
line-height: 36px;
|
|
}
|
|
|
|
.select2-container--default .select2-selection--single .select2-selection__arrow {
|
|
height: 36px;
|
|
right: 8px;
|
|
top: 1px;
|
|
width: 20px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.select2-container--default .select2-selection--single .select2-selection__arrow b {
|
|
border-color: #74788d transparent transparent transparent;
|
|
border-style: solid;
|
|
border-width: 5px 4px 0 4px;
|
|
height: 0;
|
|
left: 50%;
|
|
margin-left: -4px;
|
|
margin-top: -2px;
|
|
position: absolute;
|
|
top: 50%;
|
|
width: 0;
|
|
}
|
|
|
|
/* Hide clear button completely */
|
|
.select2-container--default .select2-selection--single .select2-selection__clear {
|
|
display: none !important;
|
|
}
|
|
|
|
.select2-dropdown {
|
|
border: 1px solid #e2e5ec;
|
|
border-radius: 4px;
|
|
z-index: 9999 !important;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
}
|
|
|
|
.select2-results__option {
|
|
padding: 8px 12px;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.select2-results__option--highlighted {
|
|
background-color: #5d78ff;
|
|
color: white;
|
|
}
|
|
|
|
.select2-container--default.select2-container--focus .select2-selection--single {
|
|
border-color: #5d78ff;
|
|
outline: 0;
|
|
box-shadow: 0 0 0 0.2rem rgba(93, 120, 255, 0.25);
|
|
}
|
|
|
|
/* Select2 for table cells - adjust width */
|
|
#products-table-mutasi .select2-container {
|
|
width: 100% !important;
|
|
max-width: 100%;
|
|
}
|
|
|
|
/* Style for placeholder options */
|
|
select option[disabled] {
|
|
color: #6c757d;
|
|
font-style: italic;
|
|
background-color: #f8f9fa;
|
|
}
|
|
|
|
/* Prevent auto-selection of first option */
|
|
select:focus option:first-child {
|
|
background-color: #f8f9fa;
|
|
}
|
|
|
|
/* Required field styling */
|
|
.form-control[required]:not(:placeholder-shown):valid {
|
|
border-color: #28a745;
|
|
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);
|
|
}
|
|
|
|
.form-control[required]:not(:placeholder-shown):invalid {
|
|
border-color: #dc3545;
|
|
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
|
|
}
|
|
|
|
/* Required field indicator */
|
|
.form-control[required]::placeholder {
|
|
color: #6c757d;
|
|
}
|
|
|
|
/* Service Advisor required styling */
|
|
select[name="user_sa_id"][required] option:first-child {
|
|
color: #6c757d;
|
|
font-style: italic;
|
|
}
|
|
|
|
/* Required field labels */
|
|
.form-group label:after {
|
|
content: " *";
|
|
color: #dc3545;
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* Required field focus styling */
|
|
.form-control[required]:focus {
|
|
border-color: #5d78ff;
|
|
box-shadow: 0 0 0 0.2rem rgba(93, 120, 255, 0.25);
|
|
}
|
|
|
|
/* Invalid field styling */
|
|
.form-control.is-invalid {
|
|
border-color: #dc3545;
|
|
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
|
|
}
|
|
|
|
/* Valid field styling */
|
|
.form-control.is-valid {
|
|
border-color: #28a745;
|
|
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);
|
|
}
|
|
|
|
/* Claim tab specific styling */
|
|
#claimTransactionsTable {
|
|
font-size: 14px;
|
|
}
|
|
|
|
#claimTransactionsTable th {
|
|
background-color: #f8f9fa;
|
|
font-weight: 600;
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
border: 1px solid #dee2e6;
|
|
}
|
|
|
|
#claimTransactionsTable td {
|
|
vertical-align: middle;
|
|
border: 1px solid #dee2e6;
|
|
}
|
|
|
|
#claimTransactionsTable .btn {
|
|
font-size: 12px;
|
|
padding: 4px 8px;
|
|
margin: 1px;
|
|
}
|
|
|
|
/* Status badge styling for claim table */
|
|
#claimTransactionsTable .badge {
|
|
font-size: 11px;
|
|
padding: 4px 8px;
|
|
border-radius: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* Tab claim specific styling */
|
|
#form-claim {
|
|
background-color: #fff;
|
|
padding: 20px;
|
|
border: 1px solid #dee2e6;
|
|
border-top: none;
|
|
border-radius: 0 0 5px 5px;
|
|
}
|
|
|
|
#form-claim h6 {
|
|
color: #495057;
|
|
font-weight: 600;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
/* Stock tab specific styling - simplified */
|
|
|
|
/* Ensure stock sub-tabs are visible */
|
|
#stock .nav-tabs {
|
|
display: flex;
|
|
border-bottom: 1px solid #dee2e6;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
#stock .nav-tabs .nav-link {
|
|
padding: 0.5rem 1rem;
|
|
border: 1px solid transparent;
|
|
border-radius: 0.25rem 0.25rem 0 0;
|
|
text-decoration: none;
|
|
color: #495057;
|
|
cursor: pointer;
|
|
}
|
|
|
|
#stock .nav-tabs .nav-link.active {
|
|
color: #495057;
|
|
background-color: #fff;
|
|
border-color: #dee2e6 #dee2e6 #fff;
|
|
}
|
|
|
|
/* Ensure transaksi sub-tabs have the same styling */
|
|
#transaksi .nav-tabs {
|
|
display: flex;
|
|
border-bottom: 1px solid #dee2e6;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
#transaksi .nav-tabs .nav-link {
|
|
padding: 0.5rem 1rem;
|
|
border: 1px solid transparent;
|
|
border-radius: 0.25rem 0.25rem 0 0;
|
|
text-decoration: none;
|
|
color: #495057;
|
|
cursor: pointer;
|
|
}
|
|
|
|
#transaksi .nav-tabs .nav-link.active {
|
|
color: #495057;
|
|
background-color: #fff;
|
|
border-color: #dee2e6 #dee2e6 #fff;
|
|
}
|
|
|
|
/* Prevent stock tabs from appearing in transaksi tab */
|
|
#transaksi #stock,
|
|
#transaksi #opname,
|
|
#transaksi #mutasi,
|
|
#transaksi #penerimaan {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Prevent transaksi tabs from appearing in stock tab */
|
|
#stock #form-kerja,
|
|
#stock #form-cuci,
|
|
#stock #form-claim {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Ensure proper tab display */
|
|
.tab-content > .tab-pane {
|
|
display: none;
|
|
}
|
|
|
|
.tab-content > .tab-pane.active {
|
|
display: block;
|
|
}
|
|
|
|
/* Ensure main tab content is properly separated */
|
|
#transaksi {
|
|
display: none;
|
|
}
|
|
|
|
#transaksi.active {
|
|
display: block;
|
|
}
|
|
|
|
#stock {
|
|
display: none;
|
|
}
|
|
|
|
#stock.active {
|
|
display: block;
|
|
}
|
|
|
|
/* Ensure sub-tab content is properly contained within their parent tabs */
|
|
#transaksi .tab-content .tab-pane {
|
|
display: none;
|
|
}
|
|
|
|
#transaksi .tab-content .tab-pane.active {
|
|
display: block;
|
|
}
|
|
|
|
#stock .tab-content .tab-pane {
|
|
display: none;
|
|
}
|
|
|
|
#stock .tab-content .tab-pane.active {
|
|
display: block;
|
|
}
|
|
|
|
/* Additional safety to prevent cross-tab content display */
|
|
#transaksi .tab-content #opname,
|
|
#transaksi .tab-content #mutasi,
|
|
#transaksi .tab-content #penerimaan {
|
|
display: none !important;
|
|
}
|
|
|
|
#stock .tab-content #form-kerja,
|
|
#stock .tab-content #form-cuci,
|
|
#stock .tab-content #form-claim {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Force proper tab separation */
|
|
.tab-content > #stock {
|
|
display: none !important;
|
|
}
|
|
|
|
.tab-content > #stock.active {
|
|
display: block !important;
|
|
}
|
|
|
|
.tab-content > #transaksi {
|
|
display: none !important;
|
|
}
|
|
|
|
.tab-content > #transaksi.active {
|
|
display: block !important;
|
|
}
|
|
|
|
</style>
|
|
@endsection
|
|
|
|
@section('content')
|
|
<div class="mobile-container">
|
|
<div class="container">
|
|
<div class="row mb-4 mt-4">
|
|
<div class="col-8">
|
|
{{-- <h5 class="text-center mt-4">Cipta Kreasi Baru</h5> --}}
|
|
<a href="/"><img src="{{ asset('logo-ckb.png') }}" style="width: 100%" alt="LOGO CKB"></a>
|
|
</div>
|
|
<div class="col-4 text-right my-auto">
|
|
<a class="btn btn-sm btn-danger mt-3" style="background: red !important;" href="{{ route('logout') }}" onclick="logout(event)">
|
|
{{ __('Logout') }}
|
|
</a>
|
|
|
|
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
|
|
@csrf
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<!--begin::Portlet-->
|
|
<div class="kt-portlet">
|
|
<div class="kt-portlet__head">
|
|
<div class="kt-portlet__head-label">
|
|
<span>{{ $mechanic->name }}</span>
|
|
</div>
|
|
<div class="kt-portlet__head-toolbar">
|
|
<span class="float-right">{{ $now }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="kt-portlet__body">
|
|
<div class="row">
|
|
<div class="col-8">
|
|
<b>Dealer {{ $mechanic->dealer_name }}</b><br><br>
|
|
<a href="#">Total {{ $count_transaction_dealers }} Pekerjaan terkirim pada dealer</a><br>
|
|
<a href="#">Anda telah posting {{ $count_transaction_users }} pekerjaan</a>
|
|
|
|
<!-- KPI Information -->
|
|
<div class="mt-3">
|
|
@if($kpiData['has_target'])
|
|
<div class="row">
|
|
<div class="col-6">
|
|
<small class="text-muted">Target {{ $kpiData['period'] }}</small><br>
|
|
<strong class="text-primary" id="kpi-target">{{ number_format($kpiData['target']) }} Pekerjaan</strong>
|
|
</div>
|
|
<div class="col-6">
|
|
<small class="text-muted">Pencapaian</small><br>
|
|
<strong class="text-{{ $kpiData['status_color'] }}" id="kpi-actual">{{ number_format($kpiData['actual']) }} Pekerjaan</strong>
|
|
</div>
|
|
</div>
|
|
<div class="mt-2">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<small class="text-muted">Progress</small>
|
|
<small class="text-{{ $kpiData['status_color'] }} font-weight-bold" id="kpi-percentage">{{ $kpiData['percentage'] }}%</small>
|
|
</div>
|
|
<div class="progress" style="height: 8px;">
|
|
@php
|
|
$progressWidth = min(100, $kpiData['percentage']);
|
|
@endphp
|
|
<div class="progress-bar bg-{{ $kpiData['status_color'] }}"
|
|
role="progressbar"
|
|
style="width: {{ $progressWidth }}%"
|
|
aria-valuenow="{{ $kpiData['percentage'] }}"
|
|
aria-valuemin="0"
|
|
aria-valuemax="100">
|
|
</div>
|
|
</div>
|
|
<div class="mt-1">
|
|
@if($kpiData['status'] == 'exceeded')
|
|
<small class="text-success"><i class="fa fa-check-circle"></i> Target tercapai!</small>
|
|
@elseif($kpiData['status'] == 'good')
|
|
<small class="text-info"><i class="fa fa-arrow-up"></i> Performa baik</small>
|
|
@elseif($kpiData['status'] == 'fair')
|
|
<small class="text-warning"><i class="fa fa-exclamation-triangle"></i> Perlu peningkatan</small>
|
|
@elseif($kpiData['status'] == 'poor')
|
|
<small class="text-danger"><i class="fa fa-times-circle"></i> Perlu perbaikan</small>
|
|
@else
|
|
<small class="text-secondary"><i class="fa fa-clock"></i> Belum ada data</small>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
@else
|
|
<div class="text-center py-2">
|
|
<i class="fa fa-info-circle text-muted"></i>
|
|
<small class="text-muted">Belum ada target KPI untuk {{ $kpiData['period'] }}</small>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
<div class="col-4">
|
|
<div class="text-center mt-2">
|
|
<a href="{{ route('transaction.lists') }}">
|
|
<i style="font-size: 16px;" class="fa fa-eye"></i>
|
|
<p>Laporan harian</p>
|
|
</a>
|
|
</div>
|
|
<div class="text-center mt-2">
|
|
<a href="{{ route('transaction.recap') }}">
|
|
<i style="font-size: 16px;" class="fa fa-eye"></i>
|
|
<p>Rekap Laporan</p>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<!--begin::Portlet-->
|
|
<div class="kt-portlet">
|
|
<div class="kt-portlet__body">
|
|
<!-- Main Tabs -->
|
|
<ul class="nav nav-tabs nav-tabs-line nav-tabs-line-primary" role="tablist">
|
|
<li class="nav-item">
|
|
<a class="nav-link active" href="#transaksi">Transaksi</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="#stock">Stock</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content">
|
|
<!-- Tab Transaksi -->
|
|
<div class="tab-pane active" id="transaksi" role="tabpanel">
|
|
<!-- Sub Tabs untuk Transaksi -->
|
|
<ul class="nav nav-tabs nav-tabs-line nav-tabs-line-success mt-3" role="tablist">
|
|
<li class="nav-item">
|
|
<a class="nav-link @if(old('form') == 'work') active @endif" href="#form-kerja">Form Kerja</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link @if(old('form') == 'wash') active @endif" href="#form-cuci">Form Cuci</a>
|
|
</li>
|
|
@if(Auth::user()->role_id == 3)
|
|
<li class="nav-item">
|
|
<a class="nav-link @if(old('form') == 'claim') active @endif" href="#form-claim">Klaim</a>
|
|
</li>
|
|
@endif
|
|
</ul>
|
|
|
|
<div class="tab-content mt-3">
|
|
<div class="tab-pane @if(old('form') == 'work') active @endif" id="form-kerja" role="tabpanel">
|
|
<!-- Form Kerja -->
|
|
<form action="{{ route('transaction.store') }}" method="POST" id="workForm">
|
|
@csrf
|
|
<input type="hidden" name="form" value="work">
|
|
<input type="hidden" name="mechanic_id" value="{{ $mechanic->id }}">
|
|
<input type="hidden" name="dealer_id" value="{{ $mechanic->dealer_id }}">
|
|
|
|
|
|
|
|
@if($errors->has('error'))
|
|
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
|
<strong><i class="fa fa-times-circle"></i> Error:</strong>
|
|
{{ $errors->first('error') }}
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
@endif
|
|
<div class="form-group row">
|
|
<div class="col-6">
|
|
<label>No. SPK</label>
|
|
<input type="text" name="spk_no" class="form-control @if(old('form') == 'work') @error('spk_no') is-invalid @enderror @endif" value="{{ old('spk_no') }}" placeholder="No. SPK" required>
|
|
|
|
@if(old('form') == 'work')
|
|
@error('spk_no')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
<div class="col-6">
|
|
<label>No. Polisi</label>
|
|
<input type="text" name="police_number" class="form-control @if(old('form') == 'work') @error('police_number') is-invalid @enderror" @endif value="{{ old('police_number') }}" placeholder="No. Polisi" required>
|
|
@if(old('form') == 'work')
|
|
@error('police_number')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<div class="col-6">
|
|
<label>Warranty</label>
|
|
<select name="warranty" class="form-control @if(old('form') == 'work') @error('warranty') is-invalid @enderror @endif">
|
|
<option value="" @if(old('form') == 'work') @if(old('warranty') == '' || old('warranty') == null) selected @endif @else selected @endif>Warranty</option>
|
|
<option value="1" @if(old('form') == 'work') @if(old('warranty') == 1) selected @endif @endif>Ya</option>
|
|
<option value="0" @if(old('form') == 'work') @if(old('warranty') == 0) selected @endif @endif>Tidak</option>
|
|
</select>
|
|
@if(old('form') == 'work')
|
|
@error('warranty')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
<div class="col-6">
|
|
<label>Tanggal Pekerjaan</label>
|
|
<input type="text" name="date" id="date-work" required class="form-control @if(old('form') == 'work') @error('date') is-invalid @enderror @endif" placeholder="Tanggal Pekerjaan">
|
|
@if(old('form') == 'work')
|
|
@error('date')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
</div>
|
|
<div class="form-group mt-4">
|
|
<label>Service Advisor</label>
|
|
<select name="user_sa_id" class="form-control @if(old('form') == 'work') @error('user_sa_id') is-invalid @enderror @endif" required>
|
|
<option value="" selected>Service Advisor</option>
|
|
@foreach ($user_sas as $user_sa)
|
|
<option @if(old('form') == 'work') @if($user_sa->id == old('user_sa_id')) selected @enderror @endif value="{{ $user_sa->id }}">{{ $user_sa->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
@error('user_sa_id')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
</div>
|
|
<input type="hidden" name="category" value="work">
|
|
<div class="work_multirow">
|
|
@if (old('work_id') && old('form') == 'work')
|
|
{{-- @php
|
|
dd($errors->all());
|
|
@endphp --}}
|
|
<input type="hidden" class="work_field_counter" value="{{ count(old('work_id')) }}">
|
|
@for ($i = 0; $i < count(old('work_id')); $i++)
|
|
<div class="form-group row" id="work_field{{ $i+1 }}">
|
|
<div class="col-6">
|
|
<select name="work_id[]" id="work_work{{ $i+1 }}" class="form-control @error('work_id.'.$i) is-invalid @enderror">
|
|
<option value="" disabled>Pekerjaan</option>
|
|
@foreach ($work_works as $work)
|
|
<option value="{{ $work->id }}" @if($work->id == old('work_id.'.$i)) selected @endif>{{ $work->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
|
|
@error('work_id.'.$i)
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
</div>
|
|
<div class="col-4">
|
|
<input type="number" class="form-control @error('quantity.'.$i) is-invalid @enderror" value="{{ old('quantity.'.$i) }}" name="quantity[]" placeholder="Qty">
|
|
@error('quantity.'.$i)
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
</div>
|
|
<div class="col-2">
|
|
<button class="btn btn-danger work-btn-remove float-right" style="width: 100%;" type="button" id="workRemove1" onclick="removeFormField('work', 1)">X</button>
|
|
</div>
|
|
</div>
|
|
@endfor
|
|
@else
|
|
<input type="hidden" class="work_field_counter" value="5">
|
|
<div class="form-group row" id="work_field1">
|
|
<div class="col-6">
|
|
<select name="work_id[]" id="work_work1" class="form-control">
|
|
<option value="" selected disabled>Pekerjaan</option>
|
|
@foreach ($work_works as $work)
|
|
<option value="{{ $work->id }}">{{ $work->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-4">
|
|
<input type="number" class="form-control" name="quantity[]" placeholder="Qty">
|
|
</div>
|
|
<div class="col-2">
|
|
<button class="btn btn-danger work-btn-remove float-right" style="width: 100%;" type="button" id="workRemove1" onclick="removeFormField('work', 1)">X</button>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row" id="work_field2">
|
|
<div class="col-6">
|
|
<select name="work_id[]" id="work_work2" class="form-control">
|
|
<option value="" selected disabled>Pekerjaan</option>
|
|
@foreach ($work_works as $work)
|
|
<option value="{{ $work->id }}">{{ $work->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-4">
|
|
<input type="number" class="form-control" name="quantity[]" placeholder="Qty">
|
|
</div>
|
|
<div class="col-2">
|
|
<button class="btn btn-danger work-btn-remove float-right" style="width: 100%;" type="button" id="workRemove2" onclick="removeFormField('work', 2)">X</button>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row" id="work_field3">
|
|
<div class="col-6">
|
|
<select name="work_id[]" id="work_work3" class="form-control">
|
|
<option value="" selected disabled>Pekerjaan</option>
|
|
@foreach ($work_works as $work)
|
|
<option value="{{ $work->id }}">{{ $work->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-4">
|
|
<input type="number" class="form-control" name="quantity[]" placeholder="Qty">
|
|
</div>
|
|
<div class="col-2">
|
|
<button class="btn btn-danger work-btn-remove float-right" style="width: 100%;" type="button" id="workRemove3" onclick="removeFormField('work', 3)">X</button>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row" id="work_field4">
|
|
<div class="col-6">
|
|
<select name="work_id[]" id="work_work4" class="form-control">
|
|
<option value="" selected disabled>Pekerjaan</option>
|
|
@foreach ($work_works as $work)
|
|
<option value="{{ $work->id }}">{{ $work->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-4">
|
|
<input type="number" class="form-control" name="quantity[]" placeholder="Qty">
|
|
</div>
|
|
<div class="col-2">
|
|
<button class="btn btn-danger work-btn-remove float-right" style="width: 100%;" type="button" id="workRemove4" onclick="removeFormField('work', 4)">X</button>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row" id="work_field5">
|
|
<div class="col-6">
|
|
<select name="work_id[]" id="work_work5" class="form-control">
|
|
<option value="" selected disabled>Pekerjaan</option>
|
|
@foreach ($work_works as $work)
|
|
<option value="{{ $work->id }}">{{ $work->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-4">
|
|
<input type="number" class="form-control" name="quantity[]" placeholder="Qty">
|
|
</div>
|
|
<div class="col-2">
|
|
<button class="btn btn-danger work-btn-remove float-right" style="width: 100%;" type="button" id="workRemove5" onclick="removeFormField('work', 5)">X</button>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
<div class="row">
|
|
<div class="col-10"></div>
|
|
<div class="col-2">
|
|
<button class="btn mb-4 btn-sm btn-primary float-right btn-add-field-work" style="width: 100%;" onclick="addFormFieldWithStockCheck('work'); return false;">+</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-brand button-save" style="display: block; width: 100%;">Simpan</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Form Cuci -->
|
|
<div class="tab-pane @if(old('form') == 'wash') active @endif" id="form-cuci" role="tabpanel">
|
|
<form action="{{ route('transaction.store') }}" method="POST" id="washForm">
|
|
@csrf
|
|
<input type="hidden" name="form" value="wash">
|
|
<input type="hidden" name="mechanic_id" value="{{ $mechanic->id }}">
|
|
<input type="hidden" name="dealer_id" value="{{ $mechanic->dealer_id }}">
|
|
<div class="form-group row">
|
|
<div class="col-6">
|
|
<label>No. SPK</label>
|
|
<input type="text" name="spk_no" class="form-control @if(old('form') == 'wash') @error('spk_no') is-invalid @enderror @endif" value="{{ old('spk_no') }}" placeholder="No. SPK" required>
|
|
@if(old('form') == 'wash')
|
|
@error('spk_no')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
<div class="col-6">
|
|
<label>No. Polisi</label>
|
|
<input type="text" name="police_number" class="form-control @if(old('form') == 'wash') @error('police_number') is-invalid @enderror @endif" value="{{ old('police_number') }}" placeholder="No. Polisi" required>
|
|
@if(old('form') == 'wash')
|
|
@error('police_number')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<div class="col-6">
|
|
<label>Warranty</label>
|
|
<select name="warranty" class="form-control @if(old('form') == 'wash') @error('warranty') is-invalid @enderror @endif">
|
|
<option value="" @if(old('form') == 'wash') @if(old('warranty') == '' || old('warranty') == null) selected @endif @else selected @endif>Warranty</option>
|
|
<option value="1" @if(old('form') == 'wash') @if(old('warranty') == 1) selected @endif @endif>Ya</option>
|
|
<option value="0" @if(old('form') == 'wash') @if(old('warranty') == 0) selected @endif @endif>Tidak</option>
|
|
</select>
|
|
@if(old('form') == 'wash')
|
|
@error('warranty')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
<div class="col-6">
|
|
<label>Tanggal Pekerjaan</label>
|
|
<input type="text" id="date-wash" name="date" class="form-control @if(old('form') == 'wash') @error('date') is-invalid @enderror @endif" placeholder="Tanggal Pekerjaan" required>
|
|
@if(old('form') == 'wash')
|
|
@error('date')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
</div>
|
|
<div class="form-group mt-4">
|
|
<label>Service Advisor</label>
|
|
<select name="user_sa_id" class="form-control @if(old('form') == 'wash') @error('user_sa_id') is-invalid @enderror @endif" required>
|
|
<option value="" selected>Service Advisor</option>
|
|
@foreach ($user_sas as $user_sa)
|
|
<option @if(old('form') == 'wash') @if($user_sa->id == old('user_sa_id')) selected @enderror @endif value="{{ $user_sa->id }}">{{ $user_sa->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
@if(old('form') == 'wash')
|
|
@error('user_sa_id')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
<input type="hidden" name="category" value="work">
|
|
<div class="form-group">
|
|
<label>Pekerjaan</label>
|
|
<input type="text" class="form-control" disabled value="{{ $wash_work->name }}">
|
|
<input type="hidden" class="form-control" name="work_id[]" value="{{ $wash_work->id }}">
|
|
<input type="hidden" class="form-control" name="quantity[]" value="1">
|
|
</div>
|
|
<button class="btn btn-brand button-save" style="display: block; width: 100%;">Simpan</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Form Klaim - Hanya untuk Mekanik -->
|
|
@if(Auth::user()->role_id == 3)
|
|
<div class="tab-pane @if(old('form') == 'claim') active @endif" id="form-claim" role="tabpanel">
|
|
<div class="mt-3">
|
|
<h6 class="mb-3">Daftar Pekerjaan yang Dapat Diklaim</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered table-hover" id="claimTransactionsTable">
|
|
<thead class="thead-light">
|
|
<tr>
|
|
<th width="10%">Tanggal</th>
|
|
<th width="15%">No. SPK</th>
|
|
<th width="15%">No. Polisi</th>
|
|
<th width="20%">Pekerjaan</th>
|
|
<th width="10%">Qty</th>
|
|
<th width="15%">Service Advisor</th>
|
|
<th width="10%">Status</th>
|
|
<th width="5%">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- Data will be loaded via DataTables AJAX -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Tab Stock (pindahkan ke sini, di luar tab transaksi) -->
|
|
<div class="tab-pane" id="stock" role="tabpanel">
|
|
<!-- Sub Tabs untuk Stock, samakan dengan Transaksi -->
|
|
<ul class="nav nav-tabs nav-tabs-line nav-tabs-line-success mt-3" role="tablist">
|
|
<li class="nav-item">
|
|
<a class="nav-link @if(old('form') == 'opname') active @endif" href="#opname">Opname</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link @if(old('form') == 'mutasi') active @endif" href="#mutasi">Mutasi</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link @if(old('form') == 'penerimaan') active @endif" href="#penerimaan">Penerimaan Mutasi</a>
|
|
</li>
|
|
</ul>
|
|
<div class="tab-content mt-3">
|
|
<!-- Form Opname -->
|
|
<div class="tab-pane @if(old('form') == 'opname') active @endif" id="opname" role="tabpanel">
|
|
<form action="{{ route('opnames.store') }}" method="POST" id="opnameForm">
|
|
@csrf
|
|
<input type="hidden" name="form" value="opname">
|
|
<input type="hidden" name="user_id" value="{{ $mechanic->id }}">
|
|
<input type="hidden" name="dealer_id" value="{{ $mechanic->dealer_id }}">
|
|
|
|
<div class="form-group">
|
|
<label>Tanggal Opname <small class="text-muted">(Default: Hari ini)</small></label>
|
|
<input type="text" name="opname_date" id="date-opname" class="form-control" value="{{ old('opname_date', date('Y-m-d')) }}" placeholder="YYYY-MM-DD">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Keterangan <small class="text-muted">(Opsional)</small></label>
|
|
<textarea name="description" class="form-control" rows="3" placeholder="Keterangan opname (opsional)">{{ old('description') }}</textarea>
|
|
</div>
|
|
|
|
<!-- List Produk dengan Stock -->
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered table-striped">
|
|
<thead class="thead-light">
|
|
<tr>
|
|
<th class="text-center">Produk</th>
|
|
<th class="text-center">Dealer</th>
|
|
<th class="text-center">Stock Fisik</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{-- Dealer/Mechanic - Show products for current dealer only --}}
|
|
@foreach($products as $product)
|
|
@php
|
|
$stock = $product->stocks->first();
|
|
$currentStock = $stock ? $stock->quantity : 0;
|
|
@endphp
|
|
<tr>
|
|
<td class="text-center">{{ $product->name }}</td>
|
|
<td class="text-center">{{ $mechanic->dealer_name }}</td>
|
|
<td>
|
|
<input type="hidden" name="product_id[]" value="{{ $product->id }}">
|
|
<input type="hidden" name="dealer_id_stock[]" value="{{ $mechanic->dealer_id }}">
|
|
<input type="hidden" name="system_stock[]" value="{{ $currentStock }}">
|
|
<input type="number" class="form-control physical-stock" name="physical_stock[]" step="0.01" placeholder="0.00" data-system="{{ $currentStock }}" value="{{ old('physical_stock.'.$loop->index, '0.00') }}" min="0">
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="mt-4 mb-3">
|
|
<button id="btn-save-opname" class="btn btn-warning btn-lg d-block w-100 mt-2">
|
|
Simpan Opname
|
|
</button>
|
|
<small class="text-muted d-block text-center mt-2">
|
|
<i class="fa fa-info-circle"></i>
|
|
Stock fisik yang kosong akan otomatis diisi dengan 0
|
|
</small>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Form Mutasi -->
|
|
<div class="tab-pane @if(old('form') == 'mutasi') active @endif" id="mutasi" role="tabpanel">
|
|
<form action="{{ route('mutations.store') }}" method="POST" id="mutasiForm">
|
|
@csrf
|
|
<input type="hidden" name="from_dealer_id" value="{{ $mechanic->dealer_id }}">
|
|
<input type="hidden" name="from_transaction_page" value="1">
|
|
|
|
<div class="form-group">
|
|
<label>Dealer Asal</label>
|
|
<input type="text" class="form-control" value="{{ $mechanic->dealer_name }}" disabled>
|
|
<small class="text-muted">Otomatis terdeteksi dari akun Anda</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="to_dealer_id">Dealer Tujuan </label>
|
|
<select name="to_dealer_id" id="to_dealer_id" class="form-control" required>
|
|
<option value="">Pilih Dealer Tujuan</option>
|
|
@php
|
|
$dealers = \App\Models\Dealer::where('id', '!=', $mechanic->dealer_id)->get();
|
|
@endphp
|
|
@foreach($dealers as $dealer)
|
|
<option value="{{ $dealer->id }}">{{ $dealer->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<label class="form-label mb-0">Detail Produk</span></label>
|
|
<button type="button" class="btn btn-success btn-sm" id="add-product-mutasi">
|
|
<i class="fa fa-plus"></i> Tambah Produk
|
|
</button>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered table-sm" id="products-table-mutasi">
|
|
<thead>
|
|
<tr>
|
|
<th width="40%">Produk</th>
|
|
<th width="20%">Stock Tersedia</th>
|
|
<th width="25%">Quantity</th>
|
|
<th width="15%">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="products-tbody-mutasi">
|
|
<tr class="product-row-mutasi" data-index="0">
|
|
<td>
|
|
<select name="products[0][product_id]" class="form-control product-select-mutasi" required>
|
|
<option value="">Pilih Produk</option>
|
|
@foreach($products as $product)
|
|
<option value="{{ $product->id }}">{{ $product->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</td>
|
|
<td class="text-center">
|
|
<span class="available-stock-mutasi text-muted">-</span>
|
|
</td>
|
|
<td>
|
|
<input type="number"
|
|
name="products[0][quantity_requested]"
|
|
class="form-control quantity-input-mutasi"
|
|
min="0.01"
|
|
step="0.01"
|
|
placeholder="0"
|
|
required>
|
|
</td>
|
|
<td>
|
|
<button type="button" class="btn btn-danger btn-sm remove-product-mutasi" disabled>
|
|
<i class="fa fa-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-4 mb-3">
|
|
<button id="btn-save-mutasi" type="submit" class="btn btn-warning btn-lg d-block w-100 mt-2">
|
|
Kirim Mutasi
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Tab Penerimaan Mutasi -->
|
|
<div class="tab-pane @if(old('form') == 'penerimaan') active @endif" id="penerimaan" role="tabpanel">
|
|
<div class="mt-3">
|
|
<h6 class="mb-3">Daftar Mutasi yang Perlu Diterima & Disetujui</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered table-hover" id="receiveMutationsTable">
|
|
<thead class="thead-light">
|
|
<tr>
|
|
<th width="15%">No. Mutasi</th>
|
|
<th width="20%">Dealer Asal</th>
|
|
<th width="20%">Dealer Tujuan</th>
|
|
<th width="12%">Status</th>
|
|
<th width="8%">Total Item</th>
|
|
<th width="10%">Tanggal</th>
|
|
<th width="15%">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- Data will be loaded via DataTables AJAX -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--end::Portlet-->
|
|
</div>
|
|
</div>
|
|
<input type="hidden" name="ajax_work_url" value="{{ route('transaction.workcategory', ':id') }}">
|
|
<input type="hidden" name="mechanic_id" value="{{ $mechanic->id }}">
|
|
<input type="hidden" name="dealer_id" value="{{ $mechanic->dealer_id }}">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Detail Mutasi -->
|
|
<div class="modal fade" id="mutationDetailModal" tabindex="-1" role="dialog" aria-labelledby="mutationDetailModalLabel">
|
|
<div class="modal-dialog modal-xl" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="mutationDetailModalLabel">Detail & Penerimaan Mutasi</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<form id="receiveMutationForm" action="" method="POST">
|
|
@csrf
|
|
<input type="hidden" name="from_transaction_page" value="1">
|
|
<div class="modal-body">
|
|
<div id="mutationDetailContent">
|
|
<div class="text-center">
|
|
<i class="fa fa-spinner fa-spin fa-2x"></i>
|
|
<p class="mt-2">Memuat data...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Tutup</button>
|
|
<button type="submit" class="btn btn-success" id="receiveButton" style="display: none;">
|
|
<i class="fa fa-check"></i> Terima
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@section('javascripts')
|
|
<script>
|
|
$.ajaxSetup({
|
|
headers: {
|
|
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
|
}
|
|
});
|
|
|
|
// Global variables (stock checking removed)
|
|
let dealerId = {{ $mechanic->dealer_id }};
|
|
|
|
function logout(event){
|
|
event.preventDefault();
|
|
Swal.fire({
|
|
title: 'Logout?',
|
|
text: "Anda akan keluar dari sistem!",
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#d33',
|
|
cancelButtonColor: '#dedede',
|
|
confirmButtonText: 'Logout'
|
|
}).then((result) => {
|
|
if (result.value) {
|
|
$('#logout-form').submit();
|
|
}
|
|
})
|
|
}
|
|
|
|
function addFormField(form) {
|
|
var id = $(`.${form}_field_counter`).val();
|
|
id = parseInt(id) + 1;
|
|
$(`
|
|
<div class="form-group row" id="${form}_field${id}">
|
|
<div class="col-6">
|
|
<select name="${form}_work_id[]" id="${form}_work${id}" class="form-control">
|
|
<option selected disabled>Pekerjaan</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-4">
|
|
<input type="number" class="form-control" name="${form}_quantity[]" placeholder="Qty">
|
|
</div>
|
|
<div class="col-2">
|
|
<button class="btn btn-danger" onclick="removeFormField('${form}', ${id})" style="width: 100%; opacity: 1;" id="remove${id}">X</button>
|
|
</div>
|
|
</div>
|
|
`).insertBefore($(".btn-add-field-"+form).parent().parent());
|
|
|
|
let category_id = 1;
|
|
if(form == 'wash') {
|
|
category_id = 1;
|
|
}else if(form == 'work') {
|
|
category_id = 3;
|
|
}
|
|
|
|
let ajax_work_url = $("input[name='ajax_work_url']").val()
|
|
ajax_work_url = ajax_work_url.replace(':id', category_id);
|
|
getWork(ajax_work_url, form, id)
|
|
|
|
if(id > 1) {
|
|
$(".work-btn-remove").removeAttr('disabled')
|
|
$(".work-btn-remove").removeClass("disabled")
|
|
$(".work-btn-remove").css("opacity", "1")
|
|
}
|
|
|
|
$(`.${form}_field_counter`).val(id);
|
|
}
|
|
|
|
function removeFormField(form, id) {
|
|
var attr = $(".work-btn-remove").attr('disabled');
|
|
var id = $(`.${form}_field_counter`).val();
|
|
if (typeof attr !== 'undefined' && attr !== false) {
|
|
}else{
|
|
id = parseInt(id) - 1;
|
|
$(`.${form}_field_counter`).val(id);
|
|
$(`#${form}_field${id}`).remove();
|
|
}
|
|
|
|
|
|
if(id < 2) {
|
|
$(".work-btn-remove").attr("disabled", "disabled")
|
|
$(".work-btn-remove").addClass("disabled")
|
|
$(".work-btn-remove").css("opacity", "0.5")
|
|
}
|
|
}
|
|
|
|
function getWork(ajax_work_url, form, id) {
|
|
$.get(ajax_work_url, function(res) {
|
|
var $select = $(`#${form}_work${id}`);
|
|
|
|
// Clear existing options except the first one (placeholder)
|
|
$select.find('option:not(:first)').remove();
|
|
|
|
// Add new options
|
|
$.each(res.data, function (i, item) {
|
|
$select.append($('<option>', {
|
|
value: item.id,
|
|
text : item.name
|
|
}));
|
|
});
|
|
|
|
// Ensure placeholder is still properly set
|
|
var $placeholder = $select.find('option:first');
|
|
if ($placeholder.length) {
|
|
$placeholder.prop('disabled', true).prop('selected', true).val('');
|
|
}
|
|
})
|
|
}
|
|
|
|
// Setup form fields without stock checking
|
|
$(document).ready(function() {
|
|
// Ensure transaksi tab is active by default if no tab is active
|
|
if (!$('.nav-tabs-line-primary .nav-link.active').length) {
|
|
$('.nav-link[href="#transaksi"]').addClass('active');
|
|
$('#transaksi').addClass('active');
|
|
$('.nav-link[href="#form-kerja"]').addClass('active');
|
|
$('#form-kerja').addClass('active');
|
|
}
|
|
|
|
// Ensure placeholder options are properly disabled and not selectable
|
|
$('select[name="work_id[]"]').each(function() {
|
|
var $select = $(this);
|
|
var $placeholder = $select.find('option:first');
|
|
|
|
// Make sure placeholder is disabled and has empty value
|
|
if ($placeholder.length) {
|
|
$placeholder.prop('disabled', true).prop('selected', true).val('');
|
|
}
|
|
|
|
// Prevent auto-selection of first non-disabled option
|
|
$select.on('focus', function() {
|
|
if (!$(this).val()) {
|
|
$(this).find('option:first').prop('selected', true);
|
|
}
|
|
});
|
|
});
|
|
|
|
// Handle form errors - ensure work selections are maintained
|
|
@if($errors->any() && (old('form') == 'work' || old('form') == 'wash'))
|
|
// When there are form errors, ensure the correct work selections are maintained
|
|
// The old values are already handled by the Blade template in the HTML
|
|
// We just need to ensure proper placeholder handling
|
|
$('select[name="work_id[]"]').each(function() {
|
|
var $select = $(this);
|
|
|
|
// If no value is selected, ensure placeholder is selected
|
|
if (!$select.val() || $select.val() === '') {
|
|
var $placeholder = $select.find('option:first');
|
|
if ($placeholder.length) {
|
|
$placeholder.prop('selected', true);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Update field counter to match the actual number of work fields when validation fails
|
|
@if(old('form') == 'work' && old('work_id'))
|
|
var actualFieldCount = $('select[name="work_id[]"]').length;
|
|
$('.work_field_counter').val(actualFieldCount);
|
|
console.log('Validation failed - updating field counter to:', actualFieldCount);
|
|
console.log('Old work_id values:', @json(old('work_id')));
|
|
@endif
|
|
@endif
|
|
});
|
|
|
|
// Function to add form fields (stock checking removed)
|
|
function addFormFieldWithStockCheck(form) {
|
|
addFormField(form); // Call original function
|
|
|
|
// Setup placeholder for new field
|
|
setTimeout(function() {
|
|
var id = $(`.${form}_field_counter`).val();
|
|
var $newSelect = $(`#${form}_work${id}`);
|
|
|
|
// Ensure placeholder is properly set
|
|
var $placeholder = $newSelect.find('option:first');
|
|
if ($placeholder.length) {
|
|
$placeholder.prop('disabled', true).prop('selected', true).val('');
|
|
}
|
|
|
|
// Prevent auto-selection of first non-disabled option
|
|
$newSelect.on('focus', function() {
|
|
if (!$(this).val()) {
|
|
$(this).find('option:first').prop('selected', true);
|
|
}
|
|
});
|
|
}, 100);
|
|
}
|
|
|
|
$("#workForm").submit(function(e) {
|
|
// Validate required fields
|
|
var spkNo = $('input[name="spk_no"]').val().trim();
|
|
var policeNumber = $('input[name="police_number"]').val().trim();
|
|
var userSaId = $('select[name="user_sa_id"]').val();
|
|
var date = $('input[name="date"]').val().trim();
|
|
var warranty = $('select[name="warranty"]').val();
|
|
|
|
var errorMessages = [];
|
|
|
|
if (!spkNo) {
|
|
errorMessages.push('No. SPK harus diisi');
|
|
$('input[name="spk_no"]').addClass('is-invalid');
|
|
} else {
|
|
$('input[name="spk_no"]').removeClass('is-invalid');
|
|
}
|
|
|
|
if (!policeNumber) {
|
|
errorMessages.push('No. Polisi harus diisi');
|
|
$('input[name="police_number"]').addClass('is-invalid');
|
|
} else {
|
|
$('input[name="police_number"]').removeClass('is-invalid');
|
|
}
|
|
|
|
if (!userSaId || userSaId === '') {
|
|
errorMessages.push('Service Advisor harus dipilih');
|
|
$('select[name="user_sa_id"]').addClass('is-invalid');
|
|
} else {
|
|
$('select[name="user_sa_id"]').removeClass('is-invalid');
|
|
}
|
|
|
|
if (!date) {
|
|
errorMessages.push('Tanggal Pekerjaan harus diisi');
|
|
$('input[name="date"]').addClass('is-invalid');
|
|
} else {
|
|
$('input[name="date"]').removeClass('is-invalid');
|
|
}
|
|
|
|
if (!warranty || warranty === '' || warranty === 'Warranty') {
|
|
errorMessages.push('Warranty harus dipilih');
|
|
$('select[name="warranty"]').addClass('is-invalid');
|
|
} else {
|
|
$('select[name="warranty"]').removeClass('is-invalid');
|
|
}
|
|
|
|
if (errorMessages.length > 0) {
|
|
e.preventDefault();
|
|
Swal.fire({
|
|
title: 'Validasi Gagal',
|
|
html: `
|
|
<div class="text-left">
|
|
<p class="mb-3">Mohon lengkapi field berikut:</p>
|
|
<ul class="text-left">
|
|
${errorMessages.map(msg => '<li>' + msg + '</li>').join('')}
|
|
</ul>
|
|
</div>
|
|
`,
|
|
icon: 'warning',
|
|
confirmButtonText: 'OK'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Validate that at least one work is selected with valid quantity
|
|
var hasValidWorkQuantity = false;
|
|
var validCount = 0;
|
|
var emptyWorkSelects = [];
|
|
var emptyQuantityInputs = [];
|
|
|
|
$('select[name="work_id[]"]').each(function(index) {
|
|
var workId = $(this).val();
|
|
var $quantityInput = $(this).closest('.form-group').find('input[name="quantity[]"]');
|
|
var quantity = $quantityInput.val();
|
|
|
|
// Remove previous error styling
|
|
$(this).removeClass('is-invalid');
|
|
$quantityInput.removeClass('is-invalid');
|
|
|
|
// Check if this pair is valid (both work and quantity filled)
|
|
if (workId && workId !== '' && quantity && parseInt(quantity) > 0) {
|
|
hasValidWorkQuantity = true;
|
|
validCount++;
|
|
} else if (workId && workId !== '' && (!quantity || parseInt(quantity) <= 0)) {
|
|
// Work selected but no valid quantity
|
|
emptyQuantityInputs.push($quantityInput);
|
|
} else if ((!workId || workId === '') && quantity && parseInt(quantity) > 0) {
|
|
// Quantity filled but no work selected
|
|
emptyWorkSelects.push($(this));
|
|
}
|
|
});
|
|
|
|
if (!hasValidWorkQuantity) {
|
|
e.preventDefault();
|
|
|
|
// Highlight problematic fields
|
|
emptyWorkSelects.forEach(function($select) {
|
|
$select.addClass('is-invalid');
|
|
});
|
|
emptyQuantityInputs.forEach(function($input) {
|
|
$input.addClass('is-invalid');
|
|
});
|
|
|
|
var message = 'Minimal pilih satu pekerjaan dan isi quantity-nya sebelum menyimpan!';
|
|
if (emptyWorkSelects.length > 0) {
|
|
message += '\n\n• Ada quantity yang diisi tanpa memilih pekerjaan';
|
|
}
|
|
if (emptyQuantityInputs.length > 0) {
|
|
message += '\n\n• Ada pekerjaan yang dipilih tanpa mengisi quantity';
|
|
}
|
|
|
|
Swal.fire({
|
|
title: 'Peringatan Validasi',
|
|
text: message,
|
|
icon: 'warning',
|
|
confirmButtonText: 'OK'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Show info about how many valid pairs will be saved
|
|
console.log(`Akan menyimpan ${validCount} pekerjaan`);
|
|
|
|
|
|
|
|
$(".button-save").attr("disabled", true);
|
|
$(".button-save").addClass("disabled");
|
|
return true;
|
|
})
|
|
|
|
$("#washForm").submit(function(e) {
|
|
// Validate required fields within the wash form context
|
|
var $form = $(this);
|
|
var spkNo = $form.find('input[name="spk_no"]').val();
|
|
var policeNumber = $form.find('input[name="police_number"]').val();
|
|
var userSaId = $form.find('select[name="user_sa_id"]').val();
|
|
var date = $form.find('input[name="date"]').val();
|
|
var warranty = $form.find('select[name="warranty"]').val();
|
|
|
|
var errorMessages = [];
|
|
|
|
// Reset all field error states
|
|
$form.find('input, select').removeClass('is-invalid');
|
|
|
|
if (!spkNo || spkNo.trim() === '') {
|
|
errorMessages.push('No. SPK harus diisi');
|
|
$form.find('input[name="spk_no"]').addClass('is-invalid');
|
|
}
|
|
|
|
if (!policeNumber || policeNumber.trim() === '') {
|
|
errorMessages.push('No. Polisi harus diisi');
|
|
$form.find('input[name="police_number"]').addClass('is-invalid');
|
|
}
|
|
|
|
if (!userSaId || userSaId === '' || userSaId === null) {
|
|
errorMessages.push('Service Advisor harus dipilih');
|
|
$form.find('select[name="user_sa_id"]').addClass('is-invalid');
|
|
}
|
|
|
|
if (!date || date.trim() === '') {
|
|
errorMessages.push('Tanggal Pekerjaan harus diisi');
|
|
$form.find('input[name="date"]').addClass('is-invalid');
|
|
}
|
|
|
|
if (!warranty || warranty === 'Warranty') {
|
|
errorMessages.push('Warranty harus dipilih');
|
|
$form.find('select[name="warranty"]').addClass('is-invalid');
|
|
}
|
|
|
|
if (errorMessages.length > 0) {
|
|
e.preventDefault();
|
|
Swal.fire({
|
|
title: 'Validasi Gagal',
|
|
html: `
|
|
<div class="text-left">
|
|
<p class="mb-3">Mohon lengkapi field berikut:</p>
|
|
<ul class="text-left">
|
|
${errorMessages.map(msg => '<li>' + msg + '</li>').join('')}
|
|
</ul>
|
|
</div>
|
|
`,
|
|
icon: 'warning',
|
|
confirmButtonText: 'OK'
|
|
});
|
|
|
|
// Scroll to first invalid field
|
|
var firstInvalid = $form.find('.is-invalid:first');
|
|
if (firstInvalid.length) {
|
|
$('html, body').animate({
|
|
scrollTop: firstInvalid.offset().top - 100
|
|
}, 500);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Disable submit button to prevent double submission
|
|
$form.find(".button-save").attr("disabled", true);
|
|
$form.find(".button-save").addClass("disabled");
|
|
$form.find(".button-save").text("Menyimpan...");
|
|
|
|
return true;
|
|
})
|
|
|
|
$("#opnameForm").submit(function(e) {
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
// Set default values for empty fields and validate
|
|
var hasValidStock = false;
|
|
|
|
$('.physical-stock').each(function(index) {
|
|
var value = $(this).val();
|
|
|
|
// Set default value to 0 if empty
|
|
if (value === '' || value === null || value === undefined) {
|
|
$(this).val('0.00');
|
|
value = '0.00';
|
|
}
|
|
|
|
// Validate and format the value
|
|
var numValue = parseFloat(value);
|
|
if (!isNaN(numValue) && numValue >= 0) {
|
|
hasValidStock = true;
|
|
// Ensure the value is properly formatted
|
|
$(this).val(numValue.toFixed(2));
|
|
} else {
|
|
// If invalid, set to 0
|
|
$(this).val('0.00');
|
|
hasValidStock = true; // Still consider valid since we set default
|
|
}
|
|
});
|
|
|
|
// Always allow submission since we set defaults
|
|
if (!hasValidStock) {
|
|
// This should never happen now, but just in case
|
|
resetSubmitButton();
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Peringatan',
|
|
text: 'Terjadi kesalahan dalam validasi data. Silakan coba lagi.'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Get opname date or use today as default
|
|
var opnameDate = $('#date-opname').val();
|
|
if (!opnameDate) {
|
|
// Set default to today if empty
|
|
var today = new Date().toISOString().split('T')[0];
|
|
$('#date-opname').val(today);
|
|
opnameDate = today;
|
|
}
|
|
|
|
// Validate date format (YYYY-MM-DD)
|
|
var datePattern = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
if (!datePattern.test(opnameDate)) {
|
|
resetSubmitButton();
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Format Tanggal Salah',
|
|
text: 'Format tanggal harus YYYY-MM-DD (contoh: 2023-12-25)'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Validate if date is valid
|
|
var dateParts = opnameDate.match(datePattern);
|
|
var year = parseInt(dateParts[1], 10);
|
|
var month = parseInt(dateParts[2], 10);
|
|
var day = parseInt(dateParts[3], 10);
|
|
|
|
var testDate = new Date(year, month - 1, day);
|
|
if (testDate.getDate() !== day || testDate.getMonth() !== (month - 1) || testDate.getFullYear() !== year) {
|
|
resetSubmitButton();
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Tanggal Tidak Valid',
|
|
text: 'Tanggal yang dimasukkan tidak valid!'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Check if date is not in the future
|
|
var today = new Date();
|
|
today.setHours(23, 59, 59, 999); // Set to end of today
|
|
if (testDate > today) {
|
|
resetSubmitButton();
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Tanggal Tidak Valid',
|
|
text: 'Tanggal opname tidak boleh lebih dari hari ini!'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
$("#btn-save-opname").attr("disabled", true);
|
|
$("#btn-save-opname").addClass("disabled");
|
|
$("#btn-save-opname").html('<i class="fa fa-spinner fa-spin"></i> Menyimpan...');
|
|
|
|
// Date format is already YYYY-MM-DD, no conversion needed
|
|
|
|
// Submit form
|
|
this.submit();
|
|
})
|
|
|
|
// Handle mutasi form submission
|
|
$(document).on('submit', '#mutasiForm', function(e) {
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
// Validate form
|
|
var isValid = true;
|
|
var errorMessages = [];
|
|
|
|
// Check if dealer tujuan is selected
|
|
var dealerTujuan = $('#to_dealer_id').val();
|
|
console.log('Dealer tujuan value:', dealerTujuan);
|
|
if (!dealerTujuan || dealerTujuan === '') {
|
|
errorMessages.push('Pilih dealer tujuan');
|
|
isValid = false;
|
|
}
|
|
|
|
// Check if at least one product is selected with quantity
|
|
var hasProducts = false;
|
|
var productCount = 0;
|
|
$('.product-select-mutasi').each(function(index) {
|
|
var productId = $(this).val();
|
|
var quantity = $(this).closest('tr').find('.quantity-input-mutasi').val();
|
|
|
|
console.log(`Product ${index}:`, 'ID =', productId, 'Qty =', quantity);
|
|
|
|
if (productId && productId !== '' && quantity && parseFloat(quantity) > 0) {
|
|
hasProducts = true;
|
|
productCount++;
|
|
}
|
|
});
|
|
|
|
if (!hasProducts) {
|
|
errorMessages.push('Minimal pilih satu produk dengan quantity yang valid');
|
|
isValid = false;
|
|
}
|
|
|
|
// Additional validation: check all required fields
|
|
var requiredFields = [
|
|
{name: 'to_dealer_id', label: 'Dealer Tujuan'},
|
|
{name: 'from_dealer_id', label: 'Dealer Asal'}
|
|
];
|
|
|
|
requiredFields.forEach(function(field) {
|
|
var value = $(`[name="${field.name}"]`).val();
|
|
console.log(`${field.name} value:`, value);
|
|
if (!value || value === '') {
|
|
errorMessages.push(`${field.label} harus diisi`);
|
|
isValid = false;
|
|
}
|
|
});
|
|
|
|
// Check products array
|
|
var hasValidProduct = false;
|
|
$('select[name^="products["][name$="][product_id]"]').each(function(index) {
|
|
var productId = $(this).val();
|
|
var quantityName = $(this).attr('name').replace('[product_id]', '[quantity_requested]');
|
|
var quantity = $(`[name="${quantityName}"]`).val();
|
|
|
|
console.log(`Product validation ${index}:`, productId, quantity);
|
|
|
|
if (productId && productId !== '' && quantity && parseFloat(quantity) > 0) {
|
|
hasValidProduct = true;
|
|
}
|
|
});
|
|
|
|
if (!hasValidProduct) {
|
|
errorMessages.push('Minimal harus ada satu produk dengan quantity yang valid');
|
|
isValid = false;
|
|
}
|
|
|
|
console.log('Final validation result:', isValid);
|
|
console.log('Error messages:', errorMessages);
|
|
|
|
// Check for invalid quantities
|
|
var hasInvalidQuantity = false;
|
|
$('.quantity-input-mutasi').each(function() {
|
|
if ($(this).hasClass('is-invalid')) {
|
|
hasInvalidQuantity = true;
|
|
return false; // break loop
|
|
}
|
|
});
|
|
|
|
if (hasInvalidQuantity) {
|
|
errorMessages.push('Perbaiki quantity yang melebihi stock tersedia');
|
|
isValid = false;
|
|
}
|
|
|
|
|
|
|
|
if (!isValid) {
|
|
// Highlight invalid fields
|
|
if (!$('#to_dealer_id').val()) {
|
|
$('#to_dealer_id').addClass('is-invalid');
|
|
} else {
|
|
$('#to_dealer_id').removeClass('is-invalid');
|
|
}
|
|
|
|
// Check products
|
|
$('select[name^="products["][name$="][product_id]"]').each(function() {
|
|
var productId = $(this).val();
|
|
var quantityInput = $(this).closest('tr').find('.quantity-input-mutasi');
|
|
var quantity = quantityInput.val();
|
|
|
|
if (!productId || productId === '') {
|
|
$(this).addClass('is-invalid');
|
|
} else {
|
|
$(this).removeClass('is-invalid');
|
|
}
|
|
|
|
if (!quantity || parseFloat(quantity) <= 0) {
|
|
quantityInput.addClass('is-invalid');
|
|
} else {
|
|
quantityInput.removeClass('is-invalid');
|
|
}
|
|
});
|
|
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Validasi Gagal',
|
|
text: errorMessages.join(', ')
|
|
});
|
|
} else {
|
|
alert('Validasi Gagal: ' + errorMessages.join(', '));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Show confirmation
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire({
|
|
title: 'Kirim Mutasi?',
|
|
text: "Mutasi akan dikirim ke dealer tujuan",
|
|
icon: 'question',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#ffc107',
|
|
cancelButtonColor: '#6c757d',
|
|
confirmButtonText: 'Ya, Kirim',
|
|
cancelButtonText: 'Batal'
|
|
}).then((result) => {
|
|
console.log('SweetAlert result:', result);
|
|
if (result.value === true) { // For older SweetAlert2
|
|
console.log('Confirmed, submitting...');
|
|
submitMutasiFormDirect();
|
|
}
|
|
});
|
|
} else {
|
|
// Fallback to native confirm
|
|
if (confirm('Kirim Mutasi? Mutasi akan dikirim ke dealer tujuan')) {
|
|
submitMutasiFormDirect();
|
|
}
|
|
}
|
|
})
|
|
|
|
// Initialize datepickers when document is ready
|
|
$(document).ready(function() {
|
|
$("#date-work").datepicker({
|
|
format: 'yyyy-mm-dd',
|
|
autoclose: true,
|
|
todayHighlight: true
|
|
});
|
|
$("#date-wash").datepicker({
|
|
format: 'yyyy-mm-dd',
|
|
autoclose: true,
|
|
todayHighlight: true
|
|
});
|
|
$("#date-opname").datepicker({
|
|
format: 'yyyy-mm-dd',
|
|
autoclose: true,
|
|
todayHighlight: true,
|
|
startDate: '-30d',
|
|
endDate: '+0d'
|
|
});
|
|
$("#date-mutasi").datepicker({
|
|
format: 'yyyy-mm-dd',
|
|
autoclose: true,
|
|
todayHighlight: true
|
|
});
|
|
});
|
|
|
|
// Calculate difference for opname
|
|
$(document).on('input change keyup', '.physical-stock', function() {
|
|
var systemStock = parseFloat($(this).data('system')) || 0;
|
|
var inputValue = $(this).val();
|
|
|
|
// Handle empty input - set to 0 for calculation
|
|
var physicalStock = 0;
|
|
if (inputValue !== '' && inputValue !== null && inputValue !== undefined) {
|
|
physicalStock = parseFloat(inputValue) || 0;
|
|
}
|
|
|
|
var difference = physicalStock - systemStock;
|
|
|
|
var differenceCell = $(this).closest('tr').find('.difference');
|
|
differenceCell.text(difference.toFixed(2));
|
|
|
|
// Add color coding for difference
|
|
if (difference > 0) {
|
|
differenceCell.removeClass('text-danger').addClass('text-success');
|
|
} else if (difference < 0) {
|
|
differenceCell.removeClass('text-success').addClass('text-danger');
|
|
} else {
|
|
differenceCell.removeClass('text-success text-danger');
|
|
}
|
|
|
|
// Update product counter
|
|
updateProductCounter();
|
|
});
|
|
|
|
// Function to update product counter
|
|
function updateProductCounter() {
|
|
var totalProducts = $('.physical-stock').length;
|
|
|
|
// Update button text to show total products
|
|
var buttonText = 'Simpan Opname';
|
|
buttonText += ` (${totalProducts} produk)`;
|
|
|
|
if (!$('#btn-save-opname').hasClass('disabled')) {
|
|
$('#btn-save-opname').html(buttonText);
|
|
}
|
|
}
|
|
|
|
// Initialize default values for physical stock inputs
|
|
$(document).ready(function() {
|
|
$('.physical-stock').each(function() {
|
|
var value = $(this).val();
|
|
if (value === '' || value === null || value === undefined) {
|
|
$(this).val('0.00');
|
|
}
|
|
});
|
|
|
|
|
|
});
|
|
|
|
// Handle when input loses focus - set default if empty
|
|
$(document).on('blur', '.physical-stock', function() {
|
|
var value = $(this).val();
|
|
if (value === '' || value === null || value === undefined) {
|
|
$(this).val('0.00');
|
|
}
|
|
// Trigger calculation
|
|
$(this).trigger('input');
|
|
});
|
|
|
|
// Function to reset button state if validation fails
|
|
function resetSubmitButton() {
|
|
$("#btn-save-opname").attr("disabled", false);
|
|
$("#btn-save-opname").removeClass("disabled");
|
|
updateProductCounter(); // Update with current counter
|
|
}
|
|
|
|
// Set default values when user leaves field empty
|
|
$(document).on('blur', '.physical-stock', function() {
|
|
var value = $(this).val();
|
|
if (value === '' || value === null || value === undefined) {
|
|
$(this).val('0.00');
|
|
}
|
|
});
|
|
|
|
// Remove invalid styling when user starts typing in required fields
|
|
$(document).on('input', 'input[name="spk_no"], input[name="police_number"], input[name="date"]', function() {
|
|
$(this).removeClass('is-invalid');
|
|
});
|
|
|
|
$(document).on('change', 'select[name="user_sa_id"]', function() {
|
|
$(this).removeClass('is-invalid');
|
|
});
|
|
|
|
$(document).on('change', 'select[name="warranty"]', function() {
|
|
$(this).removeClass('is-invalid');
|
|
});
|
|
|
|
// Remove invalid styling from work/quantity fields when user interacts with them
|
|
$(document).on('change', 'select[name="work_id[]"]', function() {
|
|
$(this).removeClass('is-invalid');
|
|
});
|
|
|
|
$(document).on('input', 'input[name="quantity[]"]', function() {
|
|
$(this).removeClass('is-invalid');
|
|
});
|
|
|
|
// Handle server-side errors - scroll to first error and highlight
|
|
$(document).ready(function() {
|
|
// Set default date for opname if empty
|
|
if ($('#date-opname').val() === '') {
|
|
var today = new Date().toISOString().split('T')[0];
|
|
$('#date-opname').val(today);
|
|
}
|
|
|
|
// Initialize opname form only if opname tab is active
|
|
if ($('#opname').hasClass('active')) {
|
|
updateProductCounter();
|
|
}
|
|
|
|
// Initialize mutasi form
|
|
updateRemoveButtonsMutasi();
|
|
|
|
// Initialize select2 for mutasi form
|
|
initMutasiSelect2();
|
|
|
|
// Initialize claim table if claim tab is active (only for mechanics)
|
|
if ($('#form-claim').hasClass('active') && {{ Auth::user()->role_id }} == 3) {
|
|
setTimeout(function() {
|
|
initClaimTransactionsTable();
|
|
}, 100);
|
|
}
|
|
|
|
|
|
|
|
// Check if we should show specific tab (after form submission)
|
|
@if(session('success') || session('error') || $errors->any())
|
|
@if(session('active_tab') == 'opname')
|
|
// Activate stock tab and opname sub-tab
|
|
$('.nav-link[href="#stock"]').addClass('active');
|
|
$('#stock').addClass('active');
|
|
$('.nav-link[href="#opname"]').addClass('active');
|
|
$('#opname').addClass('active');
|
|
updateProductCounter();
|
|
@elseif(session('active_tab') == 'mutasi')
|
|
// Activate stock tab and mutasi sub-tab
|
|
$('.nav-link[href="#stock"]').addClass('active');
|
|
$('#stock').addClass('active');
|
|
$('.nav-link[href="#mutasi"]').addClass('active');
|
|
$('#mutasi').addClass('active');
|
|
setTimeout(function() {
|
|
initMutasiSelect2();
|
|
updateRemoveButtonsMutasi();
|
|
}, 100);
|
|
@elseif(session('active_tab') == 'penerimaan')
|
|
// Activate stock tab and penerimaan sub-tab
|
|
$('.nav-link[href="#stock"]').addClass('active');
|
|
$('#stock').addClass('active');
|
|
$('.nav-link[href="#penerimaan"]').addClass('active');
|
|
$('#penerimaan').addClass('active');
|
|
setTimeout(function() {
|
|
initReceiveMutationsTable();
|
|
}, 100);
|
|
@elseif($errors->any() && old('form') == 'work')
|
|
// Activate transaksi tab and form kerja sub-tab when there are work form errors
|
|
$('.nav-link[href="#transaksi"]').addClass('active');
|
|
$('#transaksi').addClass('active');
|
|
$('.nav-link[href="#form-kerja"]').addClass('active');
|
|
$('#form-kerja').addClass('active');
|
|
@elseif($errors->any() && old('form') == 'wash')
|
|
// Activate transaksi tab and form cuci sub-tab when there are wash form errors
|
|
$('.nav-link[href="#transaksi"]').addClass('active');
|
|
$('#transaksi').addClass('active');
|
|
$('.nav-link[href="#form-cuci"]').addClass('active');
|
|
$('#form-cuci').addClass('active');
|
|
@elseif($errors->any() && old('form') == 'claim' && Auth::user()->role_id == 3)
|
|
// Activate transaksi tab and form claim sub-tab when there are claim form errors (only for mechanics)
|
|
$('.nav-link[href="#transaksi"]').addClass('active');
|
|
$('#transaksi').addClass('active');
|
|
$('.nav-link[href="#form-claim"]').addClass('active');
|
|
$('#form-claim').addClass('active');
|
|
@endif
|
|
@endif
|
|
|
|
// Check if there are validation errors
|
|
if ($('.is-invalid').length > 0) {
|
|
// Scroll to first error
|
|
$('html, body').animate({
|
|
scrollTop: $('.is-invalid:first').offset().top - 100
|
|
}, 500);
|
|
|
|
// Show alert for validation errors
|
|
@if(session('error'))
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Terjadi Kesalahan',
|
|
text: '{{ session("error") }}',
|
|
confirmButtonText: 'OK'
|
|
});
|
|
@endif
|
|
}
|
|
|
|
|
|
|
|
// Handle success/error messages for both opname and mutasi
|
|
@if(session('success'))
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Berhasil!',
|
|
text: '{{ session("success") }}',
|
|
timer: 3000,
|
|
showConfirmButton: false
|
|
}).then(() => {
|
|
// Check if this is from mutasi form (contains "Mutasi" in message)
|
|
var successMessage = '{{ session("success") }}';
|
|
var activeTab = '{{ session("active_tab") }}';
|
|
|
|
if (successMessage.toLowerCase().includes('mutasi') && (successMessage.toLowerCase().includes('berhasil dibuat') || activeTab === 'mutasi')) {
|
|
// Reset mutasi form after success for CREATING mutations
|
|
$('#mutasiForm')[0].reset();
|
|
$('#products-tbody-mutasi').html(`
|
|
<tr class="product-row-mutasi" data-index="0">
|
|
<td>
|
|
<select name="products[0][product_id]" class="form-control product-select-mutasi" required>
|
|
<option value="">Pilih Produk</option>
|
|
@foreach($products as $product)
|
|
<option value="{{ $product->id }}">{{ $product->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</td>
|
|
<td class="text-center">
|
|
<span class="available-stock-mutasi text-muted">-</span>
|
|
</td>
|
|
<td>
|
|
<input type="number"
|
|
name="products[0][quantity_requested]"
|
|
class="form-control quantity-input-mutasi"
|
|
min="0.01"
|
|
step="0.01"
|
|
placeholder="0"
|
|
required>
|
|
</td>
|
|
<td>
|
|
<button type="button" class="btn btn-danger btn-sm remove-product-mutasi" disabled>
|
|
<i class="fa fa-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
`);
|
|
productIndexMutasi = 0;
|
|
updateRemoveButtonsMutasi();
|
|
|
|
// Reinitialize select2
|
|
setTimeout(function() {
|
|
initMutasiSelect2();
|
|
}, 100);
|
|
|
|
$("#btn-save-mutasi").attr("disabled", false);
|
|
$("#btn-save-mutasi").removeClass("disabled");
|
|
$("#btn-save-mutasi").html('Kirim Mutasi');
|
|
} else if (successMessage.toLowerCase().includes('penerimaan') || (successMessage.toLowerCase().includes('mutasi') && successMessage.toLowerCase().includes('diterima')) || activeTab === 'penerimaan') {
|
|
// For penerimaan mutasi, just refresh the table without resetting form
|
|
// Activate the correct tab first
|
|
$('.nav-link[href="#stock"]').addClass('active');
|
|
$('#stock').addClass('active');
|
|
$('.nav-link[href="#penerimaan"]').addClass('active');
|
|
$('#penerimaan').addClass('active');
|
|
// Stay on penerimaan tab and refresh table
|
|
setTimeout(function() {
|
|
if (receiveMutationsTable && $.fn.DataTable.isDataTable('#receiveMutationsTable')) {
|
|
receiveMutationsTable.ajax.reload(null, false); // Don't reset paging
|
|
} else {
|
|
// Initialize table if not already initialized
|
|
initReceiveMutationsTable();
|
|
}
|
|
}, 100);
|
|
// Close any open modals
|
|
$('#mutationDetailModal').modal('hide');
|
|
} else if (successMessage.toLowerCase().includes('disetujui') || successMessage.toLowerCase().includes('ditolak') || activeTab === 'persetujuan') {
|
|
// For approval/rejection, refresh the table
|
|
$('.nav-link[href="#stock"]').addClass('active');
|
|
$('#stock').addClass('active');
|
|
$('.nav-link[href="#penerimaan"]').addClass('active');
|
|
$('#penerimaan').addClass('active');
|
|
// Refresh table to show updated status
|
|
setTimeout(function() {
|
|
if (receiveMutationsTable && $.fn.DataTable.isDataTable('#receiveMutationsTable')) {
|
|
receiveMutationsTable.ajax.reload(null, false);
|
|
} else {
|
|
initReceiveMutationsTable();
|
|
}
|
|
}, 100);
|
|
} else if (successMessage.toLowerCase().includes('opname') || activeTab === 'opname') {
|
|
// Reset opname form after success
|
|
$('#opnameForm')[0].reset();
|
|
// Set default values for physical stock inputs
|
|
$('.physical-stock').each(function() {
|
|
$(this).val('0.00');
|
|
});
|
|
$('.difference').text('0.00').removeClass('text-success text-danger');
|
|
$("#btn-save-opname").attr("disabled", false);
|
|
$("#btn-save-opname").removeClass("disabled");
|
|
$("#btn-save-opname").html('Simpan Opname');
|
|
// Set default date
|
|
var today = new Date().toISOString().split('T')[0];
|
|
$('#date-opname').val(today);
|
|
// Update product counter
|
|
updateProductCounter();
|
|
}
|
|
});
|
|
@endif
|
|
|
|
@if(session('error'))
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Terjadi Kesalahan',
|
|
text: '{{ session("error") }}',
|
|
confirmButtonText: 'OK'
|
|
}).then(() => {
|
|
// Check if this is from opname form error
|
|
var activeTab = '{{ session("active_tab") }}';
|
|
if (activeTab === 'opname') {
|
|
// Reset button states for opname form
|
|
$("#btn-save-opname").attr("disabled", false);
|
|
$("#btn-save-opname").removeClass("disabled");
|
|
$("#btn-save-opname").html('Simpan Opname');
|
|
// Set default values for physical stock inputs
|
|
$('.physical-stock').each(function() {
|
|
if ($(this).val() === '' || $(this).val() === null || $(this).val() === undefined) {
|
|
$(this).val('0.00');
|
|
}
|
|
});
|
|
} else if (activeTab === 'mutasi') {
|
|
// Reset button states for mutasi form
|
|
$("#btn-save-mutasi").attr("disabled", false);
|
|
$("#btn-save-mutasi").removeClass("disabled");
|
|
$("#btn-save-mutasi").html('Kirim Mutasi');
|
|
}
|
|
});
|
|
@endif
|
|
|
|
// Handle validation errors
|
|
@if($errors->any())
|
|
var errorMessages = [];
|
|
@foreach($errors->all() as $error)
|
|
errorMessages.push('{{ $error }}');
|
|
@endforeach
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Validasi Gagal',
|
|
html: errorMessages.join('<br>'),
|
|
confirmButtonText: 'OK'
|
|
});
|
|
@endif
|
|
});
|
|
|
|
// Handle opname date field - set default if becomes empty
|
|
$('#date-opname').on('blur', function() {
|
|
if ($(this).val() === '') {
|
|
var today = new Date().toISOString().split('T')[0];
|
|
$(this).val(today);
|
|
}
|
|
});
|
|
|
|
// Handle mutasi form - similar to create mutation
|
|
var productIndexMutasi = 0;
|
|
|
|
|
|
|
|
// Function to submit mutasi form directly
|
|
function submitMutasiFormDirect() {
|
|
console.log('=== SUBMITTING FORM ===');
|
|
|
|
// Set loading state
|
|
$("#btn-save-mutasi").attr("disabled", true);
|
|
$("#btn-save-mutasi").addClass("disabled");
|
|
$("#btn-save-mutasi").html('<i class="fa fa-spinner fa-spin"></i> Mengirim...');
|
|
|
|
// Get form element directly
|
|
var form = document.getElementById('mutasiForm');
|
|
|
|
if (!form) {
|
|
console.error('Form not found!');
|
|
alert('Form tidak ditemukan!');
|
|
return;
|
|
}
|
|
|
|
console.log('Form found:', form);
|
|
console.log('Form action:', form.action);
|
|
console.log('Form method:', form.method);
|
|
|
|
// Check form data
|
|
var formData = new FormData(form);
|
|
console.log('Form data:');
|
|
for (var pair of formData.entries()) {
|
|
console.log(pair[0] + ': ' + pair[1]);
|
|
}
|
|
|
|
// Submit form directly - simplified approach
|
|
try {
|
|
console.log('Attempting form.submit()...');
|
|
|
|
// Temporarily remove the submit event listener to prevent recursion
|
|
$(form).off('submit');
|
|
|
|
// Submit the form
|
|
form.submit();
|
|
console.log('form.submit() called successfully');
|
|
|
|
} catch (error) {
|
|
console.error('Form submission error:', error);
|
|
// Reset button if submission fails
|
|
$("#btn-save-mutasi").attr("disabled", false);
|
|
$("#btn-save-mutasi").removeClass("disabled");
|
|
$("#btn-save-mutasi").html('Kirim Mutasi');
|
|
alert('Terjadi kesalahan saat mengirim form. Silakan coba lagi.');
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Add product row for mutasi
|
|
$('#add-product-mutasi').click(function() {
|
|
productIndexMutasi++;
|
|
var newRow = `
|
|
<tr class="product-row-mutasi" data-index="${productIndexMutasi}">
|
|
<td>
|
|
<select name="products[${productIndexMutasi}][product_id]" class="form-control product-select-mutasi" required>
|
|
<option value="">Pilih Produk</option>
|
|
@foreach($products as $product)
|
|
<option value="{{ $product->id }}">{{ $product->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</td>
|
|
<td class="text-center">
|
|
<span class="available-stock-mutasi text-muted">-</span>
|
|
</td>
|
|
<td>
|
|
<input type="number"
|
|
name="products[${productIndexMutasi}][quantity_requested]"
|
|
class="form-control quantity-input-mutasi"
|
|
min="0.01"
|
|
step="0.01"
|
|
placeholder="0"
|
|
required>
|
|
</td>
|
|
<td>
|
|
<button type="button" class="btn btn-danger btn-sm remove-product-mutasi">
|
|
<i class="fa fa-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
|
|
$('#products-tbody-mutasi').append(newRow);
|
|
|
|
// Initialize select2 for the new product select
|
|
var newSelect = $(`select[name="products[${productIndexMutasi}][product_id]"]`);
|
|
newSelect.select2({
|
|
placeholder: 'Pilih Produk',
|
|
width: '100%',
|
|
language: {
|
|
noResults: function() {
|
|
return "Tidak ada hasil ditemukan";
|
|
},
|
|
searching: function() {
|
|
return "Mencari...";
|
|
}
|
|
}
|
|
});
|
|
|
|
updateRemoveButtonsMutasi();
|
|
});
|
|
|
|
// Remove product row for mutasi
|
|
$(document).on('click', '.remove-product-mutasi', function() {
|
|
$(this).closest('tr').remove();
|
|
updateRemoveButtonsMutasi();
|
|
});
|
|
|
|
// Update remove buttons state for mutasi
|
|
function updateRemoveButtonsMutasi() {
|
|
var rows = $('.product-row-mutasi');
|
|
if (rows.length <= 1) {
|
|
$('.remove-product-mutasi').prop('disabled', true);
|
|
} else {
|
|
$('.remove-product-mutasi').prop('disabled', false);
|
|
}
|
|
}
|
|
|
|
// Handle product selection change for mutasi - get stock info
|
|
$(document).on('change', '.product-select-mutasi', function() {
|
|
var productId = $(this).val();
|
|
var dealerId = {{ $mechanic->dealer_id }};
|
|
var stockSpan = $(this).closest('tr').find('.available-stock-mutasi');
|
|
|
|
if (productId) {
|
|
// Get stock info via AJAX
|
|
$.ajax({
|
|
url: '{{ route("mutations.get-product-stock") }}',
|
|
method: 'GET',
|
|
data: {
|
|
product_id: productId,
|
|
dealer_id: dealerId
|
|
},
|
|
success: function(response) {
|
|
stockSpan.text(parseFloat(response.current_stock).toFixed(2));
|
|
stockSpan.removeClass('text-muted').addClass('text-info');
|
|
},
|
|
error: function() {
|
|
stockSpan.text('-');
|
|
stockSpan.removeClass('text-info').addClass('text-muted');
|
|
}
|
|
});
|
|
} else {
|
|
stockSpan.text('-');
|
|
stockSpan.removeClass('text-info').addClass('text-muted');
|
|
}
|
|
});
|
|
|
|
|
|
|
|
// Validate quantity against available stock for mutasi
|
|
$(document).on('input', '.quantity-input-mutasi', function() {
|
|
var quantity = parseFloat($(this).val()) || 0;
|
|
var stockText = $(this).closest('tr').find('.available-stock-mutasi').text();
|
|
var availableStock = parseFloat(stockText) || 0;
|
|
|
|
if (quantity > availableStock && availableStock > 0) {
|
|
$(this).addClass('is-invalid');
|
|
if (!$(this).siblings('.invalid-feedback').length) {
|
|
$(this).after('<div class="invalid-feedback">Quantity melebihi stock tersedia</div>');
|
|
}
|
|
} else {
|
|
$(this).removeClass('is-invalid');
|
|
$(this).siblings('.invalid-feedback').remove();
|
|
}
|
|
});
|
|
|
|
// Remove error styling when user starts filling fields
|
|
$(document).on('change', '#to_dealer_id', function() {
|
|
$(this).removeClass('is-invalid');
|
|
});
|
|
|
|
$(document).on('change', '.product-select-mutasi', function() {
|
|
$(this).removeClass('is-invalid');
|
|
});
|
|
|
|
$(document).on('input', '.quantity-input-mutasi', function() {
|
|
if (parseFloat($(this).val()) > 0) {
|
|
$(this).removeClass('is-invalid');
|
|
}
|
|
});
|
|
|
|
|
|
|
|
// Initialize Select2 for mutasi form
|
|
function initMutasiSelect2() {
|
|
// Initialize select2 for dealer tujuan
|
|
if ($('#to_dealer_id').length && !$('#to_dealer_id').hasClass('select2-hidden-accessible')) {
|
|
$('#to_dealer_id').select2({
|
|
placeholder: 'Pilih Dealer Tujuan',
|
|
width: '100%',
|
|
language: {
|
|
noResults: function() {
|
|
return "Tidak ada hasil ditemukan";
|
|
},
|
|
searching: function() {
|
|
return "Mencari...";
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initialize select2 for all product selects
|
|
$('.product-select-mutasi').each(function() {
|
|
if (!$(this).hasClass('select2-hidden-accessible')) {
|
|
$(this).select2({
|
|
placeholder: 'Pilih Produk',
|
|
width: '100%',
|
|
language: {
|
|
noResults: function() {
|
|
return "Tidak ada hasil ditemukan";
|
|
},
|
|
searching: function() {
|
|
return "Mencari...";
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initialize DataTable for receive mutations
|
|
var receiveMutationsTable;
|
|
|
|
function initReceiveMutationsTable() {
|
|
if (receiveMutationsTable) {
|
|
receiveMutationsTable.destroy();
|
|
}
|
|
|
|
receiveMutationsTable = $('#receiveMutationsTable').DataTable({
|
|
processing: true,
|
|
serverSide: true,
|
|
ajax: {
|
|
url: '{{ route("mutations.get-pending-mutations") }}',
|
|
data: {
|
|
dealer_id: {{ $mechanic->dealer_id }}
|
|
}
|
|
},
|
|
columns: [
|
|
{data: 'mutation_number', name: 'mutation_number'},
|
|
{data: 'from_dealer', name: 'from_dealer'},
|
|
{data: 'to_dealer', name: 'to_dealer'},
|
|
{data: 'status', name: 'status', orderable: false},
|
|
{data: 'total_items', name: 'total_items'},
|
|
{data: 'created_at', name: 'created_at'},
|
|
{data: 'action', name: 'action', orderable: false, searchable: false}
|
|
],
|
|
pageLength: 10,
|
|
responsive: true,
|
|
scrollX: true
|
|
});
|
|
}
|
|
|
|
// Initialize DataTable for claim transactions
|
|
var claimTransactionsTable;
|
|
|
|
function initClaimTransactionsTable() {
|
|
if (claimTransactionsTable) {
|
|
claimTransactionsTable.destroy();
|
|
}
|
|
|
|
claimTransactionsTable = $('#claimTransactionsTable').DataTable({
|
|
processing: true,
|
|
serverSide: true,
|
|
ajax: {
|
|
url: '{{ route("transaction.get-claim-transactions") }}',
|
|
data: {
|
|
dealer_id: {{ $mechanic->dealer_id }}
|
|
}
|
|
},
|
|
columns: [
|
|
{data: 'date', name: 'date'},
|
|
{data: 'spk', name: 'spk'},
|
|
{data: 'police_number', name: 'police_number'},
|
|
{data: 'work_name', name: 'work_name'},
|
|
{data: 'qty', name: 'qty'},
|
|
{data: 'sa_name', name: 'sa_name'},
|
|
{data: 'status', name: 'status', orderable: false},
|
|
{data: 'action', name: 'action', orderable: false, searchable: false}
|
|
],
|
|
pageLength: 15,
|
|
responsive: true,
|
|
scrollX: true,
|
|
order: [[0, 'desc']], // Sort by date descending
|
|
language: {
|
|
url: "//cdn.datatables.net/plug-ins/1.10.24/i18n/Indonesian.json"
|
|
}
|
|
});
|
|
}
|
|
|
|
// Function removed since we use single table for both receive and approval mutations
|
|
|
|
// Show mutation detail modal
|
|
function showMutationDetail(mutationId) {
|
|
$('#mutationDetailModal').modal('show');
|
|
$('#mutationDetailContent').html(`
|
|
<div class="text-center">
|
|
<i class="fa fa-spinner fa-spin fa-2x"></i>
|
|
<p class="mt-2">Memuat data...</p>
|
|
</div>
|
|
`);
|
|
$('#receiveButton').hide();
|
|
|
|
// Load mutation detail via AJAX
|
|
$.ajax({
|
|
url: '{{ route("mutations.get-detail", ":id") }}'.replace(':id', mutationId),
|
|
method: 'GET',
|
|
success: function(response) {
|
|
if (response.success) {
|
|
renderMutationDetail(response.data);
|
|
} else {
|
|
$('#mutationDetailContent').html(`
|
|
<div class="alert alert-danger">
|
|
<i class="fa fa-exclamation-triangle"></i>
|
|
${response.message || 'Gagal memuat detail mutasi'}
|
|
</div>
|
|
`);
|
|
}
|
|
},
|
|
error: function(xhr) {
|
|
$('#mutationDetailContent').html(`
|
|
<div class="alert alert-danger">
|
|
<i class="fa fa-exclamation-triangle"></i>
|
|
Terjadi kesalahan saat memuat data
|
|
</div>
|
|
`);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Render mutation detail in modal
|
|
function renderMutationDetail(mutation) {
|
|
var statusColor = mutation.status_color;
|
|
var statusLabel = mutation.status_label;
|
|
var isReceived = mutation.status.value === 'received';
|
|
var canBeReceived = mutation.can_be_received;
|
|
|
|
// Set form action URL
|
|
$('#receiveMutationForm').attr('action', '{{ route("mutations.receive", ":id") }}'.replace(':id', mutation.id));
|
|
|
|
// Build detail HTML
|
|
var detailHtml = `
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<strong>No. Mutasi:</strong><br>
|
|
${mutation.mutation_number}
|
|
</div>
|
|
<div class="col-md-6">
|
|
<strong>Status:</strong><br>
|
|
<span class="font-weight-bold text-${statusColor}">${statusLabel}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<strong>Dealer Asal:</strong><br>
|
|
${mutation.from_dealer.name}
|
|
</div>
|
|
<div class="col-md-6">
|
|
<strong>Tanggal:</strong><br>
|
|
${mutation.created_at_formatted}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-12">
|
|
<strong>Dikirim oleh:</strong><br>
|
|
${mutation.requested_by ? mutation.requested_by.name : '-'}
|
|
</div>
|
|
</div>
|
|
|
|
${mutation.shipping_notes ? `
|
|
<div class="row mb-3">
|
|
<div class="col-md-12">
|
|
<strong>Catatan dari Pengirim:</strong><br>
|
|
<div class="alert alert-info mb-0">
|
|
<i class="fa fa-info-circle mr-2"></i>
|
|
${mutation.shipping_notes}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
` : ''}
|
|
|
|
<hr>
|
|
|
|
<h6 class="mb-3">Detail Produk & Penerimaan:</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered mutation-detail-table">
|
|
<thead>
|
|
<tr>
|
|
<th width="30%">Produk</th>
|
|
<th width="15%" class="text-center">Qty Diminta</th>
|
|
<th width="20%" class="text-center">Qty Disetujui</th>
|
|
<th width="35%">Catatan Produk</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
// Add product details with form inputs or read-only display
|
|
if (mutation.mutation_details && mutation.mutation_details.length > 0) {
|
|
mutation.mutation_details.forEach(function(detail) {
|
|
var quantityValue = detail.quantity_approved || detail.quantity_requested;
|
|
var notesValue = detail.notes || '';
|
|
|
|
detailHtml += `
|
|
<tr>
|
|
<td>${detail.product.name}</td>
|
|
<td class="text-center">
|
|
<span class="font-weight-bold text-info">${parseFloat(detail.quantity_requested).toFixed(2)}</span>
|
|
</td>
|
|
<td>
|
|
`;
|
|
|
|
if (canBeReceived && !isReceived) {
|
|
// Editable input for mutations that can be received
|
|
detailHtml += `
|
|
<input type="number"
|
|
name="products[${detail.id}][quantity_approved]"
|
|
class="form-control quantity-approved-input"
|
|
min="0"
|
|
max="${detail.quantity_requested}"
|
|
step="0.01"
|
|
value="${detail.quantity_requested}"
|
|
data-max="${detail.quantity_requested}"
|
|
placeholder="0.00">
|
|
`;
|
|
} else {
|
|
// Read-only display for received mutations
|
|
detailHtml += `
|
|
<span class="font-weight-bold ${quantityValue == detail.quantity_requested ? 'text-success' : 'text-warning'}">
|
|
${parseFloat(quantityValue).toFixed(2)}
|
|
</span>
|
|
${quantityValue != detail.quantity_requested ?
|
|
'<small class="text-muted d-block">(Sebagian)</small>' : ''}
|
|
`;
|
|
}
|
|
|
|
detailHtml += `
|
|
</td>
|
|
<td>
|
|
`;
|
|
|
|
if (canBeReceived && !isReceived) {
|
|
// Editable textarea for mutations that can be received
|
|
detailHtml += `
|
|
<textarea name="products[${detail.id}][notes]"
|
|
class="form-control"
|
|
rows="2"
|
|
placeholder="Catatan untuk produk ini...">${notesValue}</textarea>
|
|
`;
|
|
} else {
|
|
// Read-only display for received mutations
|
|
detailHtml += `
|
|
<span class="text-muted">${notesValue || '-'}</span>
|
|
`;
|
|
}
|
|
|
|
detailHtml += `
|
|
</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
} else {
|
|
detailHtml += `
|
|
<tr>
|
|
<td colspan="4" class="text-center">Tidak ada detail produk</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
detailHtml += `
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-12">
|
|
<label for="mutationNotes"><strong>Catatan Penerimaan:</strong></label>
|
|
`;
|
|
|
|
if (canBeReceived && !isReceived) {
|
|
// Editable textarea for mutations that can be received
|
|
detailHtml += `
|
|
<textarea name="reception_notes" id="mutationNotes" class="form-control" rows="3"
|
|
placeholder="Masukkan catatan kondisi barang saat diterima (opsional)...">${mutation.reception_notes || ''}</textarea>
|
|
`;
|
|
} else {
|
|
// Read-only display for received mutations
|
|
detailHtml += `
|
|
<div class="form-control-plaintext border rounded p-2 bg-light" style="min-height: 60px;">
|
|
${mutation.reception_notes || '<em class="text-muted">Tidak ada catatan</em>'}
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
detailHtml += `
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// Add instructions based on status
|
|
if (canBeReceived && !isReceived) {
|
|
detailHtml += `
|
|
<div class="alert alert-info mb-0">
|
|
<div class="d-flex align-items-start">
|
|
<i class="fa fa-info-circle mt-1 mr-2"></i>
|
|
<div>
|
|
<strong>Instruksi Penerimaan:</strong>
|
|
<ul class="mb-0 mt-2">
|
|
<li>Periksa kondisi fisik produk yang diterima</li>
|
|
<li>Masukkan quantity yang benar-benar diterima untuk setiap produk</li>
|
|
<li>Quantity yang disetujui tidak boleh melebihi quantity yang diminta</li>
|
|
<li>Berikan catatan jika ada produk yang rusak atau tidak sesuai</li>
|
|
</ul>
|
|
<div class="mt-2 p-2 rounded">
|
|
<small><strong>Perhatian:</strong> Setelah diterima, catatan tidak dapat diubah lagi. Pastikan informasi sudah benar sebelum menerima mutasi.</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
} else if (isReceived) {
|
|
detailHtml += `
|
|
<div class="alert alert-success mb-0">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fa fa-check-circle mr-2"></i>
|
|
<div>
|
|
<strong>Status:</strong> Mutasi telah diterima dan menunggu persetujuan admin.
|
|
<br><small>Stock akan dipindahkan setelah admin menyetujui mutasi ini.</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
$('#mutationDetailContent').html(detailHtml);
|
|
|
|
// Show receive button only if mutation can be received
|
|
if (canBeReceived && !isReceived) {
|
|
$('#receiveButton').show();
|
|
} else {
|
|
$('#receiveButton').hide();
|
|
}
|
|
|
|
// Add validation for quantity inputs (only for editable fields)
|
|
$('.quantity-approved-input').on('input', function() {
|
|
var value = parseFloat($(this).val()) || 0;
|
|
var max = parseFloat($(this).data('max')) || 0;
|
|
|
|
if (value > max) {
|
|
$(this).addClass('is-invalid');
|
|
if (!$(this).siblings('.invalid-feedback').length) {
|
|
$(this).after('<div class="invalid-feedback">Quantity tidak boleh melebihi quantity yang diminta</div>');
|
|
}
|
|
} else {
|
|
$(this).removeClass('is-invalid');
|
|
$(this).siblings('.invalid-feedback').remove();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Handle receive form submission
|
|
$('#receiveMutationForm').on('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
// Validate form
|
|
var hasInvalidInput = $('.quantity-approved-input.is-invalid').length > 0;
|
|
if (hasInvalidInput) {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Validasi Gagal',
|
|
text: 'Perbaiki quantity yang tidak valid sebelum melanjutkan'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Check if at least one product has quantity approved > 0
|
|
var hasApprovedQuantity = false;
|
|
$('.quantity-approved-input').each(function() {
|
|
if (parseFloat($(this).val()) > 0) {
|
|
hasApprovedQuantity = true;
|
|
return false; // break loop
|
|
}
|
|
});
|
|
|
|
if (!hasApprovedQuantity) {
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Peringatan',
|
|
text: 'Minimal satu produk harus memiliki quantity yang disetujui'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire({
|
|
title: 'Konfirmasi Penerimaan Mutasi',
|
|
html: `
|
|
<div class="text-left">
|
|
<p class="mb-3">Dengan menerima mutasi ini:</p>
|
|
<ul class="text-muted mb-3" style="font-size: 14px;">
|
|
<li>Anda mengkonfirmasi telah menerima produk dari dealer pengirim</li>
|
|
<li>Data quantity dan catatan yang dimasukkan akan disimpan</li>
|
|
<li>Mutasi akan masuk ke tahap persetujuan untuk memindahkan stock</li>
|
|
<li>Catatan dan data penerimaan tidak dapat diubah setelah diterima</li>
|
|
</ul>
|
|
<div class="alert alert-info">
|
|
<i class="fa fa-info-circle mr-2"></i>
|
|
<small><strong>Info:</strong> Pastikan semua data sudah benar sebelum menerima mutasi.</small>
|
|
</div>
|
|
</div>
|
|
`,
|
|
icon: 'question',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#28a745',
|
|
cancelButtonColor: '#6c757d',
|
|
confirmButtonText: 'Ya, Terima Mutasi',
|
|
cancelButtonText: 'Batal',
|
|
width: '500px'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
// Set loading state
|
|
$('#receiveButton').prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Memproses...');
|
|
|
|
// Submit form
|
|
this.submit();
|
|
}
|
|
});
|
|
} else {
|
|
if (confirm('Terima mutasi dengan data yang telah dimasukkan?')) {
|
|
$('#receiveButton').prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Memproses...');
|
|
this.submit();
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// Functions for claim transactions
|
|
function viewTransaction(transactionId) {
|
|
// Show transaction detail modal
|
|
Swal.fire({
|
|
title: 'Detail Transaksi',
|
|
html: '<div class="text-center"><i class="fa fa-spinner fa-spin fa-2x"></i><p class="mt-2">Memuat data...</p></div>',
|
|
showConfirmButton: false,
|
|
allowOutsideClick: false
|
|
});
|
|
|
|
// Load transaction detail via AJAX
|
|
$.ajax({
|
|
url: '{{ route("transaction.edit", ":id") }}'.replace(':id', transactionId),
|
|
method: 'GET',
|
|
success: function(response) {
|
|
if (response.status === 200) {
|
|
var transaction = response.data;
|
|
Swal.fire({
|
|
title: 'Detail Transaksi',
|
|
html: `
|
|
<div class="text-left">
|
|
<div class="row mb-2">
|
|
<div class="col-6"><strong>No. SPK:</strong></div>
|
|
<div class="col-6">${transaction.spk}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-6"><strong>No. Polisi:</strong></div>
|
|
<div class="col-6">${transaction.police_number}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-6"><strong>Tanggal:</strong></div>
|
|
<div class="col-6">${transaction.date}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-6"><strong>Quantity:</strong></div>
|
|
<div class="col-6">${transaction.qty}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-6"><strong>Warranty:</strong></div>
|
|
<div class="col-6">${transaction.warranty == 1 ? 'Ya' : 'Tidak'}</div>
|
|
</div>
|
|
</div>
|
|
`,
|
|
confirmButtonText: 'Tutup'
|
|
});
|
|
} else {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Error',
|
|
text: 'Gagal memuat detail transaksi'
|
|
});
|
|
}
|
|
},
|
|
error: function() {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Error',
|
|
text: 'Terjadi kesalahan saat memuat data'
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function editTransaction(transactionId) {
|
|
// Redirect to edit page or show edit modal
|
|
window.location.href = '{{ route("transaction.edit", ":id") }}'.replace(':id', transactionId);
|
|
}
|
|
|
|
function deleteTransaction(transactionId) {
|
|
Swal.fire({
|
|
title: 'Konfirmasi Hapus',
|
|
text: 'Apakah Anda yakin ingin menghapus transaksi ini?',
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#d33',
|
|
cancelButtonColor: '#3085d6',
|
|
confirmButtonText: 'Ya, Hapus!',
|
|
cancelButtonText: 'Batal'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
// Send delete request
|
|
$.ajax({
|
|
url: '{{ route("transaction.destroy", ":id") }}'.replace(':id', transactionId),
|
|
method: 'DELETE',
|
|
data: {
|
|
_token: '{{ csrf_token() }}'
|
|
},
|
|
success: function(response) {
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Berhasil!',
|
|
text: 'Transaksi berhasil dihapus',
|
|
timer: 2000,
|
|
showConfirmButton: false
|
|
}).then(() => {
|
|
// Refresh the table
|
|
if (claimTransactionsTable) {
|
|
claimTransactionsTable.ajax.reload();
|
|
}
|
|
});
|
|
},
|
|
error: function() {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Error',
|
|
text: 'Gagal menghapus transaksi'
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function claimTransaction(transactionId) {
|
|
Swal.fire({
|
|
title: 'Konfirmasi Klaim',
|
|
text: 'Apakah Anda yakin ingin mengklaim pekerjaan ini?',
|
|
icon: 'question',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#28a745',
|
|
cancelButtonColor: '#6c757d',
|
|
confirmButtonText: 'Ya, Klaim!',
|
|
cancelButtonText: 'Batal'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
// Send claim request
|
|
$.ajax({
|
|
url: '{{ route("transaction.claim", ":id") }}'.replace(':id', transactionId),
|
|
method: 'POST',
|
|
data: {
|
|
_token: '{{ csrf_token() }}'
|
|
},
|
|
success: function(response) {
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Berhasil!',
|
|
text: 'Pekerjaan berhasil diklaim',
|
|
timer: 2000,
|
|
showConfirmButton: false
|
|
}).then(() => {
|
|
// Refresh the table
|
|
if (claimTransactionsTable) {
|
|
claimTransactionsTable.ajax.reload();
|
|
}
|
|
// Refresh KPI progress bar
|
|
refreshKpiProgress();
|
|
});
|
|
},
|
|
error: function() {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Error',
|
|
text: 'Gagal mengklaim pekerjaan'
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Function to refresh KPI progress bar
|
|
function refreshKpiProgress() {
|
|
$.ajax({
|
|
url: '{{ route("transaction.get-kpi-data") }}',
|
|
method: 'GET',
|
|
success: function(response) {
|
|
if (response.success) {
|
|
var kpiData = response.data;
|
|
|
|
// Update target value using ID
|
|
$('#kpi-target').text(kpiData.target + ' Pekerjaan');
|
|
|
|
// Update actual value using ID and update class for color
|
|
$('#kpi-actual').text(kpiData.actual + ' Pekerjaan').removeClass().addClass('text-' + kpiData.status_color);
|
|
|
|
// Update percentage using ID and update class for color
|
|
$('#kpi-percentage').text(kpiData.percentage + '%').removeClass().addClass('text-' + kpiData.status_color + ' font-weight-bold');
|
|
|
|
// Update progress bar
|
|
var progressWidth = Math.min(100, kpiData.percentage);
|
|
$('.progress-bar').css('width', progressWidth + '%');
|
|
$('.progress-bar').attr('aria-valuenow', kpiData.percentage);
|
|
$('.progress-bar').removeClass().addClass('progress-bar bg-' + kpiData.status_color);
|
|
|
|
// Update status message
|
|
var statusMessage = '';
|
|
if (kpiData.status === 'exceeded') {
|
|
statusMessage = '<small class="text-success"><i class="fa fa-check-circle"></i> Target tercapai!</small>';
|
|
} else if (kpiData.status === 'good') {
|
|
statusMessage = '<small class="text-info"><i class="fa fa-arrow-up"></i> Performa baik</small>';
|
|
} else if (kpiData.status === 'fair') {
|
|
statusMessage = '<small class="text-warning"><i class="fa fa-exclamation-triangle"></i> Perlu peningkatan</small>';
|
|
} else if (kpiData.status === 'poor') {
|
|
statusMessage = '<small class="text-danger"><i class="fa fa-times-circle"></i> Perlu perbaikan</small>';
|
|
} else {
|
|
statusMessage = '<small class="text-secondary"><i class="fa fa-clock"></i> Belum ada data</small>';
|
|
}
|
|
$('.mt-1').html(statusMessage);
|
|
|
|
console.log('KPI Data updated:', kpiData);
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.log('Failed to refresh KPI data:', error);
|
|
console.log('Response:', xhr.responseText);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Note: Approve and reject buttons removed from transaction page
|
|
// These actions are now only available to admin users in the admin panel
|
|
|
|
// Handle main tab switching properly (only for main tabs)
|
|
$('.nav-tabs-line-primary .nav-link').on('click', function(e) {
|
|
e.preventDefault();
|
|
var target = $(this).attr('href');
|
|
if (target) {
|
|
// Handle main tab switching
|
|
if (target === '#transaksi' || target === '#stock') {
|
|
// Remove active from all main tabs and tab panes
|
|
$('.nav-tabs-line-primary .nav-link').removeClass('active');
|
|
$('#transaksi, #stock').removeClass('active');
|
|
|
|
// Add active to clicked main tab
|
|
$(this).addClass('active');
|
|
$(target).addClass('active');
|
|
|
|
// Handle sub-tab activation based on main tab
|
|
if (target === '#transaksi') {
|
|
// Remove active from all stock sub-tabs
|
|
$('.nav-link[href="#opname"], .nav-link[href="#mutasi"], .nav-link[href="#penerimaan"]').removeClass('active');
|
|
$('#opname, #mutasi, #penerimaan').removeClass('active');
|
|
|
|
// Always activate form-kerja by default when switching to transaksi tab
|
|
$('.nav-link[href="#form-kerja"]').addClass('active');
|
|
$('#form-kerja').addClass('active');
|
|
} else if (target === '#stock') {
|
|
// Remove active from all transaksi sub-tabs
|
|
$('.nav-link[href="#form-kerja"], .nav-link[href="#form-cuci"], .nav-link[href="#form-claim"]').removeClass('active');
|
|
$('#form-kerja, #form-cuci, #form-claim').removeClass('active');
|
|
|
|
// Always activate opname by default when switching to stock tab
|
|
$('.nav-link[href="#opname"]').addClass('active');
|
|
$('#opname').addClass('active');
|
|
setTimeout(function() {
|
|
updateProductCounter();
|
|
}, 50);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
function createTransaction(form) {
|
|
let work_ids;
|
|
if(form == 'work') {
|
|
work_ids = $(`select[name='${form}_work_id[]']`).map(function (idx, elem) {
|
|
return $(elem).val();
|
|
}).get();
|
|
}
|
|
|
|
if(form == 'wash') {
|
|
work_ids = $(`input[name='${form}_work_id[]']`).map(function (idx, elem) {
|
|
return $(elem).val();
|
|
}).get();
|
|
}
|
|
|
|
let quantities = $(`input[name='${form}_quantity[]']`).map(function (idx, elem) {
|
|
return $(elem).val();
|
|
}).get();
|
|
|
|
let datas = [];
|
|
for(let i = 0; i < work_ids.length; i++) {
|
|
const data = {
|
|
user_id : $("input[name='mechanic_id']").val(),
|
|
dealer_id : $("input[name='dealer_id']").val(),
|
|
form : form,
|
|
work_id : work_ids[i],
|
|
qty : quantities[i],
|
|
spk : $(`input[name='${form}_spk_no']`).val(),
|
|
police_number : $(`input[name='${form}_police_number']`).val(),
|
|
qtys : $(`input[name='${form}_quantity']`).val(),
|
|
warranty : $(`select[name='${form}_warranty']`).val(),
|
|
user_sa_id : $(`select[name='${form}_user_sa_id']`).val(),
|
|
date : $(`input[name='${form}_date']`).val(),
|
|
}
|
|
datas.push(data)
|
|
}
|
|
|
|
$.ajax({
|
|
url: $(`#${form}Form`).attr("action"),
|
|
type: "POST",
|
|
data: {
|
|
data : datas
|
|
},
|
|
success: function(res) {
|
|
document.location.reload()
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure transaksi tab is shown by default
|
|
$(document).ready(function() {
|
|
// First, ensure all tabs are properly hidden
|
|
$('#transaksi, #stock').removeClass('active');
|
|
$('.nav-tabs-line-primary .nav-link').removeClass('active');
|
|
|
|
// Check if we have specific form values from old input
|
|
@if(old('form'))
|
|
var oldForm = '{{ old("form") }}';
|
|
|
|
if (oldForm === 'work' || oldForm === 'wash' || oldForm === 'claim') {
|
|
// Activate transaksi tab and specific sub-tab
|
|
$('.nav-link[href="#transaksi"]').addClass('active');
|
|
$('#transaksi').addClass('active');
|
|
|
|
// Remove any active stock sub-tabs
|
|
$('.nav-link[href="#opname"], .nav-link[href="#mutasi"], .nav-link[href="#penerimaan"]').removeClass('active');
|
|
$('#opname, #mutasi, #penerimaan').removeClass('active');
|
|
|
|
if (oldForm === 'work') {
|
|
$('.nav-link[href="#form-kerja"]').addClass('active');
|
|
$('#form-kerja').addClass('active');
|
|
} else if (oldForm === 'wash') {
|
|
$('.nav-link[href="#form-cuci"]').addClass('active');
|
|
$('#form-cuci').addClass('active');
|
|
} else if (oldForm === 'claim') {
|
|
$('.nav-link[href="#form-claim"]').addClass('active');
|
|
$('#form-claim').addClass('active');
|
|
}
|
|
} else if (oldForm === 'opname' || oldForm === 'mutasi' || oldForm === 'penerimaan') {
|
|
// Activate stock tab and specific sub-tab
|
|
$('.nav-link[href="#stock"]').addClass('active');
|
|
$('#stock').addClass('active');
|
|
|
|
// Remove any active transaksi sub-tabs
|
|
$('.nav-link[href="#form-kerja"], .nav-link[href="#form-cuci"], .nav-link[href="#form-claim"]').removeClass('active');
|
|
$('#form-kerja, #form-cuci, #form-claim').removeClass('active');
|
|
|
|
if (oldForm === 'opname') {
|
|
$('.nav-link[href="#opname"]').addClass('active');
|
|
$('#opname').addClass('active');
|
|
updateProductCounter();
|
|
} else if (oldForm === 'mutasi') {
|
|
$('.nav-link[href="#mutasi"]').addClass('active');
|
|
$('#mutasi').addClass('active');
|
|
} else if (oldForm === 'penerimaan') {
|
|
$('.nav-link[href="#penerimaan"]').addClass('active');
|
|
$('#penerimaan').addClass('active');
|
|
}
|
|
}
|
|
@else
|
|
// If no tab is active, activate transaksi tab by default
|
|
$('.nav-link[href="#transaksi"]').addClass('active');
|
|
$('#transaksi').addClass('active');
|
|
|
|
// Activate form-kerja by default in transaksi tab
|
|
$('.nav-link[href="#form-kerja"]').addClass('active');
|
|
$('#form-kerja').addClass('active');
|
|
@endif
|
|
|
|
// Ensure at least one main tab is active
|
|
if (!$('.nav-tabs-line-primary .nav-link.active').length) {
|
|
$('.nav-link[href="#transaksi"]').addClass('active');
|
|
$('#transaksi').addClass('active');
|
|
|
|
// Ensure at least one sub-tab is active in transaksi
|
|
if (!$('#transaksi .tab-content .tab-pane.active').length) {
|
|
$('.nav-link[href="#form-kerja"]').addClass('active');
|
|
$('#form-kerja').addClass('active');
|
|
}
|
|
}
|
|
|
|
// Initialize components based on active tabs
|
|
if ($('#opname').hasClass('active') || $('#stock').hasClass('active')) {
|
|
updateProductCounter();
|
|
}
|
|
|
|
if ($('#mutasi').hasClass('active')) {
|
|
setTimeout(function() {
|
|
initMutasiSelect2();
|
|
updateRemoveButtonsMutasi();
|
|
}, 100);
|
|
}
|
|
|
|
if ($('#penerimaan').hasClass('active')) {
|
|
setTimeout(function() {
|
|
initReceiveMutationsTable();
|
|
}, 100);
|
|
}
|
|
|
|
if ($('#form-claim').hasClass('active')) {
|
|
setTimeout(function() {
|
|
initClaimTransactionsTable();
|
|
}, 100);
|
|
}
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Handle sub-tab switching for transaksi tabs
|
|
$('#transaksi .nav-tabs-line-success .nav-link').on('click', function(e) {
|
|
e.preventDefault();
|
|
var target = $(this).attr('href');
|
|
|
|
// Remove active from all transaksi sub-tabs
|
|
$('#transaksi .nav-tabs-line-success .nav-link').removeClass('active');
|
|
$('#transaksi .tab-content .tab-pane').removeClass('active');
|
|
|
|
// Add active to clicked sub-tab
|
|
$(this).addClass('active');
|
|
$(target).addClass('active');
|
|
|
|
// Initialize components based on which sub-tab is shown
|
|
if (target === '#form-claim') {
|
|
setTimeout(function() {
|
|
initClaimTransactionsTable();
|
|
}, 100);
|
|
}
|
|
});
|
|
|
|
// Handle sub-tab switching for stock tabs
|
|
$('#stock .nav-tabs-line-success .nav-link').on('click', function(e) {
|
|
e.preventDefault();
|
|
var target = $(this).attr('href');
|
|
|
|
// Remove active from all stock sub-tabs
|
|
$('#stock .nav-tabs-line-success .nav-link').removeClass('active');
|
|
$('#stock .tab-content .tab-pane').removeClass('active');
|
|
|
|
// Add active to clicked sub-tab
|
|
$(this).addClass('active');
|
|
$(target).addClass('active');
|
|
|
|
// Initialize components based on which sub-tab is shown
|
|
if (target === '#opname') {
|
|
updateProductCounter();
|
|
} else if (target === '#mutasi') {
|
|
setTimeout(function() {
|
|
initMutasiSelect2();
|
|
updateRemoveButtonsMutasi();
|
|
}, 100);
|
|
} else if (target === '#penerimaan') {
|
|
setTimeout(function() {
|
|
initReceiveMutationsTable();
|
|
}, 100);
|
|
}
|
|
});
|
|
</script>
|
|
@endsection |