1134 lines
60 KiB
PHP
1134 lines
60 KiB
PHP
@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: 400px;
|
|
overflow-y: auto;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
}
|
|
.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);
|
|
}
|
|
.physical-stock.is-invalid {
|
|
border-color: #dc3545;
|
|
background-color: #fff5f5;
|
|
}
|
|
.physical-stock.is-invalid:focus {
|
|
border-color: #dc3545;
|
|
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
|
|
}
|
|
</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>
|
|
</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>
|
|
@if (session('success'))
|
|
<div class="row mt-2 mb-2">
|
|
<div class="col-12">
|
|
<div class="alert alert—check alert-success fade show" role="alert">
|
|
<div class="alert-text">{{ session('success') }}</div>
|
|
<div class="alert-close">
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true"><i class="la la-close"></i></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
@if (session('error'))
|
|
<div class="row mt-2 mb-2">
|
|
<div class="col-12">
|
|
<div class="alert alert-danger fade show" role="alert">
|
|
<div class="alert-text">{{ session('error') }}</div>
|
|
<div class="alert-close">
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true"><i class="la la-close"></i></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
<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" data-toggle="tab" href="#transaksi">Transaksi</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-toggle="tab" 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') == 'wash') @else active @endif" data-toggle="tab" href="#form-kerja">Form Kerja</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link @if(old('form') == 'wash') active @endif" data-toggle="tab" href="#form-cuci">Form Cuci</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content mt-3">
|
|
<!-- Form Kerja -->
|
|
<div class="tab-pane @if(old('form') == 'wash') @else active @endif" id="form-kerja" role="tabpanel">
|
|
<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 }}">
|
|
<div class="form-group row">
|
|
<div class="col-6">
|
|
<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">
|
|
|
|
@if(old('form') == 'work')
|
|
@error('spk_no')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
<div class="col-6">
|
|
<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">
|
|
@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">
|
|
<select name="warranty" class="form-control @if(old('form') == 'work') @error('warranty') is-invalid @enderror @endif">
|
|
<option selected>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">
|
|
<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">
|
|
<select name="user_sa_id" class="form-control @if(old('form') == 'work') @error('user_sa_id') is-invalid @enderror @endif">
|
|
<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 selected 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 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 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 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 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 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="addFormField('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">
|
|
<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">
|
|
@if(old('form') == 'wash')
|
|
@error('spk_no')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
@endif
|
|
</div>
|
|
<div class="col-6">
|
|
<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">
|
|
@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">
|
|
<select name="warranty" class="form-control @if(old('form') == 'wash') @error('warranty') is-invalid @enderror @endif">
|
|
<option selected>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>
|
|
@error('warranty')
|
|
<span class="invalid-feedback" role="alert">
|
|
<strong>{!! $message !!}</strong>
|
|
</span>
|
|
@enderror
|
|
</div>
|
|
<div class="col-6">
|
|
<input type="text" id="date-wash" name="date" class="form-control @if(old('form') == 'wash') @error('date') is-invalid @enderror @endif" placeholder="Tanggal Pekerjaan">
|
|
@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">
|
|
<select name="user_sa_id" class="form-control @if(old('form') == 'wash') @error('user_sa_id') is-invalid @enderror @endif">
|
|
<option 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>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab Stock -->
|
|
<div class="tab-pane" id="stock" role="tabpanel">
|
|
<!-- Sub Tabs untuk Stock -->
|
|
<ul class="nav nav-tabs nav-tabs-line nav-tabs-line-warning mt-3" role="tablist">
|
|
<li class="nav-item">
|
|
<a class="nav-link active" data-toggle="tab" href="#opname">Opname</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-toggle="tab" href="#mutasi">Mutasi</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content mt-3">
|
|
<!-- Form Opname -->
|
|
<div class="tab-pane active" 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 @error('opname_date') is-invalid @enderror" value="{{ old('opname_date', date('Y-m-d')) }}" placeholder="YYYY-MM-DD">
|
|
@error('opname_date')
|
|
<div class="invalid-feedback">
|
|
{{ $message }}
|
|
</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Keterangan</label>
|
|
<textarea name="description" class="form-control @error('description') is-invalid @enderror" rows="3" placeholder="Keterangan opname">{{ old('description') }}</textarea>
|
|
@error('description')
|
|
<div class="invalid-feedback">
|
|
{{ $message }}
|
|
</div>
|
|
@enderror
|
|
</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 Sistem</th>
|
|
<th class="text-center">Stock Fisik</th>
|
|
<th class="text-center">Selisih</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 class="text-center">
|
|
<span class="system-stock">{{ number_format($currentStock, 2) }}</span>
|
|
<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 }}">
|
|
</td>
|
|
<td>
|
|
<input type="number" class="form-control physical-stock @error('physical_stock.'.$loop->index) is-invalid @enderror" name="physical_stock[]" step="0.01" placeholder="0.00" data-system="{{ $currentStock }}" value="{{ old('physical_stock.'.$loop->index) }}">
|
|
@error('physical_stock.'.$loop->index)
|
|
<div class="invalid-feedback">
|
|
{{ $message }}
|
|
</div>
|
|
@enderror
|
|
</td>
|
|
<td class="text-center">
|
|
<span class="difference text-bold">0.00</span>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="mt-4 mb-3">
|
|
<button class="btn btn-warning btn-lg button-save d-block w-100 mt-2">
|
|
Simpan Opname
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Form Mutasi -->
|
|
<div class="tab-pane" id="mutasi" role="tabpanel">
|
|
<form action="#" method="POST" id="mutasiForm">
|
|
@csrf
|
|
<input type="hidden" name="form" value="mutasi">
|
|
<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>Tanggal Mutasi</label>
|
|
<input type="text" name="mutasi_date" id="date-mutasi" class="form-control" placeholder="Tanggal Mutasi" required>
|
|
</div>
|
|
<div class="col-6">
|
|
<label>Jenis Mutasi</label>
|
|
<select name="mutasi_type" class="form-control" required>
|
|
<option value="">Pilih Jenis</option>
|
|
<option value="masuk">Barang Masuk</option>
|
|
<option value="keluar">Barang Keluar</option>
|
|
<option value="transfer">Transfer</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Keterangan</label>
|
|
<textarea name="description" class="form-control" rows="3" placeholder="Keterangan mutasi"></textarea>
|
|
</div>
|
|
|
|
<!-- List Produk untuk Mutasi -->
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th width="5%">
|
|
<input type="checkbox" id="select-all-mutasi">
|
|
</th>
|
|
<th>Produk</th>
|
|
<th>Stock Saat Ini</th>
|
|
<th>Jumlah Mutasi</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>
|
|
<input type="checkbox" class="mutasi-product-checkbox" name="selected_products[]" value="{{ $product->id }}_{{ $mechanic->dealer_id }}">
|
|
</td>
|
|
<td>{{ $product->name }}</td>
|
|
<td class="text-right">{{ number_format($currentStock, 2) }}</td>
|
|
<td>
|
|
<input type="number" class="form-control mutasi-quantity" name="mutasi_quantity[{{ $product->id }}_{{ $mechanic->dealer_id }}]" step="0.01" placeholder="0.00" disabled>
|
|
<input type="hidden" name="product_id_mutasi[]" value="{{ $product->id }}">
|
|
<input type="hidden" name="dealer_id_mutasi[]" value="{{ $mechanic->dealer_id }}">
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="mt-4 mb-3">
|
|
<button class="btn btn-warning btn-lg button-save d-block w-100 mt-2">
|
|
Simpan Mutasi
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</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>
|
|
@endsection
|
|
|
|
@section('javascripts')
|
|
<script>
|
|
$.ajaxSetup({
|
|
headers: {
|
|
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
|
}
|
|
});
|
|
|
|
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) {
|
|
$.each(res.data, function (i, item) {
|
|
$(`#${form}_work${id}`).append($('<option>', {
|
|
value: item.id,
|
|
text : item.name
|
|
}));
|
|
});
|
|
})
|
|
}
|
|
|
|
$("#workForm").submit(function(e) {
|
|
$(".button-save").attr("disabled");
|
|
$(".button-save").addClass("disabled");
|
|
return true;
|
|
})
|
|
|
|
$("#washForm").submit(function(e) {
|
|
$(".button-save").attr("disabled");
|
|
$(".button-save").addClass("disabled");
|
|
return true;
|
|
})
|
|
|
|
$("#opnameForm").submit(function(e) {
|
|
e.preventDefault();
|
|
|
|
// Validate form
|
|
var hasValidStock = false;
|
|
var invalidRows = [];
|
|
|
|
$('.physical-stock').each(function(index) {
|
|
var value = $(this).val();
|
|
var row = $(this).closest('tr');
|
|
var productName = row.find('td:first').text().trim();
|
|
|
|
// Check if value is valid (including 0)
|
|
if (value !== '' && value !== null && value !== undefined) {
|
|
var numValue = parseFloat(value);
|
|
if (!isNaN(numValue) && numValue >= 0) {
|
|
hasValidStock = true;
|
|
// Ensure the value is properly formatted
|
|
$(this).val(numValue.toFixed(2));
|
|
} else {
|
|
invalidRows.push(productName + ' (nilai tidak valid)');
|
|
}
|
|
}
|
|
// Don't remove elements here - let them stay for re-editing
|
|
});
|
|
|
|
// Show error if no valid stock entries
|
|
if (!hasValidStock) {
|
|
resetSubmitButton();
|
|
highlightInvalidFields();
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Peringatan',
|
|
text: 'Minimal harus ada satu produk dengan stock fisik yang diisi dengan benar!'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Show error if there are invalid entries
|
|
if (invalidRows.length > 0) {
|
|
resetSubmitButton();
|
|
highlightInvalidFields();
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Data Tidak Valid',
|
|
text: 'Perbaiki data berikut: ' + invalidRows.join(', ')
|
|
});
|
|
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;
|
|
}
|
|
|
|
$(".button-save").attr("disabled", true);
|
|
$(".button-save").addClass("disabled");
|
|
$(".button-save").html('<i class="fa fa-spinner fa-spin"></i> Menyimpan...');
|
|
|
|
// Date format is already YYYY-MM-DD, no conversion needed
|
|
|
|
// Clean up empty rows before submit (remove hidden inputs for truly empty fields only)
|
|
$('.physical-stock').each(function() {
|
|
var value = $(this).val();
|
|
var row = $(this).closest('tr');
|
|
|
|
// Only remove hidden inputs if physical stock is truly empty (not 0)
|
|
// Keep 0 values as they are valid input
|
|
if (value === '' || value === null || value === undefined) {
|
|
row.find('input[name="product_id[]"]').remove();
|
|
row.find('input[name="dealer_id_stock[]"]').remove();
|
|
row.find('input[name="system_stock[]"]').remove();
|
|
// But keep the physical_stock input so it can be re-edited if form fails
|
|
}
|
|
});
|
|
|
|
// Submit form
|
|
this.submit();
|
|
})
|
|
|
|
$("#mutasiForm").submit(function(e) {
|
|
$(".button-save").attr("disabled");
|
|
$(".button-save").addClass("disabled");
|
|
return true;
|
|
})
|
|
|
|
$("#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 filledProducts = 0;
|
|
var totalProducts = $('.physical-stock').length;
|
|
|
|
$('.physical-stock').each(function() {
|
|
var value = $(this).val();
|
|
// Count as filled if it's a valid number (including 0)
|
|
if (value !== '' && value !== null && value !== undefined && !isNaN(parseFloat(value)) && parseFloat(value) >= 0) {
|
|
filledProducts++;
|
|
}
|
|
});
|
|
|
|
// Update button text to show progress
|
|
var buttonText = 'Simpan Opname';
|
|
if (filledProducts > 0) {
|
|
buttonText += ` (${filledProducts}/${totalProducts} produk)`;
|
|
}
|
|
|
|
if (!$('.button-save').hasClass('disabled')) {
|
|
$('.button-save').html(buttonText);
|
|
}
|
|
}
|
|
|
|
// Handle when input loses focus - don't auto-fill, let user decide
|
|
$(document).on('blur', '.physical-stock', function() {
|
|
// Trigger calculation even for empty values
|
|
$(this).trigger('input');
|
|
});
|
|
|
|
// Function to reset button state if validation fails
|
|
function resetSubmitButton() {
|
|
$(".button-save").attr("disabled", false);
|
|
$(".button-save").removeClass("disabled");
|
|
updateProductCounter(); // Update with current counter
|
|
}
|
|
|
|
// Function to show field error highlighting
|
|
function highlightInvalidFields() {
|
|
$('.physical-stock').each(function() {
|
|
var value = $(this).val();
|
|
var $input = $(this);
|
|
|
|
if (value !== '' && value !== null && value !== undefined) {
|
|
var numValue = parseFloat(value);
|
|
if (isNaN(numValue) || numValue < 0) {
|
|
$input.addClass('is-invalid');
|
|
} else {
|
|
$input.removeClass('is-invalid');
|
|
}
|
|
} else {
|
|
$input.removeClass('is-invalid');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Remove error styling when user starts typing
|
|
$(document).on('input', '.physical-stock', 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);
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// Auto-dismiss alerts after 5 seconds
|
|
setTimeout(function() {
|
|
$('.alert').fadeOut('slow');
|
|
}, 5000);
|
|
});
|
|
|
|
// 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 product selection
|
|
$(document).on('change', '.mutasi-product-checkbox', function() {
|
|
var quantityInput = $(this).closest('tr').find('.mutasi-quantity');
|
|
if ($(this).is(':checked')) {
|
|
quantityInput.prop('disabled', false);
|
|
} else {
|
|
quantityInput.prop('disabled', true).val('');
|
|
}
|
|
});
|
|
|
|
// Select all mutasi products
|
|
$('#select-all-mutasi').change(function() {
|
|
$('.mutasi-product-checkbox').prop('checked', this.checked).trigger('change');
|
|
});
|
|
|
|
|
|
|
|
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()
|
|
}
|
|
})
|
|
}
|
|
|
|
</script>
|
|
@endsection |