diff --git a/Areas/Inventory/Views/ItemMovement/ItemMovementUser.cshtml b/Areas/Inventory/Views/ItemMovement/ItemMovementUser.cshtml index 383bc23..467c273 100644 --- a/Areas/Inventory/Views/ItemMovement/ItemMovementUser.cshtml +++ b/Areas/Inventory/Views/ItemMovement/ItemMovementUser.cshtml @@ -33,6 +33,10 @@ color: orange; /* Warna oren untuk 'Return' */ } + .text-success { + color: greenyellow; + } + .ms-auto { margin-left: auto !important; /* Push Complete/Incomplete to right */ } @@ -84,6 +88,13 @@
+ +
+

Assign Station Movement

+
+
+
+
@@ -100,43 +111,40 @@
- +
Latest Movement
- -

+

- {{ movement.action === 'Assign' ? 'Assign' : (movement.toOther === 'On Delivery' ? 'Receive' : 'Return') }} + {{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}

- -
-

Send Date:

- {{ movement.sendDate }} +
+

{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}

+ {{ movement.sendDate }}
-
+

Receive Date:

- {{ movement.receiveDate || 'Not arrive' }} + {{ movement.receiveDate || 'Not arrive' }}
-
+

Action:

- {{ movement.action }} + {{ movement.action }}
-
+

Status:

- {{ movement.latestStatus || movement.toOther }} + {{ movement.latestStatus || movement.toOther }}
@@ -156,7 +164,8 @@
- + +

Start

User: {{ movement.toUserName }}

@@ -194,7 +203,6 @@
- @@ -202,24 +210,22 @@
- -

+

- {{ movement.action === 'Assign' ? 'Assign' : (movement.toOther === 'On Delivery' ? 'Receive' : 'Return') }} + {{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}

-

Send Date:

+

{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}

{{ movement.sendDate }}
-
+

Receive Date:

{{ movement.receiveDate || 'Not arrive' }}
@@ -237,7 +243,7 @@
- @@ -248,13 +254,12 @@
- -
- + +

Start

User: {{ movement.toUserName }}

@@ -300,7 +305,7 @@
- +

{{ station }}

- +
- +

Item : {{ group.uniqueID }}

- +
Latest Movement
-

+

- {{ movement.action === 'Assign' ? 'Assign' : (movement.toOther === 'On Delivery' ? 'Receive' : 'Return') }} + {{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}

-
-

Send Date:

- {{ movement.sendDate }} + +
+

{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}

+ {{ movement.sendDate }}
-
+ +

Receive Date:

- {{ movement.receiveDate || 'Not arrive' }} + {{ movement.receiveDate || 'Not arrive' }}
-
+ +

Action:

- {{ movement.action }} + {{ movement.action }}
-
+ +

Status:

- {{ movement.latestStatus || movement.toOther }} + {{ movement.latestStatus || movement.toOther }}
+ -

+ +

{{ movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'Complete' : (movement.latestStatus === 'Ready To Deploy' ? 'Canceled' : 'Incomplete') }}

@@ -366,7 +377,8 @@
- + +

Start

User: {{ movement.toUserName }}

@@ -401,7 +413,7 @@
- + @@ -410,19 +422,22 @@
-

- {{ movement.action === 'Assign' ? 'Assign' : (movement.toOther === 'On Delivery' ? 'Receive' : 'Return') }} +

+ + {{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }} +

-

Send Date:

+

{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}

{{ movement.sendDate }}
-
+

Receive Date:

{{ movement.receiveDate || 'Not arrive' }}
@@ -452,7 +467,7 @@
- +
@@ -548,6 +563,7 @@ return { itemMovements: [], itemMovementCompleteDatatable: null, + stationDatatable: null, itemMovementNotCompleteDatatable: null, searchQuery: "", searchStation: "", @@ -572,28 +588,63 @@ return acc; }, {}); }, + groupedByStation() { let grouped = {}; this.itemMovements.forEach((movement) => { - let station = movement.toStationName || movement.lastStationName || "Unassign Station"; - let itemId = movement.uniqueID; - if (!grouped[station]) { - grouped[station] = {}; + if (movement.toStation !== null) { + let station = movement.toStationName; + let itemId = movement.uniqueID; + + if (!grouped[station]) { + grouped[station] = {}; + } + + if (!grouped[station][itemId]) { + grouped[station][itemId] = { uniqueID: itemId, movements: [] }; + } + + grouped[station][itemId].movements.push(movement); } - if (!grouped[station][itemId]) { - grouped[station][itemId] = { uniqueID: itemId, movements: [] }; - } + if (movement.lastStation !== null) { + let station = movement.lastStationName; + let itemId = movement.uniqueID; - grouped[station][itemId].movements.push(movement); + if (!grouped[station]) { + grouped[station] = {}; + } + + if (!grouped[station][itemId]) { + grouped[station][itemId] = { uniqueID: itemId, movements: [] }; + } + + grouped[station][itemId].movements.push(movement); + } + else if (movement.lastStation == null || movement.toStation == null) { + + let station = "Self"; + let itemId = movement.uniqueID; + + if (!grouped[station]) { + grouped[station] = {}; + } + + if (!grouped[station][itemId]) { + grouped[station][itemId] = { uniqueID: itemId, movements: [] }; + } + + grouped[station][itemId].movements.push(movement); + } + }); // Sort stations and move "Unassign Station" to the last position let sortedKeys = Object.keys(grouped).sort((a, b) => { - if (a === "Unassign Station") return 1; // Move Unassign Station to the end + if (a === "Unassign Station") return 1; if (b === "Unassign Station") return -1; - return a.localeCompare(b); // Normal sorting for other stations + return a.localeCompare(b); }); let sortedGrouped = {}; @@ -603,6 +654,7 @@ return sortedGrouped; }, + filteredItems() { if (!this.searchQuery.trim()) { return this.groupedItems; @@ -614,6 +666,7 @@ ) ); }, + filteredStation() { if (!this.searchStation) { return this.groupedByStation; @@ -684,6 +737,7 @@ this.initAllTables(); } }, + initAllTables() { if (this.itemMovementNotCompleteDatatable) { this.itemMovementNotCompleteDatatable.destroy(); @@ -691,20 +745,23 @@ if (this.itemMovementCompleteDatatable) { this.itemMovementCompleteDatatable.destroy(); } + if(this.stationDatatable) { + this.stationDatatable.destroy(); + } this.itemMovementNotCompleteDatatable = $("#itemMovementNotCompleteDatatable").DataTable({ data: this.itemMovements.filter((m) => m.movementComplete == 0), columns: [ { title: "Unique Id", data: "id" }, { title: "Product Code", data: "uniqueID" }, + { title: "Action", data: "action" }, + { title: "Send Date", data: "sendDate" }, { 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", @@ -740,22 +797,22 @@ }); this.itemMovementCompleteDatatable = $("#itemMovementCompleteDatatable").DataTable({ - data: this.itemMovements.filter((m) => m.movementComplete == 1), + data: this.itemMovements.filter((m) => m.movementComplete == 1 && m.action !== "Assign"), columns: [ { title: "Unique Id", data: "id" }, { title: "Product Code", data: "uniqueID" }, + { title: "Send Date", data: "sendDate" }, + { title: "Receive Date", data: "receiveDate" }, + { title: "Action", data: "action" }, { 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", render: function (data, type, full, meta) { @@ -788,16 +845,64 @@ ], responsive: true, }); + + this.stationDatatable = $("#stationDatatable").DataTable({ + data: this.itemMovements.filter((m) => m.action === "Assign" ), + columns: [ + { title: "Unique Id", data: "id" }, + { title: "Product Code", data: "uniqueID" }, + { title: "Assign Date", data: "sendDate" }, + { title: "From User", data: "toUserName" }, + { title: "From Station", data: "toStationName" }, + { title: "Last Station", data: "lastStationName" }, + { title: "Qty", data: "quantity" }, + { + title: "Note", + data: "consignmentNote", + render: function (data, type, full, meta) { + if (!data) { + return "No Document"; + } + + // Check if the document is an image based on file extension + var isImage = /\.(jpeg|jpg|png|gif)$/i.test(data); + var isPdf = /\.pdf$/i.test(data); + + if (isImage) { + return ` + Image + `; + } + else if (isPdf) { + return ` + PDF Document +
View PDF +
`; + } else { + return `Download File`; + } + }, + }, + { title: "Remark", data: "remark" }, + ], + responsive: true, + }); }, + toggleCategory(itemId) { this.categoryVisible[itemId] = !this.categoryVisible[itemId]; }, + toggleHistory(itemId) { this.historyVisible[itemId] = !this.historyVisible[itemId]; }, + toggleDetails(movementId) { this.detailsVisible[movementId] = !this.detailsVisible[movementId]; }, + handleSorting() { this.renderTables(); }, diff --git a/Areas/Inventory/Views/ItemMovement/QrUser.cshtml b/Areas/Inventory/Views/ItemMovement/QrUser.cshtml index 93cf6c5..7417ad2 100644 --- a/Areas/Inventory/Views/ItemMovement/QrUser.cshtml +++ b/Areas/Inventory/Views/ItemMovement/QrUser.cshtml @@ -261,6 +261,19 @@
+
+ +
+ +
+
+ +
+ +
+ +
+
@@ -457,7 +470,7 @@ ConsignmentNote: this.consignmentNote, Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(), LastUser: this.currentUserId, - LastStore: this.thisItem.currentStoreId, + LastStore: this.thisItem.toStore, LastStation: this.selectedStation, LatestStatus: "Delivered", ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(), @@ -498,7 +511,8 @@ try { const now = new Date(); const formData = { - Id : this.thisItem.id, + Id: this.thisItem.id, + LastStore: this.thisItem.toStore, LatestStatus: "Delivered", ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(), MovementComplete: true, diff --git a/Controllers/API/Inventory/InvMainAPI.cs b/Controllers/API/Inventory/InvMainAPI.cs index ce9a5d4..623f9f3 100644 --- a/Controllers/API/Inventory/InvMainAPI.cs +++ b/Controllers/API/Inventory/InvMainAPI.cs @@ -1248,20 +1248,24 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory { if (!string.IsNullOrEmpty(returnMovement.ConsignmentNote)) { + var findUniqueCode = _centralDbContext.Items.Include(i => i.Product).FirstOrDefault(r => r.ItemID == returnMovement.ItemId); + var findUniqueUser = _centralDbContext.Users.FirstOrDefault(r => r.Id == returnMovement.ToUser); + var bytes = Convert.FromBase64String(returnMovement.ConsignmentNote); string filePath = ""; - string uniqueName = $"{returnMovement.Id}_{Guid.NewGuid()}"; + var uniqueAbjad = new string(Enumerable.Range(0, 8).Select(_ => "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[new Random().Next(36)]).ToArray()); + if (IsImage(bytes)) { - filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/request", uniqueName + returnMovement.ItemId + "_Request.jpg"); - returnMovement.ConsignmentNote = "/media/inventory/request/" + uniqueName + returnMovement.ItemId + "_Request.jpg"; + filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/itemmovement", findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Return.jpg"); + returnMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Return.jpg"; } else if (IsPdf(bytes)) { - filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/request", uniqueName + returnMovement.ItemId + "_Request.pdf"); - returnMovement.ConsignmentNote = "/media/inventory/request/" + uniqueName + returnMovement.ItemId + "_Request.pdf"; + filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/itemmovement", findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "Return.pdf"); + returnMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Return.pdf"; } else { @@ -1270,16 +1274,13 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory await System.IO.File.WriteAllBytesAsync(filePath, bytes); } - // 1. Simpan returnMovement dalam database + _centralDbContext.ItemMovements.Add(returnMovement); await _centralDbContext.SaveChangesAsync(); - // 2. Cari item movement yang ada ItemId & MovementComplete = false var updateItemIdMovement = await _centralDbContext.ItemMovements .FirstOrDefaultAsync(m => m.Id == returnMovement.Id && m.MovementComplete == false); - - // 3. Jika wujud, update MovementId if (updateItemIdMovement != null) { var returnItems = await _centralDbContext.Items.FindAsync(updateItemIdMovement.ItemId); @@ -1289,21 +1290,10 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory returnItems.MovementId = updateItemIdMovement.Id; returnItems.ItemStatus = 2; _centralDbContext.Items.Update(returnItems); - + await _centralDbContext.SaveChangesAsync(); // Simpan perubahan } } - //4. Update Assign Row (Untuk ToStore = Ada value , kepada , ToStore = null) - var updateToStoreAssignStation = await _centralDbContext.ItemMovements.Where(i => i.Action == "Assign").ToListAsync(); - - foreach (var item in updateToStoreAssignStation) - { - item.ToStore = null; // Set ToStore to null for each matching row - _centralDbContext.ItemMovements.Update(item); - } - - await _centralDbContext.SaveChangesAsync(); // Simpan perubahan - return Json(new { updateItemIdMovement.Id, @@ -1326,7 +1316,6 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory updateItemIdMovement.MovementComplete }); - } catch (Exception ex) { @@ -1346,20 +1335,24 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory { if (!string.IsNullOrEmpty(stationMovement.ConsignmentNote)) { + var findUniqueCode = _centralDbContext.Items.Include(i => i.Product).FirstOrDefault(r => r.ItemID == stationMovement.ItemId); + var findUniqueUser = _centralDbContext.Users.FirstOrDefault(r => r.Id == stationMovement.ToUser); + var bytes = Convert.FromBase64String(stationMovement.ConsignmentNote); string filePath = ""; - string uniqueName = $"{stationMovement.Id}_{Guid.NewGuid()}"; + var uniqueAbjad = new string(Enumerable.Range(0, 8).Select(_ => "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[new Random().Next(36)]).ToArray()); + if (IsImage(bytes)) { - filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/request", uniqueName + stationMovement.ItemId + "_Request.jpg"); - stationMovement.ConsignmentNote = "/media/inventory/request/" + uniqueName + stationMovement.ItemId + "_Request.jpg"; + filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/itemmovement", findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Station.jpg"); + stationMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Station.jpg"; } else if (IsPdf(bytes)) { - filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/request", uniqueName + stationMovement.ItemId + "_Request.pdf"); - stationMovement.ConsignmentNote = "/media/inventory/request/" + uniqueName + stationMovement.ItemId + "_Request.pdf"; + filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/itemmovement", findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "Return.pdf"); + stationMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Station.pdf"; } else { @@ -1368,16 +1361,14 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory await System.IO.File.WriteAllBytesAsync(filePath, bytes); } - // 1. Simpan returnMovement dalam database + _centralDbContext.ItemMovements.Add(stationMovement); await _centralDbContext.SaveChangesAsync(); - // 2. Cari item movement yang ada ItemId & MovementComplete = false var updateItemIdMovement = await _centralDbContext.ItemMovements.Include(i => i.Item) .FirstOrDefaultAsync(m => m.Id == stationMovement.Id); - // 3. Jika wujud, update MovementId if (updateItemIdMovement != null) { var returnItems = await _centralDbContext.Items.FindAsync(updateItemIdMovement.ItemId); diff --git a/wwwroot/Media/Inventory/itemmovement/hilmi.rezuan Latitude 7410(UN9DWPFT) Station.jpg b/wwwroot/Media/Inventory/itemmovement/hilmi.rezuan Latitude 7410(UN9DWPFT) Station.jpg new file mode 100644 index 0000000..2e6c3a7 Binary files /dev/null and b/wwwroot/Media/Inventory/itemmovement/hilmi.rezuan Latitude 7410(UN9DWPFT) Station.jpg differ