Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -2,40 +2,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import api from 'src/services/api'
|
||||
|
||||
function normalizeTextForMatch (v) {
|
||||
return String(v || '')
|
||||
.trim()
|
||||
.toUpperCase()
|
||||
.normalize('NFD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
}
|
||||
|
||||
// Production ekranlari icin beden grup tespiti helper'i.
|
||||
// Ozel kural:
|
||||
// YETISKIN/GARSON = GARSON ve URUN ANA GRUBU "GOMLEK ATA YAKA" veya "GOMLEK KLASIK" ise => yas
|
||||
export function detectProductionBedenGroup (bedenList, urunAnaGrubu = '', urunKategori = '', yetiskinGarson = '') {
|
||||
const list = Array.isArray(bedenList) ? bedenList : []
|
||||
const hasLetterSizes = list
|
||||
.map(v => String(v || '').trim().toUpperCase())
|
||||
.some(v => ['XS', 'S', 'M', 'L', 'XL', '2XL', '3XL', '4XL', '5XL', '6XL', '7XL'].includes(v))
|
||||
|
||||
const ana = normalizeTextForMatch(urunAnaGrubu)
|
||||
const kat = normalizeTextForMatch(urunKategori)
|
||||
const yg = normalizeTextForMatch(yetiskinGarson)
|
||||
|
||||
if ((kat.includes('GARSON') || yg.includes('GARSON')) &&
|
||||
(ana.includes('GOMLEK ATAYAKA') || ana.includes('GOMLEK ATA YAKA') || ana.includes('GOMLEK KLASIK'))) {
|
||||
return 'yas'
|
||||
}
|
||||
|
||||
if (hasLetterSizes) return 'gom'
|
||||
if ((ana.includes('AYAKKABI') || kat.includes('AYAKKABI')) && (kat.includes('GARSON') || yg.includes('GARSON'))) return 'ayk_garson'
|
||||
if (kat.includes('GARSON') || yg.includes('GARSON') || ana.includes('GARSON')) return 'yas'
|
||||
if (ana.includes('PANTOLON') && kat.includes('YETISKIN')) return 'pan'
|
||||
if (ana.includes('AKSESUAR')) return 'aksbir'
|
||||
return 'tak'
|
||||
}
|
||||
|
||||
function extractApiErrorMessage (err, fallback) {
|
||||
const data = err?.response?.data
|
||||
if (typeof data === 'string' && data.trim()) return data
|
||||
@@ -70,12 +36,40 @@ export const useOrderProductionItemStore = defineStore('orderproductionitems', {
|
||||
products: [],
|
||||
colorOptionsByCode: {},
|
||||
secondColorOptionsByKey: {},
|
||||
productAttributesByItemType: {},
|
||||
cdItemLookups: null,
|
||||
cdItemDraftsByCode: {},
|
||||
productAttributeDraftsByCode: {},
|
||||
loading: false,
|
||||
saving: false,
|
||||
error: null
|
||||
}),
|
||||
|
||||
getters: {
|
||||
productCodeSet (state) {
|
||||
const set = new Set()
|
||||
for (const p of (state.products || [])) {
|
||||
const code = String(p?.ProductCode || '').trim().toUpperCase()
|
||||
if (code) set.add(code)
|
||||
}
|
||||
return set
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
classifyItemCode (value) {
|
||||
const normalized = String(value || '').trim().toUpperCase()
|
||||
if (!normalized) {
|
||||
return { normalized: '', mode: 'empty', exists: false }
|
||||
}
|
||||
const exists = this.productCodeSet.has(normalized)
|
||||
return {
|
||||
normalized,
|
||||
mode: exists ? 'existing' : 'new',
|
||||
exists
|
||||
}
|
||||
},
|
||||
|
||||
async fetchHeader (orderHeaderID) {
|
||||
if (!orderHeaderID) {
|
||||
this.header = null
|
||||
@@ -166,6 +160,62 @@ export const useOrderProductionItemStore = defineStore('orderproductionitems', {
|
||||
return []
|
||||
}
|
||||
},
|
||||
async fetchProductAttributes (itemTypeCode = 1) {
|
||||
const key = String(itemTypeCode || 1)
|
||||
if (this.productAttributesByItemType[key]) {
|
||||
return this.productAttributesByItemType[key]
|
||||
}
|
||||
try {
|
||||
const res = await api.get('/product-attributes', { params: { itemTypeCode } })
|
||||
const list = Array.isArray(res?.data) ? res.data : []
|
||||
this.productAttributesByItemType[key] = list
|
||||
return list
|
||||
} catch (err) {
|
||||
this.error = err?.response?.data || err?.message || 'Urun ozellikleri alinamadi'
|
||||
return []
|
||||
}
|
||||
},
|
||||
async fetchCdItemLookups (force = false) {
|
||||
if (this.cdItemLookups && !force) return this.cdItemLookups
|
||||
try {
|
||||
const res = await api.get('/orders/production-items/cditem-lookups')
|
||||
this.cdItemLookups = res?.data || null
|
||||
return this.cdItemLookups
|
||||
} catch (err) {
|
||||
this.error = err?.response?.data || err?.message || 'cdItem lookup listesi alinamadi'
|
||||
return null
|
||||
}
|
||||
},
|
||||
setCdItemDraft (itemCode, draft) {
|
||||
const code = String(itemCode || '').trim().toUpperCase()
|
||||
if (!code) return
|
||||
this.cdItemDraftsByCode = {
|
||||
...this.cdItemDraftsByCode,
|
||||
[code]: {
|
||||
...(draft || {}),
|
||||
ItemCode: code,
|
||||
ItemTypeCode: Number(draft?.ItemTypeCode || 1)
|
||||
}
|
||||
}
|
||||
},
|
||||
getCdItemDraft (itemCode) {
|
||||
const code = String(itemCode || '').trim().toUpperCase()
|
||||
if (!code) return null
|
||||
return this.cdItemDraftsByCode[code] || null
|
||||
},
|
||||
setProductAttributeDraft (itemCode, rows) {
|
||||
const code = String(itemCode || '').trim().toUpperCase()
|
||||
if (!code) return
|
||||
this.productAttributeDraftsByCode = {
|
||||
...this.productAttributeDraftsByCode,
|
||||
[code]: Array.isArray(rows) ? rows : []
|
||||
}
|
||||
},
|
||||
getProductAttributeDraft (itemCode) {
|
||||
const code = String(itemCode || '').trim().toUpperCase()
|
||||
if (!code) return []
|
||||
return this.productAttributeDraftsByCode[code] || []
|
||||
},
|
||||
async validateUpdates (orderHeaderID, lines) {
|
||||
if (!orderHeaderID) return { missingCount: 0, missing: [] }
|
||||
|
||||
@@ -186,7 +236,7 @@ export const useOrderProductionItemStore = defineStore('orderproductionitems', {
|
||||
this.saving = false
|
||||
}
|
||||
},
|
||||
async applyUpdates (orderHeaderID, lines, insertMissing) {
|
||||
async applyUpdates (orderHeaderID, lines, insertMissing, cdItems = [], productAttributes = []) {
|
||||
if (!orderHeaderID) return { updated: 0, inserted: 0 }
|
||||
|
||||
this.saving = true
|
||||
@@ -195,7 +245,7 @@ export const useOrderProductionItemStore = defineStore('orderproductionitems', {
|
||||
try {
|
||||
const res = await api.post(
|
||||
`/orders/production-items/${encodeURIComponent(orderHeaderID)}/apply`,
|
||||
{ lines, insertMissing }
|
||||
{ lines, insertMissing, cdItems, productAttributes }
|
||||
)
|
||||
return res?.data || { updated: 0, inserted: 0 }
|
||||
} catch (err) {
|
||||
|
||||
@@ -42,20 +42,21 @@ export function buildComboKey(row, beden) {
|
||||
|
||||
|
||||
|
||||
export const BEDEN_SCHEMA = [
|
||||
{ key: 'tak', title: 'TAKIM ELBISE', values: ['44','46','48','50','52','54','56','58','60','62','64','66','68','70','72','74'] },
|
||||
{ key: 'ayk', title: 'AYAKKABI', values: ['39','40','41','42','43','44','45'] },
|
||||
{ key: 'ayk_garson', title: 'AYAKKABI GARSON', values: ['22','23','24','25','26','27','28','29','30','31','32','33','34','35','STD'] },
|
||||
{ key: 'yas', title: 'YAS', values: ['2','4','6','8','10','12','14'] },
|
||||
{ key: 'pan', title: 'PANTOLON', values: ['38','40','42','44','46','48','50','52','54','56','58','60','62','64','66','68'] },
|
||||
{ key: 'gom', title: 'GOMLEK', values: ['XS','S','M','L','XL','2XL','3XL','4XL','5XL','6XL','7XL'] },
|
||||
{ key: 'aksbir', title: 'AKSESUAR', values: [' ', '44', 'STD', '110', '115', '120', '125', '130', '135'] }
|
||||
]
|
||||
const SIZE_GROUP_TITLES = {
|
||||
tak: 'TAKIM ELBISE',
|
||||
ayk: 'AYAKKABI',
|
||||
ayk_garson: 'AYAKKABI GARSON',
|
||||
yas: 'YAS',
|
||||
pan: 'PANTOLON',
|
||||
gom: 'GOMLEK',
|
||||
aksbir: 'AKSESUAR'
|
||||
}
|
||||
|
||||
export const schemaByKey = BEDEN_SCHEMA.reduce((m, g) => {
|
||||
m[g.key] = g
|
||||
return m
|
||||
}, {})
|
||||
const FALLBACK_SCHEMA_MAP = {
|
||||
tak: { key: 'tak', title: 'TAKIM ELBISE', values: ['44', '46', '48', '50', '52', '54', '56', '58', '60', '62', '64', '66', '68', '70', '72', '74'] }
|
||||
}
|
||||
|
||||
export const schemaByKey = { ...FALLBACK_SCHEMA_MAP }
|
||||
|
||||
const productSizeMatchCache = {
|
||||
loaded: false,
|
||||
@@ -111,6 +112,23 @@ function setProductSizeMatchCache(payload) {
|
||||
productSizeMatchCache.schemas = normalizedSchemas
|
||||
}
|
||||
|
||||
function buildSchemaMapFromCacheSchemas() {
|
||||
const out = {}
|
||||
const src = productSizeMatchCache.schemas || {}
|
||||
for (const [keyRaw, valuesRaw] of Object.entries(src)) {
|
||||
const key = String(keyRaw || '').trim()
|
||||
if (!key) continue
|
||||
const values = Array.isArray(valuesRaw) ? valuesRaw : []
|
||||
out[key] = {
|
||||
key,
|
||||
title: SIZE_GROUP_TITLES[key] || key.toUpperCase(),
|
||||
values: values.map(v => String(v == null ? '' : v))
|
||||
}
|
||||
}
|
||||
if (!out.tak) out.tak = { ...FALLBACK_SCHEMA_MAP.tak }
|
||||
return out
|
||||
}
|
||||
|
||||
|
||||
export const stockMap = ref({})
|
||||
export const bedenStock = ref([])
|
||||
@@ -257,25 +275,17 @@ export const useOrderEntryStore = defineStore('orderentry', {
|
||||
,
|
||||
/* ===========================================================
|
||||
🧩 initSchemaMap — BEDEN ŞEMA İNİT
|
||||
- TEK SOURCE OF TRUTH: BEDEN_SCHEMA
|
||||
- TEK SOURCE OF TRUTH: SQL mk_size_group (cache)
|
||||
=========================================================== */
|
||||
initSchemaMap() {
|
||||
if (this.schemaMap && Object.keys(this.schemaMap).length > 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const map = {}
|
||||
|
||||
for (const g of BEDEN_SCHEMA) {
|
||||
map[g.key] = {
|
||||
key: g.key,
|
||||
title: g.title,
|
||||
values: [...g.values]
|
||||
}
|
||||
this.schemaMap = buildSchemaMapFromCacheSchemas()
|
||||
if (!Object.keys(this.schemaMap).length) {
|
||||
this.schemaMap = { ...FALLBACK_SCHEMA_MAP }
|
||||
}
|
||||
|
||||
this.schemaMap = map
|
||||
|
||||
console.log(
|
||||
'🧩 schemaMap INIT edildi:',
|
||||
Object.keys(this.schemaMap)
|
||||
@@ -284,17 +294,20 @@ export const useOrderEntryStore = defineStore('orderentry', {
|
||||
|
||||
async ensureProductSizeMatchRules($q = null, force = false) {
|
||||
if (!force && productSizeMatchCache.loaded && productSizeMatchCache.rules.length > 0) {
|
||||
this.schemaMap = buildSchemaMapFromCacheSchemas()
|
||||
return true
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await api.get('/product-size-match/rules')
|
||||
setProductSizeMatchCache(res?.data || {})
|
||||
this.schemaMap = buildSchemaMapFromCacheSchemas()
|
||||
return true
|
||||
} catch (err) {
|
||||
if (force) {
|
||||
resetProductSizeMatchCache()
|
||||
}
|
||||
this.schemaMap = { ...FALLBACK_SCHEMA_MAP }
|
||||
console.warn('⚠ product-size-match rules alınamadı:', err)
|
||||
$q?.notify?.({
|
||||
type: 'warning',
|
||||
@@ -4044,6 +4057,8 @@ export function toSummaryRowFromForm(form) {
|
||||
|
||||
urunAnaGrubu: form.urunAnaGrubu || '',
|
||||
urunAltGrubu: form.urunAltGrubu || '',
|
||||
kategori: form.kategori || '',
|
||||
yetiskinGarson: form.yetiskinGarson || form.askiliyan || '',
|
||||
aciklama: form.aciklama || '',
|
||||
|
||||
fiyat: Number(form.fiyat || 0),
|
||||
|
||||
Reference in New Issue
Block a user