update qrmaster
This commit is contained in:
parent
11e8e84064
commit
18ecaedda8
File diff suppressed because it is too large
Load Diff
@ -93,6 +93,68 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="approveModal" tabindex="-1" role="dialog" aria-labelledby="approveRequestModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="approveRequestModalLabel">Approve Request</h5>
|
||||||
|
<button type="button" class="closeModal" data-dismiss="modal" aria-label="Close" v-on:click="showRequestModal=false">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<form v-on:submit.prevent="approveRequest" data-aos="fade-right">
|
||||||
|
@* <div class=" register" data-aos="fade-right"> *@
|
||||||
|
<div data-aos="fade-right">
|
||||||
|
<div class="row" data-aos="fade-right">
|
||||||
|
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="tab-content" id="myTabContent">
|
||||||
|
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
|
||||||
|
<h3 class="register-heading">APPROVE REQUEST</h3>
|
||||||
|
<div class="row register-form">
|
||||||
|
<div class="col-md-12">
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
@* <label class="col-sm-4 col-form-label hidden-label">Request Id</label> *@
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="dropdown">
|
||||||
|
<input type="text" id="currentRequestId" name="currentRequestId" v-model="currentRequestId" class="form-control" hidden />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">Remark</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="dropdown">
|
||||||
|
<input type="text" id="approveremark" name="approveremark" v-model="approveremark" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@* Submit and Reset Buttons *@
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-sm-8 offset-sm-3">
|
||||||
|
<button type="button" v-on:click="resetForm" class="btn btn-secondary m-1">Reset</button>
|
||||||
|
<button type="submit" class="btn btn-primary m-1 submit-button">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
@ -113,8 +175,9 @@
|
|||||||
$('.modal').modal('hide');
|
$('.modal').modal('hide');
|
||||||
});
|
});
|
||||||
$('.submit-button').on('click', function () {
|
$('.submit-button').on('click', function () {
|
||||||
// Show the modal
|
// Show the modal
|
||||||
$('#rejectModal').modal('hide');
|
$('#rejectModal').modal('hide');
|
||||||
|
$('#approveModal').modal('hide');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const app = Vue.createApp({
|
const app = Vue.createApp({
|
||||||
@ -139,6 +202,7 @@
|
|||||||
selectedCategory: "",
|
selectedCategory: "",
|
||||||
showRequestModal: false,
|
showRequestModal: false,
|
||||||
showRejectModal: false,
|
showRejectModal: false,
|
||||||
|
showApproveModal: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
request: [],
|
request: [],
|
||||||
currentUser: null,
|
currentUser: null,
|
||||||
@ -447,7 +511,7 @@
|
|||||||
|
|
||||||
$('#requestDatatable tbody').on('click', '.approve-btn', function () {
|
$('#requestDatatable tbody').on('click', '.approve-btn', function () {
|
||||||
const requestId = $(this).data('id');
|
const requestId = $(this).data('id');
|
||||||
self.approveRequest(requestId);
|
self.approveRequestModal(requestId);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#requestDatatable tbody').on('click', '.print-btn', function () {
|
$('#requestDatatable tbody').on('click', '.print-btn', function () {
|
||||||
@ -665,16 +729,25 @@
|
|||||||
this.EndWDate = null;
|
this.EndWDate = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async approveRequest(itemId) {
|
async approveRequest() {
|
||||||
// if (!confirm("Are you sure you want to approve this request?")) {
|
// if (!confirm("Are you sure you want to approve this request?")) {
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
const formData = {
|
||||||
|
RemarkMasterInv: this.rejectremark,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
let requestId = this.currentRequestId;
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/InvMainAPI/ApproveRequest/${itemId}`, {
|
const response = await fetch(`/InvMainAPI/ApproveRequest/${requestId}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
|
body: JSON.stringify(formData)
|
||||||
|
|
||||||
});
|
});
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
@ -682,7 +755,7 @@
|
|||||||
alert(result.message);
|
alert(result.message);
|
||||||
|
|
||||||
//static update
|
//static update
|
||||||
const row = $(`.approve-btn[data-id="${itemId}"]`).closest('tr');
|
const row = $(`.approve-btn[data-id="${requestId}"]`).closest('tr');
|
||||||
let rowData = this.requestDatatable.row(row).data();
|
let rowData = this.requestDatatable.row(row).data();
|
||||||
|
|
||||||
// Update the status and remark
|
// Update the status and remark
|
||||||
@ -769,6 +842,16 @@
|
|||||||
$(`#rejectModal`).modal('show');
|
$(`#rejectModal`).modal('show');
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
async approveRequestModal(requestId, remark) {
|
||||||
|
|
||||||
|
this.currentRequestId = requestId;
|
||||||
|
this.approveremark = remark;
|
||||||
|
|
||||||
|
|
||||||
|
$(`#approveModal`).modal('show');
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
async printItem(itemId, imgSrc) {
|
async printItem(itemId, imgSrc) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -16,32 +16,51 @@
|
|||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@await Html.PartialAsync("~/Areas/Inventory/Views/_InventoryPartial.cshtml");
|
@await Html.PartialAsync("~/Areas/Inventory/Views/_InventoryPartial.cshtml")
|
||||||
<div id="registerItem" class="row">
|
<div id="registerItemMovement" class="row">
|
||||||
<div class="row card">
|
<div class="row card">
|
||||||
<div v-if="thisItem" class="card-header">
|
<div v-if="thisItem" class="card-header">
|
||||||
<button v-on:click="resetScanner" class="btn btn-secondary">
|
<button v-on:click="resetScanner" class="btn btn-secondary">
|
||||||
<i class="fas fa-arrow-left"></i> Back to Scanner
|
<i class="fas fa-arrow-left"></i> Back to Scanner
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div data-aos="fade-right"></div>
|
<div data-aos="fade-right"></div>
|
||||||
<div id="app" data-aos="fade-right">
|
|
||||||
<div v-if="thisItem == null">
|
<select class="form-select" v-if="!thisItem" v-model="selectedCameraId" v-on:change="updateCamera">
|
||||||
<h1 data-aos="fade-right">QR & Barcode Scanner</h1>
|
<option v-for="device in videoInputDevices" :key="device.deviceId" :value="device.deviceId">
|
||||||
<div id="reader" data-aos="fade-right"></div>
|
{{ device.label || `Camera ${videoInputDevices.indexOf(device) + 1}` }}
|
||||||
</div>
|
</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
<div v-if="thisItem" id="qrCodeResult" style="text-align: center; margin: 20px 0; padding: 20px;">
|
<div id="registerItemMovement" v-if="!thisItem" data-aos="fade-right">
|
||||||
<h2>Scan Result:</h2>
|
<p style="text-align:center; padding:10px;">Scan QR Code Here:</p>
|
||||||
</div>
|
<qrcode-stream :constraints="selectedConstraints"
|
||||||
|
:formats="['qr_code']"
|
||||||
|
:track="trackFunctionSelected.value"
|
||||||
|
v-on:camera-on="onCameraReady"
|
||||||
|
v-on:detect="onDecode"
|
||||||
|
v-on:error="onError">
|
||||||
|
</qrcode-stream>
|
||||||
|
|
||||||
|
<p class="error">{{ error }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div v-if="thisItem" style="display: flex; justify-content: center; align-items: center;">
|
<div v-if="thisItem" style="display: flex; justify-content: center; align-items: center;">
|
||||||
<div class="col-lg-7 col-11 border rounded p-3 shadow-sm">
|
<div class="col-lg-7 col-11 border rounded p-3 shadow-sm">
|
||||||
|
|
||||||
|
<div class="row m-3 d-flex align-items-center justify-content-center">
|
||||||
|
<div class="col-lg-7 col-11 border rounded p-3 shadow-sm">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<img :src="thisItem.imageProduct" alt="Product Image" class="img-fluid rounded" data-toggle="modal" data-target="#imageModal" style="max-height: 300px;" />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 text-center mt-3">
|
||||||
|
<p class="h4 fw-bold text-primary">{{ thisItem.uniqueID }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Item Name -->
|
<!-- Item Name -->
|
||||||
<div class="col-12 mb-3">
|
<div class="col-12 mb-3">
|
||||||
<p class="h5 fw-bold">
|
<p class="h5 fw-bold">
|
||||||
@ -89,7 +108,7 @@
|
|||||||
<i class="fas fa-user me-2 text-secondary"></i>User:
|
<i class="fas fa-user me-2 text-secondary"></i>User:
|
||||||
</span>
|
</span>
|
||||||
<span class="text-muted text-end" style="max-width: 70%; word-wrap: break-word;">
|
<span class="text-muted text-end" style="max-width: 70%; word-wrap: break-word;">
|
||||||
{{ thisItem.currentUser }}
|
{{ thisItem.toUserName }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -97,9 +116,9 @@
|
|||||||
<!-- Store -->
|
<!-- Store -->
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
<span class="fw-bold">
|
<span class="fw-bold">
|
||||||
<i class="fas fa-store me-2 text-secondary"></i>Store:
|
<i class="mdi mdi-factory me-2 text-secondary"></i>Store:
|
||||||
</span>
|
</span>
|
||||||
<span class="text-muted">{{ thisItem.currentStore }}</span>
|
<span class="text-muted">{{ thisItem.toStoreName }}</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- Station -->
|
<!-- Station -->
|
||||||
@ -107,7 +126,7 @@
|
|||||||
<span class="fw-bold">
|
<span class="fw-bold">
|
||||||
<i class="fas fa-map-marker-alt me-2 text-secondary"></i>Station:
|
<i class="fas fa-map-marker-alt me-2 text-secondary"></i>Station:
|
||||||
</span>
|
</span>
|
||||||
<span class="text-muted">{{ thisItem.currentStation || 'N/A' }}</span>
|
<span class="text-muted">{{ thisItem.toStationName || 'N/A' }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -223,7 +242,8 @@
|
|||||||
@* <option class="btn-light" value="store" v-if="itemlateststatus == 'Ready To Deploy'">Assign to Store</option> *@
|
@* <option class="btn-light" value="store" v-if="itemlateststatus == 'Ready To Deploy'">Assign to Store</option> *@
|
||||||
@* <option class="btn-light" value="supplier" v-if="itemlateststatus != 'Delivered'">Assign to Supplier</option> *@
|
@* <option class="btn-light" value="supplier" v-if="itemlateststatus != 'Delivered'">Assign to Supplier</option> *@
|
||||||
@* <option class="btn-light" value="faulty" v-if="itemlateststatus != 'Delivered'">Faulty</option> *@
|
@* <option class="btn-light" value="faulty" v-if="itemlateststatus != 'Delivered'">Faulty</option> *@
|
||||||
<option class="btn-light" value="user" >Assign to User</option>
|
<option class="btn-light" value="user">Assign to User</option>
|
||||||
|
<option class="btn-light" value="station">Assign to Station</option>
|
||||||
<option class="btn-light" value="store">Assign to Store</option>
|
<option class="btn-light" value="store">Assign to Store</option>
|
||||||
<option class="btn-light" value="supplier">Assign to Supplier</option>
|
<option class="btn-light" value="supplier">Assign to Supplier</option>
|
||||||
<option class="btn-light" value="faulty">Faulty</option>
|
<option class="btn-light" value="faulty">Faulty</option>
|
||||||
@ -260,14 +280,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="invoiceDate" class="col-sm-4">Assign Date:</label>
|
<label for="invoiceDate" class="col-sm-4">Assign Date:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input type="date" id="assigndate" name="assigndate" class="form-control" v-model="assigndate">
|
<input type="date" id="assigndate" name="assigndate" class="form-control" v-model="assigndate">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">Consignment Note</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="file" id="document" name="document" class="form-control-file" v-on:change="handleFileUpload" accept="image/png, image/jpeg, application/pdf" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">Remark:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" id="remark" name="remark" v-model="remark" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@* Submit and Reset Buttons *@
|
@* Submit and Reset Buttons *@
|
||||||
@ -281,6 +314,70 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="selectedAction === 'station'">
|
||||||
|
|
||||||
|
<div class="row register-form">
|
||||||
|
<div class="col-md-3"></div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">To Station:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="dropdown">
|
||||||
|
<select class="btn btn-primary dropdown-toggle col-md-10" v-model="selectedStation" v-on:change="handleSelection" required style="width: 100%;">
|
||||||
|
<option class="btn-light" value="" disabled selected>Select Station</option>
|
||||||
|
<option class="btn-light" v-for="(station, index) in stationlist" :key="index" :value="station.stationId">{{station.stationName}}</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">To PIC:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="dropdown">
|
||||||
|
<input type="text" id="selectedStationPIC" name="selectedStationPIC" v-model="selectedStationPIC" class="form-control" readonly />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="invoiceDate" class="col-sm-4">Assign Date:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="date" id="assigndate" name="assigndate" class="form-control" v-model="assigndate">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">Consignment Note</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="file" id="document" name="document" class="form-control-file" v-on:change="handleFileUpload" accept="image/png, image/jpeg, application/pdf" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">Remark:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" id="remark" name="remark" v-model="remark" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@* Submit and Reset Buttons *@
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-sm-8 offset-sm-3">
|
||||||
|
<button type="button" v-on:click="resetForm" class="btn btn-secondary m-1">Reset</button>
|
||||||
|
<button type="submit" class="btn btn-primary m-1">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="selectedAction === 'store'">
|
<div v-if="selectedAction === 'store'">
|
||||||
|
|
||||||
<div class="row register-form">
|
<div class="row register-form">
|
||||||
@ -304,8 +401,21 @@
|
|||||||
<input type="date" id="assigndate" name="assigndate" class="form-control" v-model="assigndate">
|
<input type="date" id="assigndate" name="assigndate" class="form-control" v-model="assigndate">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">Consignment Note</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="file" id="document" name="document" class="form-control-file" v-on:change="handleFileUpload" accept="image/png, image/jpeg, application/pdf" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">Remark:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" id="remark" name="remark" v-model="remark" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@* Submit and Reset Buttons *@
|
@* Submit and Reset Buttons *@
|
||||||
@ -357,6 +467,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-4 col-form-label">Consignment Note</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="file" id="document" name="document" class="form-control-file" v-on:change="handleFileUpload" accept="image/png, image/jpeg, application/pdf" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-4 col-form-label">Remark:</label>
|
<label class="col-sm-4 col-form-label">Remark:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
@ -438,12 +555,11 @@
|
|||||||
await Html.RenderPartialAsync("_ValidationScriptsPartial");
|
await Html.RenderPartialAsync("_ValidationScriptsPartial");
|
||||||
}
|
}
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/html5-qrcode/minified/html5-qrcode.min.js"></script>
|
<script src="~/js/vue-qrcode-reader.umd.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
app.mount('#registerItem');
|
|
||||||
|
|
||||||
// Attach a click event listener to elements with the class 'btn-success'.
|
// Attach a click event listener to elements with the class 'btn-success'.
|
||||||
$('#addItemBtn').on('click', function () {
|
$('#addItemBtn').on('click', function () {
|
||||||
@ -460,12 +576,15 @@
|
|||||||
return {
|
return {
|
||||||
thisItem: null,
|
thisItem: null,
|
||||||
qrCodeResult: null,
|
qrCodeResult: null,
|
||||||
html5QrCodeScanner: null,
|
|
||||||
debounceTimeout: null,
|
debounceTimeout: null,
|
||||||
userlist: null,
|
userlist: null,
|
||||||
|
stationlist: null,
|
||||||
storelist: null,
|
storelist: null,
|
||||||
supplierlist: null,
|
supplierlist: null,
|
||||||
selectedUser: "",
|
selectedUser: "",
|
||||||
|
selectedStation: "",
|
||||||
|
selectedStationPIC: "",
|
||||||
selectedStore: "",
|
selectedStore: "",
|
||||||
selectedAction: "",
|
selectedAction: "",
|
||||||
assigndate: null,
|
assigndate: null,
|
||||||
@ -489,15 +608,43 @@
|
|||||||
currentUser: null,
|
currentUser: null,
|
||||||
currentUserCompanyDept: null,
|
currentUserCompanyDept: null,
|
||||||
itemlateststatus: "",
|
itemlateststatus: "",
|
||||||
|
|
||||||
|
//QR VARIABLE
|
||||||
|
qrCodeResult: null,
|
||||||
|
debounceTimeout: null,
|
||||||
|
error: "",
|
||||||
|
selectedConstraints: { facingMode: "environment" },
|
||||||
|
trackFunctionSelected: { text: 'outline', value: null },
|
||||||
|
barcodeFormats: {
|
||||||
|
qr_code: true, // Hanya mendukung QR Code
|
||||||
|
code_128: true,
|
||||||
|
ean_13: true
|
||||||
|
},
|
||||||
|
constraintOptions: [
|
||||||
|
{ label: "Rear Camera", constraints: { facingMode: "environment" } },
|
||||||
|
{ label: "Front Camera", constraints: { facingMode: "user" } }
|
||||||
|
],
|
||||||
|
videoInputDevices: [],
|
||||||
|
selectedCameraId: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetchUser();
|
this.fetchUser();
|
||||||
this.fetchSuppliers();
|
this.fetchSuppliers();
|
||||||
this.startScanner();
|
|
||||||
this.fetchUsers();
|
this.fetchUsers();
|
||||||
this.fetchStores();
|
this.fetchStores();
|
||||||
//this.fetchItem('ARA00500008'); // for testing only. clear this
|
this.fetchStations();
|
||||||
|
this.trackFunctionSelected.value = this.paintOutline;
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
selectedStation(newStationId) {
|
||||||
|
console.log(newStationId);
|
||||||
|
console.log(this.selectedStation);
|
||||||
|
// Find the station object that matches the selectedStation id
|
||||||
|
const selectedStationObj = this.stationlist.find(station => station.stationId === newStationId);
|
||||||
|
// Set the selectedPIC based on the stationPIC
|
||||||
|
this.selectedStationPIC = selectedStationObj ? selectedStationObj.stationPicID : "";
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
filteredDepartments() {
|
filteredDepartments() {
|
||||||
@ -520,10 +667,86 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
// handleSelection(event) {
|
||||||
|
// console.log("Event Target Value:", event.target.value); Debugging
|
||||||
|
// const selectedstationid = event.target.value;
|
||||||
|
// console.log(this.stationlist);
|
||||||
|
// const selectedStationObj = this.stationlist.find(station => station.stationId == selectedstationid);
|
||||||
|
// Set the selectedPIC based on the stationPIC
|
||||||
|
// this.selectedStationPIC = selectedStationObj ? selectedStationObj.stationPicID : "";
|
||||||
|
// },
|
||||||
|
// Split Url dapatkan unique ID Je
|
||||||
|
onDecode(detectedCodes) {
|
||||||
|
if (detectedCodes.length > 0) {
|
||||||
|
this.qrCodeResult = detectedCodes[0].rawValue; // Ambil URL dari rawValue
|
||||||
|
this.UniqueID = this.qrCodeResult.split('/').pop(); // Ambil UniqueID dari URL
|
||||||
|
this.fetchItem(this.UniqueID);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//Showing Qr Error
|
||||||
|
onError(err) {
|
||||||
|
let message = `[${err.name}]: `;
|
||||||
|
if (err.name === "NotAllowedError") {
|
||||||
|
message += "You have to allow camera accecss.";
|
||||||
|
} else if (err.name === "NotFoundError") {
|
||||||
|
message += "There's no camera detect.";
|
||||||
|
} else if (err.name === "NotReadableError") {
|
||||||
|
message += "You are using camera on the other application.";
|
||||||
|
} else {
|
||||||
|
message += err.message;
|
||||||
|
}
|
||||||
|
this.error = message;
|
||||||
|
},
|
||||||
|
|
||||||
|
//Setting Camera
|
||||||
|
async onCameraReady() {
|
||||||
|
try {
|
||||||
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||||
|
this.videoInputDevices = devices.filter(device => device.kind === 'videoinput');
|
||||||
|
|
||||||
|
if (this.videoInputDevices.length > 0) {
|
||||||
|
// Keep the selected camera if already chosen
|
||||||
|
if (!this.selectedCameraId) {
|
||||||
|
this.selectedCameraId = this.videoInputDevices[0].deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectedConstraints = { deviceId: { exact: this.selectedCameraId } };
|
||||||
|
} else {
|
||||||
|
this.error = "No camera detected.";
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.error = "Error accessing camera: " + err.message;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//Update Camera Category
|
||||||
|
updateCamera() {
|
||||||
|
this.selectedConstraints = { deviceId: { exact: this.selectedCameraId } };
|
||||||
|
},
|
||||||
|
|
||||||
|
//Red box if QR Detect
|
||||||
|
paintOutline(detectedCodes, ctx) {
|
||||||
|
for (const detectedCode of detectedCodes) {
|
||||||
|
const [firstPoint, ...otherPoints] = detectedCode.cornerPoints;
|
||||||
|
|
||||||
|
ctx.strokeStyle = 'red'; // Warna garis merah
|
||||||
|
ctx.lineWidth = 3;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(firstPoint.x, firstPoint.y);
|
||||||
|
for (const { x, y } of otherPoints) {
|
||||||
|
ctx.lineTo(x, y);
|
||||||
|
}
|
||||||
|
ctx.lineTo(firstPoint.x, firstPoint.y);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
},
|
||||||
resetScanner(){
|
resetScanner(){
|
||||||
this.thisItem = null;
|
this.thisItem = null;
|
||||||
this.resetForm();
|
this.resetForm();
|
||||||
this.startScanner();
|
|
||||||
},
|
},
|
||||||
handleFileUpload(event) {
|
handleFileUpload(event) {
|
||||||
const file = event.target.files[0];
|
const file = event.target.files[0];
|
||||||
@ -547,10 +770,11 @@
|
|||||||
const now = new Date();
|
const now = new Date();
|
||||||
const formData = {
|
const formData = {
|
||||||
|
|
||||||
...(this.selectedAction === 'user' ? { toUser: this.currentUser.id, toOther: 'On Delivery', SendDate: this.assigndate, lastUser: this.selectedUser, MovementComplete: false,} : {}),
|
...(this.selectedAction === 'user' ? { toUser: this.currentUser.id, toOther: 'On Delivery', SendDate: this.assigndate, lastUser: this.selectedUser, MovementComplete: false, Remark: this.remark, ConsignmentNote: this.document} : {}),
|
||||||
...(this.selectedAction === 'store' ? { toUser: this.currentUser.id, toOther: 'On Delivery', SendDate: this.assigndate, lastUser: this.selectedStore, MovementComplete: false, ItemId: this.thisItem.itemID, Action: 'Stock Out', Quantity: 1,} : {}),
|
...(this.selectedAction === 'station' ? { toStation: this.selectedStation, toUser: this.currentUser.id, toOther: 'On Delivery', SendDate: this.assigndate, lastUser: this.selectedUser, MovementComplete: false, Remark: this.remark, ConsignmentNote: this.document} : {}),
|
||||||
...(this.selectedAction === 'supplier' ? { toUser: this.currentUser.id, toOther: this.selectedOther, SendDate: this.assigndate, Remark: this.remark + '. Item sent to ' + this.selectedSupplier + ' for ' + this.selectedOther,lastUser: this.currentUser.id, MovementComplete: false, ItemId: this.thisItem.itemID, Action: 'Stock Out', Quantity: 1, } : {}),
|
...(this.selectedAction === 'store' ? { toUser: this.currentUser.id, toOther: 'On Delivery', SendDate: this.assigndate, lastUser: this.selectedStore, MovementComplete: false, Remark: this.remark, ConsignmentNote: this.document} : {}),
|
||||||
...(this.selectedAction === 'faulty' ? { toUser: this.currentUser.id,toOther: 'Faulty', Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(), Remark: this.remark, ConsignmentNote: this.document, MovementComplete: true, ItemId: this.thisItem.itemID, Action: 'Stock Out', Quantity: 1,} : {}),
|
...(this.selectedAction === 'supplier' ? { toUser: this.currentUser.id, toOther: this.selectedOther, SendDate: this.assigndate, Remark: this.remark + '. Item sent to ' + this.selectedSupplier + ' for ' + this.selectedOther, ConsignmentNote: this.document, lastUser: this.currentUser.id, MovementComplete: false, } : {}),
|
||||||
|
...(this.selectedAction === 'faulty' ? { toUser: this.currentUser.id,toOther: 'Faulty', Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(), Remark: this.remark, ConsignmentNote: this.document, MovementComplete: true, } : {}),
|
||||||
|
|
||||||
ItemId: this.thisItem.itemID,
|
ItemId: this.thisItem.itemID,
|
||||||
Action: 'Stock Out',
|
Action: 'Stock Out',
|
||||||
@ -649,60 +873,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
startScanner() {
|
|
||||||
const config = {
|
|
||||||
fps: 60,
|
|
||||||
qrbox: 400
|
|
||||||
};
|
|
||||||
|
|
||||||
// navigator.mediaDevices.getUserMedia({
|
|
||||||
// video: {
|
|
||||||
// width: { ideal: 1920 }, Higher resolution
|
|
||||||
// height: { ideal: 1080 },
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// .catch((err) => {
|
|
||||||
// console.error("Error accessing camera:", err);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// this.html5QrCodeScanner = new Html5QrcodeScanner(
|
|
||||||
// "reader", config, false
|
|
||||||
// );
|
|
||||||
|
|
||||||
// this.html5QrCodeScanner.render(
|
|
||||||
// (decodedText, decodedResult) => {
|
|
||||||
// if (!this.debounceTimeout) {
|
|
||||||
// this.debounceTimeout = setTimeout(() => {
|
|
||||||
// this.qrCodeResult = decodedText;
|
|
||||||
// this.sendDataToBackend(decodedText);
|
|
||||||
// this.fetchItem(decodedText.split('/').pop());
|
|
||||||
// this.fetchItem('ARA00500008'); for testing only. clear
|
|
||||||
// this.debounceTimeout = null;
|
|
||||||
// }, this.debounceTime);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
|
|
||||||
navigator.mediaDevices.getUserMedia({ video: true })
|
|
||||||
.then(() => {
|
|
||||||
this.html5QrCodeScanner = new Html5QrcodeScanner("reader", config, false);
|
|
||||||
this.html5QrCodeScanner.render((decodedText) => {
|
|
||||||
if (!this.debounceTimeout) {
|
|
||||||
this.debounceTimeout = setTimeout(() => {
|
|
||||||
this.qrCodeResult = decodedText;
|
|
||||||
// this.UniqueID = decodedText.split('/').pop();
|
|
||||||
this.fetchItem(decodedText.split('/').pop());
|
|
||||||
this.debounceTimeout = null;
|
|
||||||
}, this.debounceTime);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error("Error accessing camera:", err);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
async fetchItem(itemid) {
|
async fetchItem(itemid) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/InvMainAPI/GetItem/' + itemid, {
|
const response = await fetch('/InvMainAPI/GetItem/' + itemid, {
|
||||||
@ -804,6 +974,29 @@
|
|||||||
this.userlist = await response.json();
|
this.userlist = await response.json();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('Error fetching item:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async fetchStations() {
|
||||||
|
try {
|
||||||
|
// const token = localStorage.getItem('token'); // Get the token from localStorage
|
||||||
|
const response = await fetch('/InvMainAPI/StationList', {
|
||||||
|
method: 'POST', // Specify the HTTP method
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json', // Set content type
|
||||||
|
// 'Authorization': `Bearer ${token}` // Include the token in the headers
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to fetch item');
|
||||||
|
}
|
||||||
|
this.stationlist = await response.json();
|
||||||
|
console.log(this.stationlist);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error('Error fetching item:', error);
|
console.error('Error fetching item:', error);
|
||||||
@ -834,6 +1027,10 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.component("qrcode-stream", VueQrcodeReader.QrcodeStream);
|
||||||
|
|
||||||
|
app.mount('#registerItemMovement');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -590,6 +590,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
i.ToUser,
|
i.ToUser,
|
||||||
UniqueID = i.Item?.UniqueID,
|
UniqueID = i.Item?.UniqueID,
|
||||||
ProductName = i.Item?.Product?.ProductName,
|
ProductName = i.Item?.Product?.ProductName,
|
||||||
|
ProductCategory = i.Item?.Product?.Category,
|
||||||
LastUserName = i.FromUser?.FullName,
|
LastUserName = i.FromUser?.FullName,
|
||||||
LastStoreName = i.FromStore?.StoreName,
|
LastStoreName = i.FromStore?.StoreName,
|
||||||
LastStationName = i.FromStation?.StationName,
|
LastStationName = i.FromStation?.StationName,
|
||||||
@ -980,7 +981,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("ApproveRequest/{id}")]
|
[HttpPost("ApproveRequest/{id}")]
|
||||||
public async Task<IActionResult> ApproveRequest(int id)
|
public async Task<IActionResult> ApproveRequest(int id, [FromBody] RequestModel request)
|
||||||
{
|
{
|
||||||
var Request = await _centralDbContext.Requests.FindAsync(id);
|
var Request = await _centralDbContext.Requests.FindAsync(id);
|
||||||
if (Request == null)
|
if (Request == null)
|
||||||
@ -989,6 +990,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
}
|
}
|
||||||
|
|
||||||
Request.status = "Approved";
|
Request.status = "Approved";
|
||||||
|
Request.remarkMasterInv = request.remarkMasterInv;
|
||||||
Request.approvalDate = DateTime.UtcNow;
|
Request.approvalDate = DateTime.UtcNow;
|
||||||
_centralDbContext.SaveChanges();
|
_centralDbContext.SaveChanges();
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
Loading…
Reference in New Issue
Block a user