Qr & Movement Display
This commit is contained in:
parent
3ec456afbd
commit
f8be5be392
@ -33,6 +33,10 @@
|
|||||||
color: orange; /* Warna oren untuk 'Return' */
|
color: orange; /* Warna oren untuk 'Return' */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-success {
|
||||||
|
color: greenyellow;
|
||||||
|
}
|
||||||
|
|
||||||
.ms-auto {
|
.ms-auto {
|
||||||
margin-left: auto !important; /* Push Complete/Incomplete to right */
|
margin-left: auto !important; /* Push Complete/Incomplete to right */
|
||||||
}
|
}
|
||||||
@ -84,6 +88,13 @@
|
|||||||
<div class="card-body">
|
<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>
|
<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 class="card-header">
|
||||||
|
<h3>Assign Station Movement</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-bordered table-hover table-striped no-wrap" id="stationDatatable" style="width:100%;border-style: solid; border-width: 1px"></table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -100,43 +111,40 @@
|
|||||||
<!-- Hide all details unless button is clicked -->
|
<!-- Hide all details unless button is clicked -->
|
||||||
<div v-show="categoryVisible[itemId]" class="card-body">
|
<div v-show="categoryVisible[itemId]" class="card-body">
|
||||||
<div v-for="(movement, index) in group.movements.sort((a, b) => a.id - b.id).reverse()" :key="movement.id" class="movement-row">
|
<div v-for="(movement, index) in group.movements.sort((a, b) => a.id - b.id).reverse()" :key="movement.id" class="movement-row">
|
||||||
<!-- 📌 Show Only Latest Movement -->
|
|
||||||
<div v-if="index === 0" class="row">
|
<div v-if="index === 0" class="row">
|
||||||
<strong>Latest Movement</strong>
|
<strong>Latest Movement</strong>
|
||||||
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
|
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
|
||||||
<!-- Movement Type -->
|
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther === 'Return',
|
||||||
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther !== 'On Delivery' && movement.action !== 'Assign',
|
'text-success': movement.toStation !== null, 'text-info': movement.action === 'Assign' && movement.toStation === null}"
|
||||||
'text-info': movement.action === 'Assign'}"
|
class="flex-shrink-0 text-nowrap" style="max-width:90px; min-width:90px;">
|
||||||
class="flex-shrink-0 text-nowrap"
|
|
||||||
style="max-width:90px; min-width:90px;">
|
|
||||||
|
|
||||||
{{ movement.action === 'Assign' ? 'Assign' : (movement.toOther === 'On Delivery' ? 'Receive' : 'Return') }}
|
{{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}
|
||||||
|
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
|
||||||
<!-- Send Date -->
|
<!-- Send Date -->
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1">
|
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
|
||||||
<h4 class="fixed-label m-0 text-nowrap">Send Date:</h4>
|
<h4 class="fixed-label m-0 text-nowrap">{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}</h4>
|
||||||
<span class="fixed-value">{{ movement.sendDate }}</span>
|
<span class="fixed-value text-truncate">{{ movement.sendDate }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Receive Date -->
|
<!-- Receive Date -->
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1">
|
<div v-if="movement.action !== 'Assign'" class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
|
||||||
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
|
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
|
||||||
<span class="fixed-value">{{ movement.receiveDate || 'Not arrive' }}</span>
|
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Action -->
|
<!-- Action -->
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1">
|
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:150px; min-width:150px;">
|
||||||
<h4 class="fixed-labelStatus m-0 text-nowrap">Action:</h4>
|
<h4 class="fixed-labelStatus m-0 text-nowrap">Action:</h4>
|
||||||
<span class="fixed-value">{{ movement.action }}</span>
|
<span class="fixed-value text-truncate">{{ movement.action }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Status -->
|
<!-- Status -->
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1">
|
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:160px; min-width:160px;">
|
||||||
<h4 class="fixed-labelStatus m-0 text-nowrap">Status:</h4>
|
<h4 class="fixed-labelStatus m-0 text-nowrap">Status:</h4>
|
||||||
<span class="fixed-value">{{ movement.latestStatus || movement.toOther }}</span>
|
<span class="fixed-value text-truncate" style="max-width:90px;">{{ movement.latestStatus || movement.toOther }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- More Details Button -->
|
<!-- More Details Button -->
|
||||||
@ -156,7 +164,8 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 text-center">
|
<div class="col-md-4 text-center">
|
||||||
<!-- Conditionally render Start Icon -->
|
<!-- Conditionally render Start Icon -->
|
||||||
<i v-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
|
<i v-if="movement.toStation" class="fas fa-map-marker-alt"></i>
|
||||||
|
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
|
||||||
<i v-else class="fas fa-warehouse fa-2x"></i>
|
<i v-else class="fas fa-warehouse fa-2x"></i>
|
||||||
<p><strong>Start</strong></p>
|
<p><strong>Start</strong></p>
|
||||||
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
|
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
|
||||||
@ -194,7 +203,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 📌 Single View History Button -->
|
|
||||||
<button class="btn btn-light w-100 text-left" v-on:click="toggleHistory(itemId)">
|
<button class="btn btn-light w-100 text-left" v-on:click="toggleHistory(itemId)">
|
||||||
<i :class="historyVisible[itemId] ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"></i> View History
|
<i :class="historyVisible[itemId] ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"></i> View History
|
||||||
</button>
|
</button>
|
||||||
@ -202,24 +210,22 @@
|
|||||||
<div v-show="historyVisible[itemId]" class="history-row">
|
<div v-show="historyVisible[itemId]" class="history-row">
|
||||||
<div v-for="(movement, i) in group.movements.slice(1)" :key="i" class="row mt-2">
|
<div v-for="(movement, i) in group.movements.slice(1)" :key="i" class="row mt-2">
|
||||||
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
|
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
|
||||||
<!-- Movement Type -->
|
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther === 'Return',
|
||||||
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther !== 'On Delivery' && movement.action !== 'Assign',
|
'text-success': movement.toStation !== null, 'text-info': movement.action === 'Assign' && movement.toStation === null}"
|
||||||
'text-info': movement.action === 'Assign'}"
|
class="flex-shrink-0 text-nowrap" style="max-width:90px; min-width:90px;">
|
||||||
class="flex-shrink-0 text-nowrap"
|
|
||||||
style="max-width:90px; min-width:90px;">
|
|
||||||
|
|
||||||
{{ movement.action === 'Assign' ? 'Assign' : (movement.toOther === 'On Delivery' ? 'Receive' : 'Return') }}
|
{{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}
|
||||||
|
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<!-- Send Date -->
|
<!-- Send Date -->
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
|
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
|
||||||
<h4 class="fixed-label m-0 text-nowrap">Send Date:</h4>
|
<h4 class="fixed-label m-0 text-nowrap">{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}</h4>
|
||||||
<span class="fixed-value text-truncate">{{ movement.sendDate }}</span>
|
<span class="fixed-value text-truncate">{{ movement.sendDate }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Receive Date -->
|
<!-- Receive Date -->
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
|
<div v-if="movement.action !== 'Assign'" class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
|
||||||
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
|
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
|
||||||
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
|
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -237,7 +243,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- More Details Button -->
|
<!-- More Details Button -->
|
||||||
<button class="btn btn-info btn-sm ms-auto"v-on:click="toggleDetails(movement.id)">
|
<button class="btn btn-info btn-sm ms-auto" v-on:click="toggleDetails(movement.id)">
|
||||||
More Details
|
More Details
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@ -248,13 +254,12 @@
|
|||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- 📌 Details Section (Hidden by Default) -->
|
|
||||||
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
|
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 text-center">
|
<div class="col-md-4 text-center">
|
||||||
<!-- Conditionally render Start Icon -->
|
<!-- Conditionally render Start Icon -->
|
||||||
<i v-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
|
<i v-if="movement.toStation" class="fas fa-map-marker-alt"></i>
|
||||||
|
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
|
||||||
<i v-else class="fas fa-warehouse fa-2x"></i>
|
<i v-else class="fas fa-warehouse fa-2x"></i>
|
||||||
<p><strong>Start</strong></p>
|
<p><strong>Start</strong></p>
|
||||||
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
|
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
|
||||||
@ -300,7 +305,7 @@
|
|||||||
<!--------------------------------------------STATION CATEGORY---------------------------------------------------------------------->
|
<!--------------------------------------------STATION CATEGORY---------------------------------------------------------------------->
|
||||||
<div v-if="sortBy === 'station'">
|
<div v-if="sortBy === 'station'">
|
||||||
<div v-for="(items, station) in filteredStation" :key="stationName" :class="{'bg-light-gray': station === 'Unassign Station', 'bg-white': station !== 'Unassign Station'}" class="station-category card mt-3">
|
<div v-for="(items, station) in filteredStation" :key="stationName" :class="{'bg-light-gray': station === 'Unassign Station', 'bg-white': station !== 'Unassign Station'}" class="station-category card mt-3">
|
||||||
<!-- 📌 Station Header -->
|
<!-- Station Header -->
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<h3>{{ station }}</h3>
|
<h3>{{ station }}</h3>
|
||||||
<button class="btn btn-light" v-on:click="toggleCategory(station)">
|
<button class="btn btn-light" v-on:click="toggleCategory(station)">
|
||||||
@ -308,10 +313,10 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 📌 Show Items Under Each Station -->
|
<!-- Show Items Under Each Station -->
|
||||||
<div v-show="categoryVisible[station]" class="card-body">
|
<div v-show="categoryVisible[station]" class="card-body">
|
||||||
<div v-for="(group, itemId) in items" :key="itemId" class="row card">
|
<div v-for="(group, itemId) in items" :key="itemId" class="row card">
|
||||||
<!-- 📌 Item Header -->
|
<!-- Item Header -->
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<h2>Item : {{ group.uniqueID }}</h2>
|
<h2>Item : {{ group.uniqueID }}</h2>
|
||||||
<button class="btn btn-light" v-on:click="toggleCategory(itemId)">
|
<button class="btn btn-light" v-on:click="toggleCategory(itemId)">
|
||||||
@ -319,46 +324,52 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 📌 Show Movements for Each Item -->
|
<!-- Show Movements for Each Item -->
|
||||||
<div v-show="categoryVisible[itemId]" class="card-body">
|
<div v-show="categoryVisible[itemId]" class="card-body">
|
||||||
<div v-for="(movement, index) in group.movements.sort((a, b) => a.id - b.id).reverse()" :key="movement.id" class="movement-row">
|
<div v-for="(movement, index) in group.movements.sort((a, b) => a.id - b.id).reverse()" :key="movement.id" class="movement-row">
|
||||||
<div v-if="index === 0" class="row">
|
<div v-if="index === 0" class="row">
|
||||||
<strong>Latest Movement</strong>
|
<strong>Latest Movement</strong>
|
||||||
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
|
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
|
||||||
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther !== 'On Delivery' && movement.action !== 'Assign',
|
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther === 'Return',
|
||||||
'text-info': movement.action === 'Assign'}"
|
'text-success': movement.toStation !== null, 'text-info': movement.action === 'Assign' && movement.toStation === null}"
|
||||||
class="flex-shrink-0 text-nowrap"
|
class="flex-shrink-0 text-nowrap" style="max-width:90px; min-width:90px;">
|
||||||
style="max-width:90px; min-width:90px;">
|
|
||||||
|
|
||||||
{{ movement.action === 'Assign' ? 'Assign' : (movement.toOther === 'On Delivery' ? 'Receive' : 'Return') }}
|
{{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}
|
||||||
|
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1">
|
<!-- Send Date -->
|
||||||
<h4 class="fixed-label m-0 text-nowrap">Send Date:</h4>
|
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
|
||||||
<span class="fixed-value">{{ movement.sendDate }}</span>
|
<h4 class="fixed-label m-0 text-nowrap">{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}</h4>
|
||||||
|
<span class="fixed-value text-truncate">{{ movement.sendDate }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1">
|
<!-- Receive Date -->
|
||||||
|
<div v-if="movement.action !== 'Assign'" class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
|
||||||
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
|
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
|
||||||
<span class="fixed-value">{{ movement.receiveDate || 'Not arrive' }}</span>
|
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1">
|
<!-- Action -->
|
||||||
|
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:150px; min-width:150px;">
|
||||||
<h4 class="fixed-labelStatus m-0 text-nowrap">Action:</h4>
|
<h4 class="fixed-labelStatus m-0 text-nowrap">Action:</h4>
|
||||||
<span class="fixed-value">{{ movement.action }}</span>
|
<span class="fixed-value text-truncate">{{ movement.action }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1">
|
<!-- Status -->
|
||||||
|
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:160px; min-width:160px;">
|
||||||
<h4 class="fixed-labelStatus m-0 text-nowrap">Status:</h4>
|
<h4 class="fixed-labelStatus m-0 text-nowrap">Status:</h4>
|
||||||
<span class="fixed-value">{{ movement.latestStatus || movement.toOther }}</span>
|
<span class="fixed-value text-truncate" style="max-width:90px;">{{ movement.latestStatus || movement.toOther }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- More Details Button -->
|
||||||
<button class="btn btn-info btn-sm ms-auto" v-on:click="toggleDetails(movement.id)">
|
<button class="btn btn-info btn-sm ms-auto" v-on:click="toggleDetails(movement.id)">
|
||||||
More Details
|
More Details
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<h4 :class="movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'text-success' : 'text-danger'" class="text-nowrap ms-3">
|
<!-- Completion Status -->
|
||||||
|
<h4 :class="movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'text-success' : 'text-danger'"
|
||||||
|
class="text-nowrap ms-3">
|
||||||
{{ movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'Complete' : (movement.latestStatus === 'Ready To Deploy' ? 'Canceled' : 'Incomplete') }}
|
{{ movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'Complete' : (movement.latestStatus === 'Ready To Deploy' ? 'Canceled' : 'Incomplete') }}
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
@ -366,7 +377,8 @@
|
|||||||
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
|
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 text-center">
|
<div class="col-md-4 text-center">
|
||||||
<i v-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
|
<i v-if="movement.toStation" class="fas fa-map-marker-alt"></i>
|
||||||
|
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
|
||||||
<i v-else class="fas fa-warehouse fa-2x"></i>
|
<i v-else class="fas fa-warehouse fa-2x"></i>
|
||||||
<p><strong>Start</strong></p>
|
<p><strong>Start</strong></p>
|
||||||
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
|
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
|
||||||
@ -401,7 +413,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 📌 Single View History Button -->
|
<!-- Single View History Button -->
|
||||||
<button class="btn btn-light w-100 text-left" v-on:click="toggleHistory(itemId)">
|
<button class="btn btn-light w-100 text-left" v-on:click="toggleHistory(itemId)">
|
||||||
<i :class="historyVisible[itemId] ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"></i> View History
|
<i :class="historyVisible[itemId] ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"></i> View History
|
||||||
</button>
|
</button>
|
||||||
@ -410,19 +422,22 @@
|
|||||||
<div v-for="(movement, i) in group.movements.slice(1)" :key="i" class="row mt-2">
|
<div v-for="(movement, i) in group.movements.slice(1)" :key="i" class="row mt-2">
|
||||||
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
|
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
|
||||||
<!-- Movement Type -->
|
<!-- Movement Type -->
|
||||||
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther !== 'On Delivery' && movement.action !== 'Assign',
|
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther === 'Return',
|
||||||
'text-info': movement.action === 'Assign'}" class="flex-shrink-0 text-nowrap" style="max-width:90px; min-width:90px;">
|
'text-success': movement.toStation !== null, 'text-info': movement.action === 'Assign' && movement.toStation === null}"
|
||||||
{{ movement.action === 'Assign' ? 'Assign' : (movement.toOther === 'On Delivery' ? 'Receive' : 'Return') }}
|
class="flex-shrink-0 text-nowrap" style="max-width:90px; min-width:90px;">
|
||||||
|
|
||||||
|
{{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}
|
||||||
|
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<!-- Send Date -->
|
<!-- Send Date -->
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
|
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
|
||||||
<h4 class="fixed-label m-0 text-nowrap">Send Date:</h4>
|
<h4 class="fixed-label m-0 text-nowrap">{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}</h4>
|
||||||
<span class="fixed-value text-truncate">{{ movement.sendDate }}</span>
|
<span class="fixed-value text-truncate">{{ movement.sendDate }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Receive Date -->
|
<!-- Receive Date -->
|
||||||
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
|
<div v-if="movement.action !== 'Assign'" class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
|
||||||
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
|
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
|
||||||
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
|
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -452,7 +467,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- 📌 Details Section (Hidden by Default) -->
|
<!-- Details Section (Hidden by Default) -->
|
||||||
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
|
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 text-center">
|
<div class="col-md-4 text-center">
|
||||||
@ -548,6 +563,7 @@
|
|||||||
return {
|
return {
|
||||||
itemMovements: [],
|
itemMovements: [],
|
||||||
itemMovementCompleteDatatable: null,
|
itemMovementCompleteDatatable: null,
|
||||||
|
stationDatatable: null,
|
||||||
itemMovementNotCompleteDatatable: null,
|
itemMovementNotCompleteDatatable: null,
|
||||||
searchQuery: "",
|
searchQuery: "",
|
||||||
searchStation: "",
|
searchStation: "",
|
||||||
@ -572,28 +588,63 @@
|
|||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
},
|
},
|
||||||
|
|
||||||
groupedByStation() {
|
groupedByStation() {
|
||||||
let grouped = {};
|
let grouped = {};
|
||||||
this.itemMovements.forEach((movement) => {
|
this.itemMovements.forEach((movement) => {
|
||||||
let station = movement.toStationName || movement.lastStationName || "Unassign Station";
|
|
||||||
let itemId = movement.uniqueID;
|
|
||||||
|
|
||||||
if (!grouped[station]) {
|
if (movement.toStation !== null) {
|
||||||
grouped[station] = {};
|
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]) {
|
if (movement.lastStation !== null) {
|
||||||
grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
let station = movement.lastStationName;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
grouped[station][itemId].movements.push(movement);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort stations and move "Unassign Station" to the last position
|
// Sort stations and move "Unassign Station" to the last position
|
||||||
let sortedKeys = Object.keys(grouped).sort((a, b) => {
|
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;
|
if (b === "Unassign Station") return -1;
|
||||||
return a.localeCompare(b); // Normal sorting for other stations
|
return a.localeCompare(b);
|
||||||
});
|
});
|
||||||
|
|
||||||
let sortedGrouped = {};
|
let sortedGrouped = {};
|
||||||
@ -603,6 +654,7 @@
|
|||||||
|
|
||||||
return sortedGrouped;
|
return sortedGrouped;
|
||||||
},
|
},
|
||||||
|
|
||||||
filteredItems() {
|
filteredItems() {
|
||||||
if (!this.searchQuery.trim()) {
|
if (!this.searchQuery.trim()) {
|
||||||
return this.groupedItems;
|
return this.groupedItems;
|
||||||
@ -614,6 +666,7 @@
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
filteredStation() {
|
filteredStation() {
|
||||||
if (!this.searchStation) {
|
if (!this.searchStation) {
|
||||||
return this.groupedByStation;
|
return this.groupedByStation;
|
||||||
@ -684,6 +737,7 @@
|
|||||||
this.initAllTables();
|
this.initAllTables();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
initAllTables() {
|
initAllTables() {
|
||||||
if (this.itemMovementNotCompleteDatatable) {
|
if (this.itemMovementNotCompleteDatatable) {
|
||||||
this.itemMovementNotCompleteDatatable.destroy();
|
this.itemMovementNotCompleteDatatable.destroy();
|
||||||
@ -691,20 +745,23 @@
|
|||||||
if (this.itemMovementCompleteDatatable) {
|
if (this.itemMovementCompleteDatatable) {
|
||||||
this.itemMovementCompleteDatatable.destroy();
|
this.itemMovementCompleteDatatable.destroy();
|
||||||
}
|
}
|
||||||
|
if(this.stationDatatable) {
|
||||||
|
this.stationDatatable.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
this.itemMovementNotCompleteDatatable = $("#itemMovementNotCompleteDatatable").DataTable({
|
this.itemMovementNotCompleteDatatable = $("#itemMovementNotCompleteDatatable").DataTable({
|
||||||
data: this.itemMovements.filter((m) => m.movementComplete == 0),
|
data: this.itemMovements.filter((m) => m.movementComplete == 0),
|
||||||
columns: [
|
columns: [
|
||||||
{ title: "Unique Id", data: "id" },
|
{ title: "Unique Id", data: "id" },
|
||||||
{ title: "Product Code", data: "uniqueID" },
|
{ title: "Product Code", data: "uniqueID" },
|
||||||
|
{ title: "Action", data: "action" },
|
||||||
|
{ title: "Send Date", data: "sendDate" },
|
||||||
{ title: "From User", data: "toUserName" },
|
{ title: "From User", data: "toUserName" },
|
||||||
{ title: "Last User", data: "lastUserName" },
|
{ title: "Last User", data: "lastUserName" },
|
||||||
{ title: "From Station", data: "toStationName" },
|
{ title: "From Station", data: "toStationName" },
|
||||||
{ title: "From Store", data: "toStoreName" },
|
{ title: "From Store", data: "toStoreName" },
|
||||||
{ title: "Action", data: "action" },
|
|
||||||
{ title: "Start Status", data: "toOther" },
|
{ title: "Start Status", data: "toOther" },
|
||||||
{ title: "Quantity", data: "quantity" },
|
{ title: "Quantity", data: "quantity" },
|
||||||
{ title: "Send Date", data: "sendDate" },
|
|
||||||
{
|
{
|
||||||
title: "Note",
|
title: "Note",
|
||||||
data: "consignmentNote",
|
data: "consignmentNote",
|
||||||
@ -740,22 +797,22 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.itemMovementCompleteDatatable = $("#itemMovementCompleteDatatable").DataTable({
|
this.itemMovementCompleteDatatable = $("#itemMovementCompleteDatatable").DataTable({
|
||||||
data: this.itemMovements.filter((m) => m.movementComplete == 1),
|
data: this.itemMovements.filter((m) => m.movementComplete == 1 && m.action !== "Assign"),
|
||||||
columns: [
|
columns: [
|
||||||
{ title: "Unique Id", data: "id" },
|
{ title: "Unique Id", data: "id" },
|
||||||
{ title: "Product Code", data: "uniqueID" },
|
{ 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: "From User", data: "toUserName" },
|
||||||
{ title: "Last User", data: "lastUserName" },
|
{ title: "Last User", data: "lastUserName" },
|
||||||
{ title: "From Station", data: "toStationName" },
|
{ title: "From Station", data: "toStationName" },
|
||||||
{ title: "Last Station", data: "lastStationName" },
|
{ title: "Last Station", data: "lastStationName" },
|
||||||
{ title: "From Store", data: "toStoreName" },
|
{ title: "From Store", data: "toStoreName" },
|
||||||
{ title: "Last Store", data: "lastStoreName" },
|
{ title: "Last Store", data: "lastStoreName" },
|
||||||
{ title: "Action", data: "action" },
|
|
||||||
{ title: "Start Status", data: "toOther" },
|
{ title: "Start Status", data: "toOther" },
|
||||||
{ title: "Latest Status", data: "latestStatus" },
|
{ title: "Latest Status", data: "latestStatus" },
|
||||||
{ title: "Qty", data: "quantity" },
|
{ title: "Qty", data: "quantity" },
|
||||||
{ title: "Send Date", data: "sendDate" },
|
|
||||||
{ title: "Receive Date", data: "receiveDate" },
|
|
||||||
{ title: "Note",
|
{ title: "Note",
|
||||||
data: "consignmentNote",
|
data: "consignmentNote",
|
||||||
render: function (data, type, full, meta) {
|
render: function (data, type, full, meta) {
|
||||||
@ -788,16 +845,64 @@
|
|||||||
],
|
],
|
||||||
responsive: true,
|
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 `<a href="${data}" target="_blank" data-lightbox="image-1">
|
||||||
|
<img src="${data}" alt="Image" class="img-thumbnail" style="width: 100px; height: 100px;" />
|
||||||
|
</a>`;
|
||||||
|
}
|
||||||
|
else if (isPdf) {
|
||||||
|
return `<a href="${data}" target="_blank">
|
||||||
|
<img src="https://upload.wikimedia.org/wikipedia/commons/8/87/PDF_file_icon.svg"
|
||||||
|
alt="PDF Document" class="img-thumbnail"
|
||||||
|
style="width: 50px; height: 50px;" />
|
||||||
|
<br>View PDF
|
||||||
|
</a>`;
|
||||||
|
} else {
|
||||||
|
return `<a href="${data}" target="_blank">Download File</a>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ title: "Remark", data: "remark" },
|
||||||
|
],
|
||||||
|
responsive: true,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleCategory(itemId) {
|
toggleCategory(itemId) {
|
||||||
this.categoryVisible[itemId] = !this.categoryVisible[itemId];
|
this.categoryVisible[itemId] = !this.categoryVisible[itemId];
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleHistory(itemId) {
|
toggleHistory(itemId) {
|
||||||
this.historyVisible[itemId] = !this.historyVisible[itemId];
|
this.historyVisible[itemId] = !this.historyVisible[itemId];
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleDetails(movementId) {
|
toggleDetails(movementId) {
|
||||||
this.detailsVisible[movementId] = !this.detailsVisible[movementId];
|
this.detailsVisible[movementId] = !this.detailsVisible[movementId];
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSorting() {
|
handleSorting() {
|
||||||
this.renderTables();
|
this.renderTables();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -261,6 +261,19 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</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" class="form-control" v-model="remark" />
|
||||||
|
</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" class="form-control-file" v-on:change="handleFileUpload" accept="image/png, image/jpeg, application/pdf" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button type="submit" class="btn btn-primary">Deploy Station</button>
|
<button type="submit" class="btn btn-primary">Deploy Station</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -457,7 +470,7 @@
|
|||||||
ConsignmentNote: this.consignmentNote,
|
ConsignmentNote: this.consignmentNote,
|
||||||
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
LastUser: this.currentUserId,
|
LastUser: this.currentUserId,
|
||||||
LastStore: this.thisItem.currentStoreId,
|
LastStore: this.thisItem.toStore,
|
||||||
LastStation: this.selectedStation,
|
LastStation: this.selectedStation,
|
||||||
LatestStatus: "Delivered",
|
LatestStatus: "Delivered",
|
||||||
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
@ -498,7 +511,8 @@
|
|||||||
try {
|
try {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const formData = {
|
const formData = {
|
||||||
Id : this.thisItem.id,
|
Id: this.thisItem.id,
|
||||||
|
LastStore: this.thisItem.toStore,
|
||||||
LatestStatus: "Delivered",
|
LatestStatus: "Delivered",
|
||||||
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
MovementComplete: true,
|
MovementComplete: true,
|
||||||
|
|||||||
@ -1248,20 +1248,24 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(returnMovement.ConsignmentNote))
|
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);
|
var bytes = Convert.FromBase64String(returnMovement.ConsignmentNote);
|
||||||
string filePath = "";
|
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))
|
if (IsImage(bytes))
|
||||||
{
|
{
|
||||||
filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/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/request/" + uniqueName + returnMovement.ItemId + "_Request.jpg";
|
returnMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Return.jpg";
|
||||||
}
|
}
|
||||||
else if (IsPdf(bytes))
|
else if (IsPdf(bytes))
|
||||||
{
|
{
|
||||||
filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/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/request/" + uniqueName + returnMovement.ItemId + "_Request.pdf";
|
returnMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Return.pdf";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1270,16 +1274,13 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
|
|
||||||
await System.IO.File.WriteAllBytesAsync(filePath, bytes);
|
await System.IO.File.WriteAllBytesAsync(filePath, bytes);
|
||||||
}
|
}
|
||||||
// 1. Simpan returnMovement dalam database
|
|
||||||
_centralDbContext.ItemMovements.Add(returnMovement);
|
_centralDbContext.ItemMovements.Add(returnMovement);
|
||||||
await _centralDbContext.SaveChangesAsync();
|
await _centralDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
// 2. Cari item movement yang ada ItemId & MovementComplete = false
|
|
||||||
var updateItemIdMovement = await _centralDbContext.ItemMovements
|
var updateItemIdMovement = await _centralDbContext.ItemMovements
|
||||||
.FirstOrDefaultAsync(m => m.Id == returnMovement.Id && m.MovementComplete == false);
|
.FirstOrDefaultAsync(m => m.Id == returnMovement.Id && m.MovementComplete == false);
|
||||||
|
|
||||||
|
|
||||||
// 3. Jika wujud, update MovementId
|
|
||||||
if (updateItemIdMovement != null)
|
if (updateItemIdMovement != null)
|
||||||
{
|
{
|
||||||
var returnItems = await _centralDbContext.Items.FindAsync(updateItemIdMovement.ItemId);
|
var returnItems = await _centralDbContext.Items.FindAsync(updateItemIdMovement.ItemId);
|
||||||
@ -1289,21 +1290,10 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
returnItems.MovementId = updateItemIdMovement.Id;
|
returnItems.MovementId = updateItemIdMovement.Id;
|
||||||
returnItems.ItemStatus = 2;
|
returnItems.ItemStatus = 2;
|
||||||
_centralDbContext.Items.Update(returnItems);
|
_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
|
return Json(new
|
||||||
{
|
{
|
||||||
updateItemIdMovement.Id,
|
updateItemIdMovement.Id,
|
||||||
@ -1326,7 +1316,6 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
updateItemIdMovement.MovementComplete
|
updateItemIdMovement.MovementComplete
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -1346,20 +1335,24 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(stationMovement.ConsignmentNote))
|
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);
|
var bytes = Convert.FromBase64String(stationMovement.ConsignmentNote);
|
||||||
string filePath = "";
|
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))
|
if (IsImage(bytes))
|
||||||
{
|
{
|
||||||
filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/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/request/" + uniqueName + stationMovement.ItemId + "_Request.jpg";
|
stationMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Station.jpg";
|
||||||
}
|
}
|
||||||
else if (IsPdf(bytes))
|
else if (IsPdf(bytes))
|
||||||
{
|
{
|
||||||
filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/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/request/" + uniqueName + stationMovement.ItemId + "_Request.pdf";
|
stationMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Station.pdf";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1368,16 +1361,14 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
|
|
||||||
await System.IO.File.WriteAllBytesAsync(filePath, bytes);
|
await System.IO.File.WriteAllBytesAsync(filePath, bytes);
|
||||||
}
|
}
|
||||||
// 1. Simpan returnMovement dalam database
|
|
||||||
_centralDbContext.ItemMovements.Add(stationMovement);
|
_centralDbContext.ItemMovements.Add(stationMovement);
|
||||||
await _centralDbContext.SaveChangesAsync();
|
await _centralDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
// 2. Cari item movement yang ada ItemId & MovementComplete = false
|
|
||||||
var updateItemIdMovement = await _centralDbContext.ItemMovements.Include(i => i.Item)
|
var updateItemIdMovement = await _centralDbContext.ItemMovements.Include(i => i.Item)
|
||||||
.FirstOrDefaultAsync(m => m.Id == stationMovement.Id);
|
.FirstOrDefaultAsync(m => m.Id == stationMovement.Id);
|
||||||
|
|
||||||
|
|
||||||
// 3. Jika wujud, update MovementId
|
|
||||||
if (updateItemIdMovement != null)
|
if (updateItemIdMovement != null)
|
||||||
{
|
{
|
||||||
var returnItems = await _centralDbContext.Items.FindAsync(updateItemIdMovement.ItemId);
|
var returnItems = await _centralDbContext.Items.FindAsync(updateItemIdMovement.ItemId);
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
Loading…
Reference in New Issue
Block a user