Gitlab@Informatics

Skip to content
Snippets Groups Projects
Commit 70653915 authored by Kritkhanin Anantakul's avatar Kritkhanin Anantakul
Browse files

fix targettable

parent 238f40c9
No related branches found
No related tags found
No related merge requests found
...@@ -2,20 +2,18 @@ ...@@ -2,20 +2,18 @@
import { ref, onMounted, computed } from 'vue' import { ref, onMounted, computed } from 'vue'
import { useProductionTargetStore } from '@/stores/productionTarget' import { useProductionTargetStore } from '@/stores/productionTarget'
import { usePageContextStore } from '@/stores/pageContext' import { usePageContextStore } from '@/stores/pageContext'
// ⬇️ ใช้ dateStore แทน props
import { useDateStore } from '@/stores/dateStore' import { useDateStore } from '@/stores/dateStore'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
const productionTargetStore = useProductionTargetStore() const productionTargetStore = useProductionTargetStore()
const pageContext = usePageContextStore() const pageContext = usePageContextStore()
const { currentDate: selectedDate } = storeToRefs(useDateStore()) // ✅ ใช้จาก store const { currentDate: selectedDate } = storeToRefs(useDateStore())
const currentPage = computed(() => pageContext.currentPage) const currentPage = computed(() => pageContext.currentPage)
const headers = ref([ const headers = ref([
{ title: "รหัส", key: "id" }, { title: "รหัส", key: "id" },
{ title: "ชื่อ", key: "name" }, { title: "ชื่อ", key: "name" },
{ title: "ขนาด", key: "size" }, { title: "ขนาด", key: "size" },
{ title: "แบรนด์", key: "brand" }, { title: "แบรนด์", key: "brand" },
{ title: "ชนิด", key: "type" }, { title: "ชนิด", key: "type" },
...@@ -29,12 +27,15 @@ const groupBy = [{ key: 'customerGroup' }] ...@@ -29,12 +27,15 @@ const groupBy = [{ key: 'customerGroup' }]
const savingRowIds = ref<number[]>([]) const savingRowIds = ref<number[]>([])
const recentlySavedIds = ref<number[]>([]) const recentlySavedIds = ref<number[]>([])
// ตั้งค่า delay (ms) หลังจากเรียก edit function ก่อน re-fetch data
const UPDATE_DELAY = 500
onMounted(async () => { onMounted(async () => {
await productionTargetStore.fetchProductionTargets() await productionTargetStore.fetchProductionTargets()
}) })
// ✅ กรองตาม PageID + selectedDate จาก store
const productionData = computed(() => { const productionData = computed(() => {
// map rawData ให้มี field ที่จำเป็นสำหรับ UI และ API
const rawData = productionTargetStore.productionTargets const rawData = productionTargetStore.productionTargets
.filter((target) => .filter((target) =>
target.page?.PageID === currentPage.value && target.page?.PageID === currentPage.value &&
...@@ -44,6 +45,10 @@ const productionData = computed(() => { ...@@ -44,6 +45,10 @@ const productionData = computed(() => {
const customerName = target.order?.customer?.name || 'ไม่ระบุลูกค้า' const customerName = target.order?.customer?.name || 'ไม่ระบุลูกค้า'
return { return {
id: target.ProductionTargetID, id: target.ProductionTargetID,
// เปลี่ยน field จาก target.item?.ItemID เป็น target.item?.id
// ให้แน่ใจว่าฟิลด์นี้ตรงกับ structure ที่ backend ส่งมา
itemID: target.item?.id,
itemType: target.itemType,
name: target.item?.name || target.item?.brand || 'ไม่พบข้อมูล', name: target.item?.name || target.item?.brand || 'ไม่พบข้อมูล',
size: target.item?.size || '-', size: target.item?.size || '-',
brand: target.item?.brand || '-', brand: target.item?.brand || '-',
...@@ -57,11 +62,13 @@ const productionData = computed(() => { ...@@ -57,11 +62,13 @@ const productionData = computed(() => {
} }
}) })
// 🔄 รวมรายการซ้ำในกลุ่ม "วันนี้" console.log('✅ rawData:', rawData)
const todayGroupMap = new Map<string, any>()
// รวมรายการซ้ำในกลุ่ม "วันนี้"
const todayGroupMap = new Map<string, any>()
rawData.forEach(item => { rawData.forEach(item => {
const key = `${item.name}|${item.size}|${item.brand}|${item.type}` // key รวม itemID เพื่อให้แน่ใจว่า itemID ไม่หาย
const key = `${item.itemID}|${item.name}|${item.size}|${item.brand}|${item.type}`
if (todayGroupMap.has(key)) { if (todayGroupMap.has(key)) {
const existing = todayGroupMap.get(key) const existing = todayGroupMap.get(key)
existing.target += item.target existing.target += item.target
...@@ -69,14 +76,18 @@ const productionData = computed(() => { ...@@ -69,14 +76,18 @@ const productionData = computed(() => {
} else { } else {
todayGroupMap.set(key, { todayGroupMap.set(key, {
...item, ...item,
customerGroup: '0-รวมทั้งหมด', // กลุ่ม "วันนี้" // force ให้แน่ใจว่า itemID กับ itemType ถูกเก็บไว้
itemID: item.itemID,
itemType: item.itemType,
customerGroup: '0-รวมทั้งหมด',
}) })
} }
}) })
const todayItems = Array.from(todayGroupMap.values()) const todayItems = Array.from(todayGroupMap.values())
console.log('✅ todayItems:', todayItems)
// กลุ่มรายลูกค้า (ไม่ยุบ) // กลุ่มรายลูกค้า (ไม่รวมกัน)
const customerItems = rawData.map(item => ({ const customerItems = rawData.map(item => ({
...item, ...item,
customerGroup: `1-${item.customer}`, customerGroup: `1-${item.customer}`,
...@@ -85,10 +96,6 @@ const productionData = computed(() => { ...@@ -85,10 +96,6 @@ const productionData = computed(() => {
return [...todayItems, ...customerItems] return [...todayItems, ...customerItems]
}) })
async function saveActualProduced(item: any) { async function saveActualProduced(item: any) {
const id = item.id const id = item.id
const produced = Number(item.produced) const produced = Number(item.produced)
...@@ -98,22 +105,34 @@ async function saveActualProduced(item: any) { ...@@ -98,22 +105,34 @@ async function saveActualProduced(item: any) {
savingRowIds.value.push(id) savingRowIds.value.push(id)
try { try {
await productionTargetStore.editProductionTarget(id, { if (item.customerGroup?.startsWith('0-')) {
ActualProduced: produced, await productionTargetStore.editTodayTarget({
}) itemID: item.itemID,
await productionTargetStore.fetchProductionTargets() itemType: item.itemType,
date: selectedDate.value.split('-').reverse().join('/'),
actualProduced: produced,
})
// ✅ optional: อาจต้อง fetch ใหม่ เพราะรวม target หลายรายการ
await productionTargetStore.fetchProductionTargets()
} else {
await productionTargetStore.editProductionTarget(id, {
ActualProduced: produced,
})
// ❌ ไม่ต้อง fetch
}
recentlySavedIds.value.push(id) recentlySavedIds.value.push(id)
setTimeout(() => { setTimeout(() => {
recentlySavedIds.value = recentlySavedIds.value.filter(rowId => rowId !== id) recentlySavedIds.value = recentlySavedIds.value.filter((rowId) => rowId !== id)
}, 1000) }, 1000)
} catch (e) { } catch (e) {
console.error('❌ Save failed:', e) console.error('❌ Save failed:', e)
} finally { } finally {
savingRowIds.value = savingRowIds.value.filter(rowId => rowId !== id) savingRowIds.value = savingRowIds.value.filter((rowId) => rowId !== id)
} }
} }
function blockInvalidKeys(event: KeyboardEvent) { function blockInvalidKeys(event: KeyboardEvent) {
const invalidKeys = ['e', 'E', '+', '-', '.', ','] const invalidKeys = ['e', 'E', '+', '-', '.', ',']
if (invalidKeys.includes(event.key)) { if (invalidKeys.includes(event.key)) {
...@@ -132,25 +151,24 @@ function blockInvalidKeys(event: KeyboardEvent) { ...@@ -132,25 +151,24 @@ function blockInvalidKeys(event: KeyboardEvent) {
item-value="name" item-value="name"
hide-default-footer hide-default-footer
> >
<template v-slot:group-header="{ item, columns, toggleGroup, isGroupOpen }"> <template v-slot:group-header="{ item, columns, toggleGroup, isGroupOpen }">
<tr> <tr>
<td :colspan="columns.length"> <td :colspan="columns.length">
<div class="d-flex align-center"> <div class="d-flex align-center">
<v-btn <v-btn
:icon="isGroupOpen(item) ? '$expand' : '$next'" :icon="isGroupOpen(item) ? '$expand' : '$next'"
density="comfortable" density="comfortable"
size="x-small" size="x-small"
variant="outlined" variant="outlined"
@click="toggleGroup(item)" @click="toggleGroup(item)"
/> />
<span class="ms-2 text-caption"> <span class="ms-2 text-caption">
{{ item.value.startsWith('0-') ? 'วันนี้' : 'ลูกค้า: ' + item.value.slice(2) }} {{ item.value.startsWith('0-') ? 'วันนี้' : 'ลูกค้า: ' + item.value.slice(2) }}
</span> </span>
</div> </div>
</td> </td>
</tr> </tr>
</template> </template>
<template v-slot:item.produced="{ item }"> <template v-slot:item.produced="{ item }">
<div class="save-cell-wrapper" style="position: relative; display: inline-block;"> <div class="save-cell-wrapper" style="position: relative; display: inline-block;">
...@@ -190,10 +208,19 @@ function blockInvalidKeys(event: KeyboardEvent) { ...@@ -190,10 +208,19 @@ function blockInvalidKeys(event: KeyboardEvent) {
.fade-check { .fade-check {
animation: fadeOut 1s ease-out forwards; animation: fadeOut 1s ease-out forwards;
} }
@keyframes fadeOut { @keyframes fadeOut {
0% { opacity: 1; transform: scale(1); } 0% {
80% { opacity: 1; transform: scale(1.2); } opacity: 1;
100% { opacity: 0; transform: scale(1); } transform: scale(1);
}
80% {
opacity: 1;
transform: scale(1.2);
}
100% {
opacity: 0;
transform: scale(1);
}
} }
</style> </style>
...@@ -29,3 +29,10 @@ export async function updateProductionTarget( ...@@ -29,3 +29,10 @@ export async function updateProductionTarget(
export async function deleteProductionTarget(id: number): Promise<void> { export async function deleteProductionTarget(id: number): Promise<void> {
await http.delete(`/production-targets/${id}`); await http.delete(`/production-targets/${id}`);
} }
export async function editTodayTarget(payload: {
ProductionTargetID: number;
ActualProduced: number;
}): Promise<void> {
await http.post('/production-targets/edit-today', payload);
}
\ No newline at end of file
...@@ -53,7 +53,11 @@ export const useProductionTargetStore = defineStore('productionTarget', () => { ...@@ -53,7 +53,11 @@ export const useProductionTargetStore = defineStore('productionTarget', () => {
const updated = await productionTargetService.updateProductionTarget(id, payload); const updated = await productionTargetService.updateProductionTarget(id, payload);
const index = productionTargets.value.findIndex(p => p.ProductionTargetID === id); const index = productionTargets.value.findIndex(p => p.ProductionTargetID === id);
if (index !== -1) { if (index !== -1) {
productionTargets.value[index] = updated; // ✅ อัปเดตค่าจริงใน local state เพื่อให้ computed re-render
productionTargets.value[index] = {
...productionTargets.value[index],
...payload, // ใช้ payload (เช่น ActualProduced) ทับของเดิม
};
} }
} catch (e: any) { } catch (e: any) {
error.value = e.message || 'Unknown Error'; error.value = e.message || 'Unknown Error';
...@@ -61,6 +65,21 @@ export const useProductionTargetStore = defineStore('productionTarget', () => { ...@@ -61,6 +65,21 @@ export const useProductionTargetStore = defineStore('productionTarget', () => {
loading.value = false; loading.value = false;
} }
} }
async function editTodayTarget(payload: { ProductionTargetID: number, ActualProduced: number }) {
loading.value = true;
error.value = null;
try {
await productionTargetService.editTodayTarget(payload);
} catch (e: any) {
error.value = e.message || 'Unknown Error';
throw e; // เพื่อให้ caller เช่นหน้า UI จับ error ได้
} finally {
loading.value = false;
}
}
async function removeProductionTarget(id: number) { async function removeProductionTarget(id: number) {
loading.value = true; loading.value = true;
...@@ -82,6 +101,7 @@ export const useProductionTargetStore = defineStore('productionTarget', () => { ...@@ -82,6 +101,7 @@ export const useProductionTargetStore = defineStore('productionTarget', () => {
fetchProductionTargets, fetchProductionTargets,
fetchProductionTarget, fetchProductionTarget,
addProductionTarget, addProductionTarget,
editTodayTarget,
editProductionTarget, editProductionTarget,
removeProductionTarget, removeProductionTarget,
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment