PSTW_CentralizeSystem/Areas/Inventory/Views/ItemMovement/ItemMovementUser.cshtml
2025-02-26 16:28:08 +08:00

255 lines
10 KiB
Plaintext

@{
ViewData["Title"] = "Item Movement";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<style>
@@font-face {
font-family: 'OCR-A';
src: url('../assets/fonts/ocraext.ttf');
}
.QrPrintFont {
font-family: 'OCR-A', monospace;
}
.table td img {
display: block !important;
}
</style>
@await Html.PartialAsync("~/Areas/Inventory/Views/_InventoryPartialUser.cshtml");
<div id="ItemMovement" class="row">
<div class="row mb-3">
<h2 for="sortSelect" class="col-sm-1 col-form-h2">Sort by:</h2>
<div class="col-sm-4">
<select id="sortSelect" class="form-control" v-model="sortBy" v-on:change="handleSorting">
<option value="all">All</option>
<option value="item">Item</option>
</select>
</div>
</div>
<div v-if="sortBy === 'all'">
<div class="row card">
<div class="card-header">
<h2>Pending Item Movement</h2>
</div>
<div class="card-body">
<table class="table table-bordered table-hover table-striped no-wrap" id="itemMovementNotCompleteDatatable" style="width:100%;border-style: solid; border-width: 1px"></table>
</div>
</div>
<div class="row card">
<div class="card-header">
<h2>Complete Item Movement</h2>
</div>
<div class="card-body">
<table class="table table-bordered table-hover table-striped no-wrap" id="itemMovementCompleteDatatable" style="width:100%;border-style: solid; border-width: 1px"></table>
</div>
</div>
</div>
<div v-if="sortBy === 'item'">
<div v-for="(group, itemId) in groupedByItem" :key="itemId" class="row card">
<div class="card-header">
<h2>Item Name: {{ group.productName }}</h2>
</div>
<div class="card-body">
<div v-for="movement in group.movements" :key="movement.id" class="movement-row">
<div class="row">
<div class="col-md-12">
<strong>{{ movement.toOther === 'On Delivery' ? 'Receive' : 'Return' }}:</strong>
| <strong>Send Date:</strong> {{ movement.sendDate }}
| <strong>Receive Date:</strong> {{ movement.receiveDate || 'Not arrive' }}
| <strong>Status:</strong> {{ movement.latestStatus || movement.toOther }}
| <button class="btn btn-info btn-sm" v-on:click="toggleDetails(movement.id)">More Details</button>
</div>
</div>
<div v-if="movement.showDetails" class="details-row mt-2">
<div class="row align-items-center">
<div class="col-md-4 text-center">
<i class="fas fa-warehouse fa-2x"></i>
<p>Information: {{ movement.toOther }}</p>
<p>User: {{ movement.toUser }}</p>
<p>Station: {{ movement.toStationName }}</p>
<p>Store: {{ movement.toStoreName }}</p>
</div>
<div class="col-md-4 text-center">
<i class="fas fa-arrow-right fa-2x"></i>
</div>
<div class="col-md-4 text-center">
<i class="fas fa-user fa-2x"></i>
<p>Information: {{ movement.toOther }}</p>
<p>User: {{ movement.lastUser }}</p>
<p>Station: {{ movement.lastStationName }}</p>
<p>Store: {{ movement.lastStoreName }}</p>
</div>
</div>
</div>
<hr>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
<script>
$(function () {
app.mount('#ItemMovement');
});
const app = Vue.createApp({
data() {
return {
itemMovements: [],
itemMovementCompleteDatatable : null,
itemMovementNotCompleteDatatable : null,
itemDatatables: {}, // Store tables by ItemId
sortBy: 'all', // Sorting option
}
},
computed: {
groupedByItem() {
return this.itemMovements.reduce((acc, movement) => {
if (!acc[movement.itemId]) {
acc[movement.itemId] = {
productName: movement.productName,
movements: []
};
}
acc[movement.itemId].movements.push({...movement, showDetails: false});
return acc;
}, {});
},
},
mounted() {
this.fetchItemMovement();
},
methods: {
async fetchItemMovement() {
try {
const response = await fetch('/InvMainAPI/ItemMovementUser', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
});
if (!response.ok) {
throw new Error('Failed to fetch item movement');
}
const data = await response.json();
// Ensure showDetails is reactive
this.itemMovements = data.map(movement => ({
...movement,
showDetails: false
}));
if (this.itemMovementNotCompleteDatatable) {
this.itemMovementNotCompleteDatatable.clear().destroy();
}
if (this.itemMovementCompleteDatatable) {
this.itemMovementCompleteDatatable.clear().destroy();
}
this.renderTables();
}
catch (error) {
console.error('Error fetching item:', error);
}
},
renderTables() {
if (this.sortBy === 'all') {
this.initAllTables();
}
},
initAllTables() {
if (this.itemMovementNotCompleteDatatable) {
this.itemMovementNotCompleteDatatable.clear().destroy();
}
if (this.itemMovementCompleteDatatable) {
this.itemMovementCompleteDatatable.clear().destroy();
}
self = this;
this.itemMovementNotCompleteDatatable = $('#itemMovementNotCompleteDatatable').DataTable({
"data": this.itemMovements.filter(movement => movement.movementComplete == 0),
"columns": [
{
"title": "Unique Id",
"data": "id",
"createdCell": function (td, cellData, rowData, row, col) {
// Assign a unique ID to the <td> element
$(td).attr('id', `qr${cellData}`);
},
},
{ title: "From User", data: "toUserName" },
{ title: "Last User", data: "lastUserName" },
{ title: "From Station", data: "toStationName" },
{ title: "From Store", data: "toStoreName" },
{ title: "Action", data: "action" },
{ title: "Start Status", data: "toOther" },
{ title: "Quantity", data: "quantity" },
{ title: "Send Date", data: "sendDate" },
{ title: "Note", data: "consignmentNote" },
{ title: "Remark", data: "remark" },
],
responsive: true,
});
this.itemMovementCompleteDatatable = $('#itemMovementCompleteDatatable').DataTable({
"data": this.itemMovements.filter(movement => movement.movementComplete == 1),
"columns": [
{
"title": "Unique Id",
"data": "id",
"createdCell": function (td, cellData, rowData, row, col) {
// Assign a unique ID to the <td> element
$(td).attr('id', `qr${cellData}`);
},
},
{ "title": "From User", "data": "toUserName" },
{ "title": "Last User", "data": "lastUserName" },
{ "title": "From Station", "data": "toStationName" },
{ "title": "Last Station", "data": "lastStationName" },
{ "title": "From Store", "data": "toStoreName" },
{ "title": "Last Store", "data": "lastStoreName" },
{ "title": "Action", "data": "action" },
{ "title": "Start Status", "data": "toOther" },
{ "title": "Latest Status", "data": "latestStatus" },
{ "title": "Qty", "data": "quantity" },
{ "title": "Send Date", "data": "sendDate" },
{ "title": "Receive Date", "data": "receiveDate" },
{ "title": "Note", "data": "consignmentNote" },
{ "title": "Remark", "data": "remark" },
],
responsive: true,
});
this.loading = false;
},
toggleDetails(id) {
const movement = this.itemMovements.find(m => m.id === id);
if (movement) {
movement.showDetails = !movement.showDetails;
}
},
resetForm() {
this.itemMovement = '';
},
handleSorting() {
this.$nextTick(() => this.fetchItemMovement());
},
},
});
</script>
}