Files
myprojplanet_vite/src/components/CCatalogoCard/CCatalogoCard.ts
2025-12-05 17:56:05 +01:00

892 lines
24 KiB
TypeScript
Executable File

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 '@/components/CLabel';
import { CSchedaProdotto } from '@/components/CSchedaProdotto';
import { CModifTrafiletto } from '@/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,
ICatalog,
} from '@/model';
import { IBaseOrder } from '@/model';
import { tools } from '@tools';
import { useProducts } from '@store/Products';
import { shared_consts } from '@/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<IProduct | null>,
required: false,
default: null,
},
myCatalog: {
type: Object as PropType<ICatalog | null>,
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<IOptCatalogo>,
required: true,
},
idPage: {
type: String,
required: false,
default: '',
},
scheda: {
type: Object as PropType<IMyScheda>,
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(<IOrderCart[]>[]);
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(<any>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<IOptCatalogo>({ ...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(<IOrder>{
idapp: tools.getEnv('VITE_APP_ID'),
quantity: 0,
quantitypreordered: 0,
idStorehouse: '',
idGasordine: null,
storehouse: {},
gasordine: { active: false },
});
const storeSelected = ref('');
const arrordersCart = ref(<IOrderCart[]>[]);
const modifOn = ref(false);
const modifTrafiletto = ref(false);
const modifProd = ref(false);
const timerInterval = ref(<any>null);
const timerLabelScadenza = ref('');
const labelDataRitiro = ref('');
const labelDataArrivoMerce = ref('');
const openlistorders = ref(false);
const endload = ref(false);
const myproduct = ref(<IProduct | null>{});
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, 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,
scrapingBook,
};
},
});