import type { PropType } from 'vue'; import { defineComponent, ref, toRef, computed, watch, onMounted, reactive, onBeforeUnmount, } from 'vue'; import { useI18n } from 'vue-i18n'; import { useUserStore } from '@store/UserStore'; import { useGlobalStore } from '@store/globalStore'; import { useQuasar } from 'quasar'; import { CTitleBanner } from '../CTitleBanner'; import { CCardState } from '../CCardState'; import { CCopyBtn } from '../CCopyBtn'; import { CViewTable } from '../CViewTable'; import { CMyValueDb } from '../CMyValueDb'; import { CPrice } from '../CPrice'; import { CText } from '../CText'; import { CLabel } from '@src/components/CLabel'; import { CSchedaProdotto } from '@src/components/CSchedaProdotto'; import { CModifTrafiletto } from '@src/components/CModifTrafiletto'; import { CBarCode } from '../CBarCode'; import { CTableCupleLabelValue } from '../CTableCupleLabelValue'; import { func_tools, toolsext } from '@store/Modules/toolsext'; import type { IOptCatalogo, IGasordine, IMyScheda, IOrder, IOrderCart, IProduct, IVariazione, IRecFields, } from '@src/model'; import { IBaseOrder } from '@src/model'; import { tools } from '@tools'; import { useProducts } from '@store/Products'; import { shared_consts } from '@src/common/shared_vuejs'; import { useRouter } from 'vue-router'; import { costanti } from '@costanti'; export default defineComponent({ name: 'CCatalogoCard', emits: ['selauthor', 'opendetail', 'update:modelValue'], props: { product: { type: Object as PropType, required: false, default: null, }, id: { type: String, required: false, default: '', }, cosa: { type: Number, required: false, default: 0, }, complete: { type: Boolean, required: false, default: false, }, options: { type: Object, required: false, default: () => {}, }, modelValue: { type: Object as PropType, required: true, }, idPage: { type: String, required: false, default: '', }, scheda: { type: Object as PropType, required: false, default: () => ({}), }, }, components: { CTitleBanner, CCardState, CCopyBtn, CMyValueDb, CPrice, CBarCode, CLabel, CText, CViewTable, CTableCupleLabelValue, CSchedaProdotto, CModifTrafiletto, }, setup(props, { emit }) { const $q = useQuasar(); const { t } = useI18n(); const userStore = useUserStore(); const globalStore = useGlobalStore(); const Products = useProducts(); const listord = ref([]); const sumval = ref(0); const loading = ref(false); const indvariazSel = ref(-1); const site = ref(globalStore.site); const arrlistScheda = ref([]); const $router = useRouter(); const fullscreenImage = ref(null); const apriSchedaPDF = ref(false); const visufromgm = ref(false); const visudataextracted = ref(false); const updatefromgm = ref(false); const updatetogm = ref(false); const showQtaDisponibile = ref(false); const field_updated_fromGM = ref(''); const dataextractedWeb = ref(''); const widthoggetto = ref(40); const heightoggetto = ref(40); // Crea una copia locale reattiva di modelValue const optcatalogo = ref({ ...props.modelValue }); const mywidthogg = computed(() => { return widthoggetto.value * tools.getScaleX(optcatalogo.value, props.scheda); }); const myheightogg = computed(() => { return heightoggetto.value * tools.getScaleY(optcatalogo.value, props.scheda); }); const editOn = computed({ get(): boolean { return globalStore.editOn ? globalStore.editOn : false; }, set(value: boolean) { return tools.updateEditOn(value); }, }); // Watcher per sincronizzare le modifiche di modelValue watch( () => props.modelValue, (newVal) => { optcatalogo.value = { ...newVal }; // updateCatalogoPadre() }, { deep: false } ); function updateCatalogoPadre() { emit('update:modelValue', optcatalogo.value); } // Metodo per aggiornare il valore del catalogo const updateCatalogo = (updatedCatalogo: IOptCatalogo) => { optcatalogo.value = updatedCatalogo; // Aggiorna la copia locale updateCatalogoPadre(); }; const myorder = reactive({ idapp: tools.getEnv('VITE_APP_ID'), quantity: 0, quantitypreordered: 0, idStorehouse: '', idGasordine: '', storehouse: {}, gasordine: { active: false }, }); const storeSelected = ref(''); const arrordersCart = ref([]); const modifOn = ref(false); const modifTrafiletto = ref(false); const modifProd = ref(false); const timerInterval = ref(null); const timerLabelScadenza = ref(''); const labelDataRitiro = ref(''); const labelDataArrivoMerce = ref(''); const openlistorders = ref(false); const endload = ref(false); const myproduct = ref({}); const isFullScreen = ref(false); const imageSrc = ref('URL_DEL_TUO_FILE_IMMAGINE'); const startX = ref(0); const startY = ref(0); const scale = ref(1); const getTesto_Right = computed(() => { return Products.replaceKeyWordsByProduct( optcatalogo.value, myproduct.value!, props.scheda.testo_right!, props.idPage ); }); const getTesto_Right_attaccato = computed(() => { return Products.replaceKeyWordsByProduct( optcatalogo.value, myproduct.value!, props.scheda.testo_right_attaccato!, props.idPage ); }); const getTesto_Debug = computed(() => { return Products.replaceKeyWordsByProduct( optcatalogo.value, myproduct.value!, { contenuto: '{debug}', maxlength: 10000 }, props.idPage ); }); const getTesto_Bottom = computed(() => { return Products.replaceKeyWordsByProduct( optcatalogo.value, myproduct.value!, props.scheda.testo_bottom!, props.idPage ); }); watch( () => editOn.value, (to: any, from: any) => { if (!editOn.value) ricarica(); } ); /*const myproduct = computed((): IProduct => { console.log('getproduct computed') const ris = Products.getProduct(props.code) console.log(' received', ris) return ris })*/ function iconWhishlist(order: IProduct) { return 'fas fa-heart'; } async function addtoCart(add: boolean) { if (!userStore.isLogged) { tools.showNeutralNotif($q, t('ecomm.area_personale')); globalStore.rightDrawerOpen = true; return false; } if (myproduct.value) { const ris = await Products.addtoCartBase({ $q, t, id: myproduct.value._id, order: myorder, addqty: add, }); updateproduct(false); if (ris && ris.myord) { } } } function getnumstore() { if (myproduct.value) { if (myproduct.value.storehouses) return myproduct.value.storehouses.length; else return 0; } return 0; } function getSingleStorehouse() { try { if (!myproduct.value) return ''; const mystore = myproduct.value.storehouses[0]; if (mystore) return mystore.name + ' (' + mystore.city + ')'; else return ''; } catch (e) { return ''; } } function getSingleGasordine(gasordine: IGasordine) { try { const mygas = gasordine; if (mygas) /*return mygas.name + ' (' + mygas.city + ') ' + t('gas.dataora_chiusura_ordini') + ': ' + tools.getstrDateShort(mygas.dataora_chiusura_ordini) + ' ' + t('gas.data_arrivo_merce') + ': ' + tools.getstrDateShort(mygas.data_arrivo_merce) + ' ' + t('gas.dataora_ritiro') + ': ' + tools.getstrDateShort(mygas.dataora_ritiro)*/ return mygas.name; else return ''; } catch (e) { return ''; } } async function updateproduct(atload: boolean, forza?: boolean) { let carica = true; if (atload) { if (props.product) { myproduct.value = props.product; carica = false; } } else { } if (carica) { myproduct.value = null; updateproductmodif(null, forza); } // Products.updateQuantityAvailable(myproduct.value._id) } async function ricarica() { endload.value = false; if (myproduct.value) { const prod = await Products.loadProductById(myproduct.value._id); if (prod) { myproduct.value = prod; } } await load(); } async function updateproductmodif(element: any, forza?: boolean) { console.log('CCATALOGOCARD: updateproductmodif'); try { if (element?._id) { myproduct.value = await Products.getProductById(element?._id, forza); } else { myproduct.value = await Products.getProductById(props.id, forza); } updateLabel(); } catch (e) { console.error('err', e); } } function getStorehouses() { if (!myproduct.value) return []; const myarr: any = []; let ind = 1; myproduct.value.storehouses.forEach((store) => { myarr.push({ id: ind, label: store.name + ' (' + store.city + ')', value: store._id, }); ind++; }); // console.log('arraystore', myarr) return myarr; } function checkifCartDisable() { // return !myorder.idStorehouse return isOrdineChiuso(); } function checkifCartEnable() { return false; } function getQtyWarn() { if (myorder.quantity > 0) { return t('ecomm.di_cui_x_in_carrello', { qty: myorder.quantity }); } return ''; } function getQtyWarnPreOrdered() { if (myorder.quantitypreordered > 0) { return t('ecomm.di_cui_x_in_carrello', { qty: myorder.quantitypreordered, }); } return ''; } watch( () => props.id, async (newval, oldval) => { // console.log('change code') await load(); } ); watch( () => storeSelected.value, (newval, oldval) => { myorder.idStorehouse = newval; } ); function updateLabel() { let dataArrivoMerce = ''; let dataRitiro = ''; try { if (myproduct.value && myproduct.value.gasordine) { if (myproduct.value.gasordine.data_arrivo_merce) dataArrivoMerce = tools.getstrDateShort( myproduct.value.gasordine.data_arrivo_merce ); if (myproduct.value.gasordine.dataora_ritiro) dataRitiro = tools.getstrDateTime(myproduct.value.gasordine.dataora_ritiro); } else { dataArrivoMerce = ''; dataRitiro = ''; } } catch (e) {} if (labelDataArrivoMerce.value !== dataArrivoMerce) labelDataArrivoMerce.value = dataArrivoMerce; if (labelDataRitiro.value !== dataRitiro) labelDataRitiro.value = dataRitiro; updateTimerLabel(); } async function mounted() { await load(); // Start the timer when the component is mounted startTimer(); } function beforeDestroy() { // Clear the interval when the component is destroyed to prevent memory leaks clearInterval(timerInterval.value); } function updateTimerLabel() { if ( myproduct.value && myproduct.value.gasordine && myproduct.value.gasordine._id && myproduct.value.gasordine.dataora_chiusura_ordini ) timerLabelScadenza.value = tools.getCountDown( myproduct.value.gasordine.dataora_chiusura_ordini ); else timerLabelScadenza.value = ''; } function isOrdineChiuso() { if (myproduct.value) { return ( myproduct.value.gasordine && myproduct.value.gasordine.dataora_chiusura_ordini && tools.getCountDown(myproduct.value.gasordine.dataora_chiusura_ordini) === '' ); } else return false; } function startTimer() { // Update the timer label every second timerInterval.value = setInterval(() => updateTimerLabel(), 60000); } async function load() { indvariazSel.value = -1; Products.initproduct(myorder); await updateproduct(true, true); labelDataArrivoMerce.value = ''; labelDataRitiro.value = ''; // console.log('Load', myproduct.value.name) if (myproduct.value) { Products.setMyOrder(myorder, myproduct.value, storeSelected.value, { setstore: true, }); } updateLabel(); // console.log('myproduct', myproduct.value, 'arrvariaz', myproduct.value.arrvariazioni, 'compl', props.complete) if (props.complete && myproduct.value && myproduct.value.arrvariazioni) { // console.log('ENTRATO') indvariazSel.value = 0; } // console.log('°°° ENDLOAD °°°') endload.value = true; } function getclimgproduct() { return 'myimgproduct centermydiv'; } function visuListDisponibili() { if (myproduct.value) { openlistorders.value = true; sumval.value = Products.getSumQtyOrderProductInOrdersCart(myproduct.value._id); listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => { return accumulator + item.order.quantity; }, 0) ); } else return false; } function visuListBookable() { if (myproduct.value) { openlistorders.value = true; sumval.value = Products.getSumQtyPreOrderInOrdersCart(myproduct.value._id); listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => { return accumulator + item.order.quantitypreordered; }, 0) ); } else { return ''; } } function isOrdGas(): boolean { if (myproduct.value) return ( myproduct.value && !!myproduct.value.idGasordine && myproduct.value.gasordine! && myproduct.value.gasordine.active ); else return false; } function getpercqtaraggiunta(): number { if (myproduct.value) return ( tools.calcperc( (myproduct.value.bookableGASBloccatiQty + myproduct.value.QuantitaPrenotateInAttesa!) * myproduct.value.productInfo.weight!, myproduct.value.qtyToReachForGas * myproduct.value.productInfo.weight! ) / 100 ); else return 0; } function toggleFullScreen() { isFullScreen.value = !isFullScreen.value; scale.value = 1; } function onTouchStart(e: any) { startX.value = e.touches[0].pageX; startY.value = e.touches[0].pageY; } function onTouchMove(e: any) { const deltaX = e.touches[0].pageX - startX.value; const deltaY = e.touches[0].pageY - startY.value; // Calcola la distanza percorsa const distance = Math.sqrt(deltaX ** 2 + deltaY ** 2); // Imposta il fattore di scala in base alla distanza percorsa scale.value = Math.min(Math.max(1, scale.value + distance / 100), 3); // Salva le nuove coordinate di partenza startX.value = e.touches[0].pageX; startY.value = e.touches[0].pageY; // Applica la trasformazione if (fullscreenImage.value) fullscreenImage.value.style.transform = `scale(${scale.value})`; } function onTouchEnd() { // Ripristina la trasformazione quando l'utente solleva il dito if (fullscreenImage.value) fullscreenImage.value.fullscreenImage.style.transform = 'scale(1)'; } function naviga(path: string) { $router.push(path); } function setvariazioneSelected(indvariaz: number) { if (indvariazSel.value === indvariaz) indvariazSel.value = -1; else { indvariazSel.value = -1; indvariazSel.value = indvariaz; } } function click_author(id: any, autore: any) { emit('selauthor', id, autore); } function click_opendetail() { if (!optcatalogo.value.pdf) emit('opendetail'); } function escludiArticolo(variazione: IVariazione) { const hasExcludeProductTypes = !optcatalogo.value.excludeproductTypes || (optcatalogo.value.excludeproductTypes && optcatalogo.value.excludeproductTypes.includes(variazione.versione!)); return hasExcludeProductTypes; } function checkIfVariazioneDaVisu(variazione: IVariazione) { return !escludiArticolo(variazione); } function isProductNovita() { const monthsAgo = props.scheda.etichette?.novita?.months ?? 6; // Numero di mesi da considerare "recenti" const publishingDate = new Date(myproduct.value!.productInfo.date_pub!); // Calcola i millisecondi corrispondenti a X mesi fa const monthsInMilliseconds = monthsAgo * 30 * 24 * 60 * 60 * 1000; // Approssimazione, non tutti i mesi hanno 30 giorni // Crea una data che rappresenta X mesi fa const monthsAgoDate = new Date(tools.getTimeNow() - monthsInMilliseconds); // Confronta la data di pubblicazione con la data X mesi fa return publishingDate > monthsAgoDate; } function isProductBestseller() { try { if (props.scheda.etichette?.bestseller?.show) { // diventa un bestseller quando il numero di fatturati Annuali è superiore a const numfatturati = props.scheda.etichette?.bestseller?.quantiFattRaggiunti ?? 50; return myproduct.value!.productInfo.fatLast1Y > numfatturati; } } catch (e) { return false; } return false; } /*async function refreshDataFromGM() { if (myproduct.value) { loading.value = true updatefromgm.value = true field_updated_fromGM.value = '' const ris = await globalStore.updateLocalDbFromGM_T_Web_Articoli(myproduct.value.productInfo.sku!, myproduct.value.isbn) if (ris) { // field_updated_fromGM.value = t('dbgm.updateLocalDb_OK') await updateproduct(false) tools.showPositiveNotif($q, t('dbgm.updateLocalDb_OK')) updatefromgm.value = false } loading.value = false } }*/ /*async function refreshAllDataBookFromGM(options: any) { if (myproduct.value) { loading.value = true updatefromgm.value = true field_updated_fromGM.value = '' const ris = await globalStore.updateAllBookFromGM_T_Web_Articoli({ sku: myproduct.value.productInfo.sku!, isbn: myproduct.value.productInfo.code, ...options, caricatutti: true }) if (ris) { // field_updated_fromGM.value = t('dbgm.updateLocalDb_OK') await updateproduct(false, false) tools.showPositiveNotif($q, t('dbgm.updateLocalDb_OK')) updatefromgm.value = false } loading.value = false } }*/ async function refreshSingleBookFromGM(options: any) { if (myproduct.value) { loading.value = true; updatefromgm.value = true; field_updated_fromGM.value = ''; const ris = await globalStore.updateAllBookFromGM_T_Web_Articoli({ sku: myproduct.value.productInfo.sku!, isbn: myproduct.value.productInfo.code, ...options, }); if (ris) { // field_updated_fromGM.value = t('dbgm.updateLocalDb_OK') if (ris.error) { tools.showNegativeNotif($q, ris.error); } else { await updateproduct(false, false); tools.showPositiveNotif($q, t('dbgm.updateLocalDb_OK')); } updatefromgm.value = false; } loading.value = false; } } async function refreshFieldFromGM(field: string) { if (myproduct.value) { loading.value = true; updatefromgm.value = true; field_updated_fromGM.value = ''; field_updated_fromGM.value = await globalStore.getGM_FieldOf_T_Web_Articoli( myproduct.value.productInfo.sku!, field, shared_consts.CmdQueryMs.GET ); loading.value = false; } } async function scrapingBook(update: boolean, aggiornasoloSeVuoti: boolean) { const options = { update, aggiornasoloSeVuoti, forzaricarica: true, }; const myparam = { product_id: myproduct.value._id, options }; loading.value = true; const dataupdated = await globalStore .scrapingBook(myparam) .then((dataupdated) => { if (dataupdated && update) { tools.showPositiveNotif($q, t('dbgm.scrapingOkUpdated')); } if (!dataupdated) { tools.showNegativeNotif($q, t('dbgm.dati_non_estratti')); visudataextracted.value = false; } return dataupdated; }) .catch((e) => { if (update) { console.error('Errore aggiornamento singolo libro:', e); tools.showNegativeNotif($q, t('dbgm.updateLocalDb_ERROR')); } else { tools.showNegativeNotif($q, t('dbgm.err_extraction')); } loading.value = false; }); loading.value = false; return dataupdated; } async function getDataExtracted() { visudataextracted.value = true; loading.value = true; dataextractedWeb.value = '... caricamento in corso...'; try { const data = await scrapingBook(false); const html = tools.generateHtmlTableFromObject(data); dataextractedWeb.value = html; } catch (error) { console.error("Errore durante l'estrazione dei dati:", error); dataextractedWeb.value = 'Errore nel caricamento dei dati.'; visudataextracted.value = false; } finally { loading.value = false; } } onMounted(mounted); onBeforeUnmount(beforeDestroy); return { visuListDisponibili, visuListBookable, addtoCart, iconWhishlist, getclimgproduct, getnumstore, getSingleStorehouse, getSingleGasordine, getStorehouses, checkifCartDisable, myproduct, myorder, tools, t, storeSelected, getQtyWarn, openlistorders, func_tools, toolsext, Products, arrordersCart, endload, shared_consts, site, getQtyWarnPreOrdered, listord, sumval, timerLabelScadenza, labelDataRitiro, labelDataArrivoMerce, getpercqtaraggiunta, isOrdGas, isFullScreen, toggleFullScreen, onTouchStart, onTouchMove, onTouchEnd, naviga, globalStore, editOn, costanti, updateproduct, updateproductmodif, isOrdineChiuso, ricarica, apriSchedaPDF, setvariazioneSelected, indvariazSel, checkifCartEnable, click_author, click_opendetail, checkIfVariazioneDaVisu, isProductNovita, isProductBestseller, modifOn, modifProd, getTesto_Right, getTesto_Right_attaccato, getTesto_Bottom, getTesto_Debug, updateCatalogo, optcatalogo, visufromgm, visudataextracted, updatefromgm, showQtaDisponibile, field_updated_fromGM, refreshFieldFromGM, updatetogm, dataextractedWeb, // refreshDataFromGM, // refreshAllDataBookFromGM, refreshSingleBookFromGM, loading, modifTrafiletto, getDataExtracted, widthoggetto, heightoggetto, mywidthogg, myheightogg, }; }, });