request & Qr

This commit is contained in:
ArifHilmi 2025-02-26 16:28:08 +08:00
parent 8cf3fd9b14
commit 41d1c8e1af
3 changed files with 58 additions and 62 deletions

View File

@ -49,12 +49,45 @@
</div> </div>
<div v-if="sortBy === 'item'"> <div v-if="sortBy === 'item'">
<div v-for="(movements, itemId) in groupedByItem" :key="itemId" class="row card"> <div v-for="(group, itemId) in groupedByItem" :key="itemId" class="row card">
<div class="card-header"> <div class="card-header">
<h2>Item ID: {{ itemId }}</h2> <h2>Item Name: {{ group.productName }}</h2>
</div> </div>
<div class="card-body"> <div class="card-body">
<table class="table table-bordered table-hover table-striped no-wrap item-table" :id="'itemTable_' + itemId" style="width:100%;border-style: solid; border-width: 1px"></table> <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>
</div> </div>
@ -82,9 +115,12 @@
groupedByItem() { groupedByItem() {
return this.itemMovements.reduce((acc, movement) => { return this.itemMovements.reduce((acc, movement) => {
if (!acc[movement.itemId]) { if (!acc[movement.itemId]) {
acc[movement.itemId] = []; acc[movement.itemId] = {
productName: movement.productName,
movements: []
};
} }
acc[movement.itemId].push(movement); acc[movement.itemId].movements.push({...movement, showDetails: false});
return acc; return acc;
}, {}); }, {});
}, },
@ -95,7 +131,7 @@
methods: { methods: {
async fetchItemMovement() { async fetchItemMovement() {
try { try {
const response = await fetch('/InvMainAPI/ItemMovementUser', { const response = await fetch('/InvMainAPI/ItemMovementUser', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -105,7 +141,13 @@
if (!response.ok) { if (!response.ok) {
throw new Error('Failed to fetch item movement'); throw new Error('Failed to fetch item movement');
} }
this.itemMovements = await response.json(); const data = await response.json();
// Ensure showDetails is reactive
this.itemMovements = data.map(movement => ({
...movement,
showDetails: false
}));
if (this.itemMovementNotCompleteDatatable) { if (this.itemMovementNotCompleteDatatable) {
this.itemMovementNotCompleteDatatable.clear().destroy(); this.itemMovementNotCompleteDatatable.clear().destroy();
@ -124,10 +166,7 @@
renderTables() { renderTables() {
if (this.sortBy === 'all') { if (this.sortBy === 'all') {
this.initAllTables(); this.initAllTables();
} else { }
console.log(this.sortBy);
this.initItemTables();
}
}, },
initAllTables() { initAllTables() {
@ -194,41 +233,11 @@
this.loading = false; this.loading = false;
}, },
initItemTables() { toggleDetails(id) {
if (this.itemMovementNotCompleteDatatable) { const movement = this.itemMovements.find(m => m.id === id);
this.itemMovementNotCompleteDatatable.clear().destroy(); if (movement) {
movement.showDetails = !movement.showDetails;
} }
if (this.itemMovementCompleteDatatable) {
this.itemMovementCompleteDatatable.clear().destroy();
}
Object.values(this.itemDatatables).forEach(table => table.destroy());
this.itemDatatables = {};
Object.entries(this.groupedByItem).forEach(([itemId, movements]) => {
const tableId = `#itemTable_${itemId}`;
this.itemDatatables[itemId] = $(tableId).DataTable({
data: movements,
columns: this.getColumns(),
responsive: true,
});
});
},
getColumns() {
return [
{ title: "Unique Id", data: "id" },
{ 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" },
];
}, },
resetForm() { resetForm() {
@ -236,22 +245,7 @@
}, },
handleSorting() { handleSorting() {
// Destroy existing DataTables before switching views this.$nextTick(() => this.fetchItemMovement());
if (this.itemMovementNotCompleteDatatable) {
this.itemMovementNotCompleteDatatable.clear().destroy();
this.itemMovementNotCompleteDatatable = null;
}
if (this.itemMovementCompleteDatatable) {
this.itemMovementCompleteDatatable.clear().destroy();
this.itemMovementCompleteDatatable = null;
}
Object.values(this.itemDatatables).forEach(table => table.destroy());
this.itemDatatables = {};
// Delay rendering to ensure Vue updates the DOM
this.$nextTick(() => {
this.renderTables();
});
}, },

View File

@ -576,7 +576,6 @@
async receiveReturnAPI() { async receiveReturnAPI() {
this.receiveReturn = 1; this.receiveReturn = 1;
console.log("update");
this.updateItemMovement(); this.updateItemMovement();
}, },

View File

@ -668,6 +668,8 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
} }
var itemMovementUser = await _centralDbContext.ItemMovements var itemMovementUser = await _centralDbContext.ItemMovements
.Include(i => i.Item)
.ThenInclude(i => i.Product)
.Include(i => i.FromStore) .Include(i => i.FromStore)
.Include(i => i.FromStation) .Include(i => i.FromStation)
.Include(i => i.FromUser) .Include(i => i.FromUser)
@ -684,6 +686,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
i.ToStation, i.ToStation,
i.ToStore, i.ToStore,
i.ToUser, i.ToUser,
ProductName = i.Item?.Product?.ProductName,
LastUserName = i.FromUser?.FullName, LastUserName = i.FromUser?.FullName,
LastStoreName = i.FromStore?.StoreName, LastStoreName = i.FromStore?.StoreName,
LastStationName = i.FromStation?.StationName, LastStationName = i.FromStation?.StationName,