diff --git a/composer.json b/composer.json index 3ad2395..7c6f34f 100644 --- a/composer.json +++ b/composer.json @@ -42,8 +42,9 @@ "laravel/tinker": "^2.7", "laravel/ui": "^4.0", "phpmailer/phpmailer": "^6.9", - "phpoffice/phpspreadsheet": "^4.1", + "phpoffice/phpspreadsheet": "^5.2", "proengsoft/laravel-jsvalidation": "^4.0.0", + "smalot/pdfparser": "^2.12", "socialiteproviders/microsoft": "^4.7", "spatie/laravel-query-builder": "^5.0", "vanguardapp/activity-log": "^6.0", diff --git a/composer.lock b/composer.lock index 764458a..8ad8c93 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9c4f1e3bc3ee2180211c055e70635aef", + "content-hash": "97382155de516648df8ab1f1c50ab1d5", "packages": [ { "name": "akaunting/laravel-setting", @@ -3839,16 +3839,16 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "4.1.0", + "version": "5.2.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "6ff18c3a8df3a945492f75ce455d77f7ad55dd5c" + "reference": "3b8994b3aac4b61018bc04fc8c441f4fd68c18eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/6ff18c3a8df3a945492f75ce455d77f7ad55dd5c", - "reference": "6ff18c3a8df3a945492f75ce455d77f7ad55dd5c", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/3b8994b3aac4b61018bc04fc8c441f4fd68c18eb", + "reference": "3b8994b3aac4b61018bc04fc8c441f4fd68c18eb", "shasum": "" }, "require": { @@ -3878,18 +3878,19 @@ "dealerdirect/phpcodesniffer-composer-installer": "dev-main", "dompdf/dompdf": "^2.0 || ^3.0", "friendsofphp/php-cs-fixer": "^3.2", - "mitoteam/jpgraph": "^10.3", + "mitoteam/jpgraph": "^10.5", "mpdf/mpdf": "^8.1.1", "phpcompatibility/php-compatibility": "^9.3", - "phpstan/phpstan": "^1.1", - "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan": "^1.1 || ^2.0", + "phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0", + "phpstan/phpstan-phpunit": "^1.0 || ^2.0", "phpunit/phpunit": "^10.5", "squizlabs/php_codesniffer": "^3.7", "tecnickcom/tcpdf": "^6.5" }, "suggest": { "dompdf/dompdf": "Option for rendering PDF with PDF Writer", - "ext-intl": "PHP Internationalization Functions", + "ext-intl": "PHP Internationalization Functions, regquired for NumberFormat Wizard", "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", "mpdf/mpdf": "Option for rendering PDF with PDF Writer", "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" @@ -3938,9 +3939,9 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/4.1.0" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.2.0" }, - "time": "2025-03-02T06:52:24+00:00" + "time": "2025-10-26T15:54:22+00:00" }, { "name": "phpoption/phpoption", @@ -4980,6 +4981,57 @@ ], "time": "2024-04-27T21:32:50+00:00" }, + { + "name": "smalot/pdfparser", + "version": "v2.12.1", + "source": { + "type": "git", + "url": "https://github.com/smalot/pdfparser.git", + "reference": "98d31ba34ef5b5a98897ef4b6c3925d502ea53b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/smalot/pdfparser/zipball/98d31ba34ef5b5a98897ef4b6c3925d502ea53b1", + "reference": "98d31ba34ef5b5a98897ef4b6c3925d502ea53b1", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-zlib": "*", + "php": ">=7.1", + "symfony/polyfill-mbstring": "^1.18" + }, + "type": "library", + "autoload": { + "psr-0": { + "Smalot\\PdfParser\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Sebastien MALOT", + "email": "sebastien@malot.fr" + } + ], + "description": "Pdf parser library. Can read and extract information from pdf file.", + "homepage": "https://www.pdfparser.org", + "keywords": [ + "extract", + "parse", + "parser", + "pdf", + "text" + ], + "support": { + "issues": "https://github.com/smalot/pdfparser/issues", + "source": "https://github.com/smalot/pdfparser/tree/v2.12.1" + }, + "time": "2025-07-31T06:19:56+00:00" + }, { "name": "socialiteproviders/manager", "version": "v4.8.1", @@ -11355,6 +11407,6 @@ "php": "^8.2.0", "ext-json": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/public/uploads/client_files/1762868941_client1_provapagina.pdf b/public/uploads/client_files/1762868941_client1_provapagina.pdf new file mode 100644 index 0000000..3f997ec Binary files /dev/null and b/public/uploads/client_files/1762868941_client1_provapagina.pdf differ diff --git a/public/uploads/client_files/1762868959_client1_provapagina.pdf b/public/uploads/client_files/1762868959_client1_provapagina.pdf new file mode 100644 index 0000000..3f997ec Binary files /dev/null and b/public/uploads/client_files/1762868959_client1_provapagina.pdf differ diff --git a/public/uploads/client_files/1762869314_client1_provapagina.pdf b/public/uploads/client_files/1762869314_client1_provapagina.pdf new file mode 100644 index 0000000..3f997ec Binary files /dev/null and b/public/uploads/client_files/1762869314_client1_provapagina.pdf differ diff --git a/public/uploads/client_files/1762869435_provapagina.pdf b/public/uploads/client_files/1762869435_provapagina.pdf new file mode 100644 index 0000000..3f997ec Binary files /dev/null and b/public/uploads/client_files/1762869435_provapagina.pdf differ diff --git a/public/uploads/client_files/1762873212_Cassina_Indoor_Listino_Prezzi______IVA_Esclusa__ITALIA_-_Febbraio_2024-332.pdf b/public/uploads/client_files/1762873212_Cassina_Indoor_Listino_Prezzi______IVA_Esclusa__ITALIA_-_Febbraio_2024-332.pdf new file mode 100644 index 0000000..33b3e78 Binary files /dev/null and b/public/uploads/client_files/1762873212_Cassina_Indoor_Listino_Prezzi______IVA_Esclusa__ITALIA_-_Febbraio_2024-332.pdf differ diff --git a/public/userarea/annotationsModal.js b/public/userarea/annotationsModal.js deleted file mode 100644 index ad66692..0000000 --- a/public/userarea/annotationsModal.js +++ /dev/null @@ -1,1598 +0,0 @@ -$(document).ready(function () { - // =================== - // GLOBAL STATE - // =================== - let photoData = { - naturalWidth: 0, - naturalHeight: 0, - displayWidth: 0, - displayHeight: 0, - scale: 1, - }; - - let photoAnnotations = {}; - let partColors = {}; - let partSizes = {}; // memorizza la dimensione specifica per parte - let selectedPartNumber = null; - let unsavedChanges = false; - let fabricCanvas = null; - let descriptionTextbox = null; - let markerObjects = {}; - let nextMarkerId = 1; - let partsListData = []; - // DIMENSIONE GLOBALE MARKER - let globalMarkerSize = 16; - - // =================== - // MODAL INITIALIZATION - // =================== - window.initAnnotationsModal = function (iddatadb, idquotations, trfHeader) { - console.log("initAnnotationsModal chiamato con:", { - iddatadb, - idquotations, - trfHeader, - }); - - $("#annotationsModal").attr("data-iddatadb", iddatadb); - - if (!iddatadb && !idquotations) { - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - $("#trfHeaderAnnotations").text(trfHeader || "N/D"); - $("#annotationsModal") - .data("iddatadb", iddatadb || null) - .data("idquotations", idquotations || null); - - loadPhoto(iddatadb, idquotations); - loadExistingParts(iddatadb, idquotations); - - const modalElement = document.getElementById("annotationsModal"); - if (!modalElement) { - console.error("Elemento #annotationsModal non trovato nel DOM."); - alert( - "Errore: Il modale delle annotazioni non è presente nel DOM.", - ); - return; - } - let modal = bootstrap.Modal.getInstance(modalElement); - if (!modal) { - modal = new bootstrap.Modal(modalElement, { - backdrop: true, - keyboard: true, - focus: true, - }); - } - modal.show(); - // Inizializza slider dimensione marker - $("#markerSizeSlider").val(globalMarkerSize); - $("#markerSizeValue").text(globalMarkerSize + "px"); - - // Debug: Verifica presenza elementi DOM - console.log( - "Presenza #partsListAnnotations:", - $("#partsListAnnotations").length, - ); - console.log( - "Presenza #showMixPartsAnnotations:", - $("#showMixPartsAnnotations").length, - ); - console.log( - "Presenza #addDescriptionsBtnAnnotations:", - $("#addDescriptionsBtnAnnotations").length, - ); - console.log( - "Presenza #removeAnnotationsBtnAnnotations:", - $("#removeAnnotationsBtnAnnotations").length, - ); - console.log( - "Presenza #downloadPhotoBtnAnnotations:", - $("#downloadPhotoBtnAnnotations").length, - ); - console.log( - "Presenza #backToPartsBtnAnnotations:", - $("#backToPartsBtnAnnotations").length, - ); - console.log( - "Presenza #overlayCanvasAnnotations:", - $("#overlayCanvasAnnotations").length, - ); - }; - - $("#annotationsModal").on("hide.bs.modal", function (e) { - if ( - unsavedChanges && - !confirm("Hai modifiche non salvate. Vuoi davvero uscire?") - ) { - e.preventDefault(); - } - }); - - $("#annotationsModal").on("hidden.bs.modal", function () { - photoData = { - naturalWidth: 0, - naturalHeight: 0, - displayWidth: 0, - displayHeight: 0, - scale: 1, - }; - photoAnnotations = {}; - partColors = {}; - selectedPartNumber = null; - unsavedChanges = false; - partsListData = []; - if (fabricCanvas) { - fabricCanvas.off(); - fabricCanvas.dispose(); - fabricCanvas = null; - } - descriptionTextbox = null; - markerObjects = {}; - globalMarkerSize = 16; - $("#photoSelectorContainerAnnotations").empty().hide(); - $("#samplePhotoAnnotations").attr("src", ""); - $("#partsListAnnotations").empty(); - $(".temp-alert").remove(); - - const modalElement = document.getElementById("annotationsModal"); - const modal = bootstrap.Modal.getInstance(modalElement); - if (modal) { - modal.dispose(); - } - $(".modal-backdrop").remove(); - $("body").removeClass("modal-open"); - $("body").css("padding-right", ""); - $(":focus").blur(); - }); - - // SLIDER DIMENSIONE MARKER - $(document) - .off("input", "#markerSizeSlider") - .on("input", "#markerSizeSlider", function () { - globalMarkerSize = parseInt($(this).val()); - $("#markerSizeValue").text(globalMarkerSize + "px"); - - partsListData.forEach(function (part) { - if (part && part.part_number != null) { - partSizes[part.part_number] = globalMarkerSize; - } - }); - - $("#partsListAnnotations .marker-size-slider").val( - globalMarkerSize, - ); - $("#partsListAnnotations .marker-size-value").text( - globalMarkerSize + "px", - ); - - updateMarkers(); - markUnsaved(); - }); - - // =================== - // PHOTO LOADERS - // =================== - function loadPhoto(iddatadb, idquotations) { - const currentPhoto = $("#samplePhotoAnnotations").attr("src"); - const endpoint = idquotations - ? "load_photo_quotation.php" - : "load_photo.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - $.ajax({ - url: endpoint, - method: "GET", - data: data, - success: function (response) { - console.log("Risposta da load_photo:", response); - if (response.success) { - if (response.photos && response.photos.length > 1) { - showPhotoSelector(response.photos, currentPhoto); - } else if ( - response.photos && - response.photos.length === 1 - ) { - loadSinglePhoto(response.photos[0]); - } else { - $("#samplePhotoAnnotations").attr("src", ""); - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - } else { - const errorMsg = $( - '", - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - console.error("Errore AJAX in loadPhoto:", { - status, - error, - responseText: xhr.responseText, - }); - const errorMsg = $( - '", - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } - - function showPhotoSelector(photos, selected = null) { - const selectorContainer = $("#photoSelectorContainerAnnotations"); - selectorContainer.empty().show(); - const selector = $( - '', - ); - photos.forEach((photo, index) => { - const photoName = photo.split("/").pop(); - const option = $("") - .val(photo) - .text(`Photo ${index + 1} - ${photoName}`); - selector.append(option); - }); - selector.on("change", function () { - loadSinglePhoto($(this).val()); - }); - selectorContainer.append(selector); - const photoToSelect = - selected && photos.includes(selected) ? selected : photos[0]; - if (photoToSelect) { - selector.val(photoToSelect); - loadSinglePhoto(photoToSelect); - } - } - - function loadSinglePhoto(photoPath) { - const img = $("#samplePhotoAnnotations"); - img.off("load").attr("src", photoPath); - img.on("load", function () { - console.log("Foto caricata:", photoPath); - const canvas = document.getElementById("photoCanvasAnnotations"); - const ctx = canvas.getContext("2d"); - const naturalWidth = img[0].naturalWidth; - const naturalHeight = img[0].naturalHeight; - const parent = $(canvas).parent(); - const maxW = parent.width(); - const maxH = parent.height(); - const scale = Math.min(maxW / naturalWidth, maxH / naturalHeight); - - photoData = { - naturalWidth, - naturalHeight, - displayWidth: Math.max(1, Math.round(naturalWidth * scale)), - displayHeight: Math.max(1, Math.round(naturalHeight * scale)), - scale, - }; - - canvas.width = naturalWidth; - canvas.height = naturalHeight; - canvas.style.width = `${photoData.displayWidth}px`; - canvas.style.height = `${photoData.displayHeight}px`; - - ctx.clearRect(0, 0, naturalWidth, naturalHeight); - ctx.drawImage(img[0], 0, 0, naturalWidth, naturalHeight); - - if (fabricCanvas) { - fabricCanvas.off(); - fabricCanvas.dispose(); - fabricCanvas = null; - } - - const overlayCanvas = document.getElementById( - "overlayCanvasAnnotations", - ); - const canvasContainer = overlayCanvas.parentElement; - const newOverlayCanvas = document.createElement("canvas"); - newOverlayCanvas.id = "overlayCanvasAnnotations"; - newOverlayCanvas.width = photoData.displayWidth; - newOverlayCanvas.height = photoData.displayHeight; - newOverlayCanvas.style.width = `${photoData.displayWidth}px`; - newOverlayCanvas.style.height = `${photoData.displayHeight}px`; - newOverlayCanvas.style.position = "absolute"; - newOverlayCanvas.style.top = "0"; - newOverlayCanvas.style.left = "0"; - newOverlayCanvas.style.zIndex = "1000"; - - canvasContainer.removeChild(overlayCanvas); - canvasContainer.appendChild(newOverlayCanvas); - - setTimeout(() => { - fabricCanvas = new fabric.Canvas("overlayCanvasAnnotations", { - selection: true, - preserveObjectStacking: true, - width: photoData.displayWidth, - height: photoData.displayHeight, - }); - - fabricCanvas.setDimensions({ - width: photoData.displayWidth, - height: photoData.displayHeight, - }); - - fabricCanvas.on("mouse:down", function (options) { - console.log( - "Evento mouse:down su canvas, selectedPartNumber:", - selectedPartNumber, - ); - if (selectedPartNumber === null) { - console.log( - "Nessuna parte selezionata, ignoro il click.", - ); - return; - } - if (options.target) { - console.log("Click su un oggetto esistente, ignoro."); - return; - } - const pointer = fabricCanvas.getPointer(options.e); - const x = pointer.x / photoData.scale; - const y = pointer.y / photoData.scale; - const currentPhoto = $("#samplePhotoAnnotations").attr( - "src", - ); - - if (!photoAnnotations[currentPhoto]) { - photoAnnotations[currentPhoto] = { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - } - - const partColor = - partColors[selectedPartNumber] || "#ff0000"; - photoAnnotations[currentPhoto].markers.push({ - id: nextMarkerId++, - partNumber: selectedPartNumber, - x, - y, - color: partColor, - }); - - console.log("Marker aggiunto/spostato:", { - partNumber: selectedPartNumber, - x, - y, - color: partColor, - }); - updateMarkers(); - markUnsaved(); - }); - - fabricCanvas.upperCanvasEl.focus(); - fabricCanvas.renderAll(); - - updateMarkers(); - updateDescriptions(); - }, 10); - }); - } - - // =================== - // DOWNLOAD PHOTO - // =================== - $(document) - .off("click.downloadPhoto", "#downloadPhotoBtnAnnotations") - .on( - "click.downloadPhoto", - "#downloadPhotoBtnAnnotations", - function (e) { - e.preventDefault(); - e.stopPropagation(); - console.log( - "Evento click su #downloadPhotoBtnAnnotations, ID elemento:", - $(this).attr("id"), - ); - if (!$("#downloadPhotoBtnAnnotations").length) { - console.error( - "Pulsante #downloadPhotoBtnAnnotations non trovato nel DOM.", - ); - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - const photoSrc = $("#samplePhotoAnnotations").attr("src"); - console.log("URL immagine per il download:", photoSrc); - if (!photoSrc) { - console.error("Nessuna foto caricata da scaricare."); - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - // Verifica se l'URL è valido - const img = new Image(); - img.src = photoSrc; - img.onload = function () { - const photoName = - photoSrc.split("/").pop() || "downloaded_photo.png"; - console.log("Nome file per il download:", photoName); - const link = document.createElement("a"); - link.href = photoSrc; - link.download = photoName; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - console.log("Download avviato per:", photoName); - }; - img.onerror = function () { - console.error( - "Errore: Impossibile caricare l'immagine per il download:", - photoSrc, - ); - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }; - }, - ); - - // =================== - // TORNA AL MODALE PARTI (modal_partsTable.php) - // =================== - $(document) - .off("click.backToParts", "#backToPartsBtnAnnotations") - .on("click.backToParts", "#backToPartsBtnAnnotations", function (e) { - e.preventDefault(); - e.stopPropagation(); - - if ( - unsavedChanges && - !confirm( - "Hai modifiche non salvate. Vuoi davvero tornare al modale delle parti?", - ) - ) { - return; - } - - const iddatadb = $("#annotationsModal").data("iddatadb"); - const idquotations = $("#annotationsModal").data("idquotations"); - const trfHeader = $("#trfHeaderAnnotations").text(); - - // CHIUDI MODALE ANNOTAZIONI IN MODO SICURO - const annotationsModalElement = - document.getElementById("annotationsModal"); - if (annotationsModalElement) { - const modalInstance = bootstrap.Modal.getInstance( - annotationsModalElement, - ); - if (modalInstance) { - modalInstance.hide(); - } else { - $(annotationsModalElement).modal("hide"); // fallback jQuery - } - } - console.log("Torno a modal_partsTable.php con:", { - iddatadb, - idquotations, - trfHeader, - }); - // CARICA E APRI MODALE PARTI - $.get( - "modal_partsTable.php", - { - iddatadb: iddatadb || "", - idquotations: idquotations || "", - trfHeader: trfHeader, - }, - function (data) { - // Rimuovi vecchio modale (con ID corretto) - $("#partsTableModal").remove(); - $(".modal-backdrop").remove(); - - // Aggiungi nuovo modale - $("body").append(data); - - // Apri con Bootstrap 5 - const partsModalElement = - document.getElementById("partsTableModal"); - if (partsModalElement) { - const modal = new bootstrap.Modal(partsModalElement, { - backdrop: true, - keyboard: true, - focus: true, - }); - modal.show(); - } else { - let iddatadb = - $("#annotationsModal").attr("data-iddatadb"); - - $( - "button.parts-btn[data-iddatadb='" + - iddatadb + - "']", - ).trigger("click"); - } - }, - ).fail(function (xhr) { - console.error("Errore caricamento modale parti:", xhr); - alert( - "Errore 404: modal_partsTable.php non trovato o errore server.", - ); - }); - }); - // =================== - // PARTS LIST - // =================== - function updatePartsList() { - console.log( - "updatePartsList chiamato con partsListData:", - partsListData, - ); - const showMixParts = $("#showMixPartsAnnotations").is(":checked"); - console.log("Stato showMixPartsAnnotations:", showMixParts); - const partsListElement = $("#partsListAnnotations"); - - if (!partsListElement.length) { - console.error( - "Elemento #partsListAnnotations non trovato nel DOM.", - ); - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - partsListElement.empty(); - const predefinedColors = [ - "#ff0000", // Rosso - "#0000ff", // Blu - "#00ff00", // Verde - "#ffff00", // Giallo - "#ff00ff", // Magenta - "#00ffff", // Ciano - "#800080", // Viola - "#ffa500", // Arancione - ]; - - partsListData.forEach((part) => { - const partNumber = part.part_number; - const partDescription = part.part_description; - const partColor = - partColors[partNumber] || - (partDescription.toLowerCase().startsWith("mix") - ? "#0000ff" - : "#ff0000"); - if ( - partNumber && - partDescription && - (showMixParts || - !partDescription.toLowerCase().startsWith("mix")) - ) { - const colorOptions = predefinedColors - .map( - (color) => - `
`, - ) - .join(""); - const listItem = ` -
  • -${partNumber} - ${partDescription} -
    -
    - -
    -
    - - ${partSizes[partNumber] || globalMarkerSize}px -
    -
  • `; - partsListElement.append(listItem); - } - }); - - console.log( - "Elementi aggiunti a #partsListAnnotations:", - partsListElement.find("li").length, - ); - console.log("HTML di #partsListAnnotations:", partsListElement.html()); - - // Associa evento di selezione all'intera riga - partsListElement - .off("click.partsList") - .on("click.partsList", ".list-group-item", function (e) { - e.stopPropagation(); - e.preventDefault(); - // Ignora il click se è sulla paletta dei colori - if ($(e.target).closest(".color-picker-container").length) { - console.log( - "Click sulla paletta dei colori, ignoro selezione parte.", - ); - return; - } - - const $listItem = $(this); - const partNumber = $listItem.data("part-number"); - - if ( - selectedPartNumber == partNumber && - $listItem.hasClass("active") - ) { - selectedPartNumber = null; - $listItem.removeClass("active"); - - return; - } - - selectedPartNumber = partNumber; - $listItem.addClass("active").siblings().removeClass("active"); - console.log( - "Parte selezionata tramite riga:", - selectedPartNumber, - ); - }); - - // Associa eventi alla paletta dei colori - partsListElement - .off("click.selectedColor") - .on("click.selectedColor", ".selected-color", function (e) { - e.stopPropagation(); - e.preventDefault(); - const $picker = $(this).siblings(".color-picker"); - console.log( - "Cliccato .selected-color, mostro/nascondo paletta:", - $picker.is(":visible"), - ); - $(".color-picker").not($picker).hide(); - $picker.toggle(); - }); - - // === Gestione cambio colore === - partsListElement - .off("click.colorOption") - .on("click.colorOption", ".color-option", function (e) { - e.stopPropagation(); - e.preventDefault(); - - const $this = $(this); - const color = $this.data("color"); - const $listItem = $this.closest("li"); - const partNumber = $listItem.data("part-number"); - - console.log( - "Cliccato .color-option, colore:", - color, - "per parte:", - partNumber, - ); - - // Salva il nuovo colore - partColors[partNumber] = color; - - // Aggiorna il colore visivo nel selettore - $listItem - .find(".selected-color") - .css("background-color", color); - - let currentPhoto = $("#samplePhotoAnnotations").attr("src"); - let annotations = photoAnnotations[currentPhoto]; - - if (annotations) { - annotations.markers.forEach(function (m) { - if (m.partNumber == partNumber) { - m.color = color; - let group = markerObjects[m.id]; - - if (group) { - let circle = group.item(0); - - circle.set("fill", color); - circle.set("stroke", color); - } - } - }); - fabricCanvas.renderAll(); - } - - // Chiudi la palette e aggiorna canvas - $this.closest(".color-picker").hide(); - updateMarkers(); - markUnsaved(); - }); - - // === Slider locale per dimensione marker === - partsListElement - .off("input.localMarkerSize") - .on("input.localMarkerSize", ".marker-size-slider", function (e) { - e.stopPropagation(); - e.preventDefault(); - - // Riferimenti alla parte e valore scelto - const $slider = $(this); - const partNumber = $slider.closest("li").data("part-number"); - const newSize = parseInt($slider.val()); - - // Aggiorna il valore visivo accanto allo slider - $slider.siblings(".marker-size-value").text(newSize + "px"); - - // Memorizza la nuova dimensione per quella parte - partSizes[partNumber] = newSize; - - // Aggiorna i marker sul canvas - updateMarkers(); - - // Segnala modifiche non salvate - markUnsaved(); - - console.log( - `Dimensione marker aggiornata per parte ${partNumber}: ${newSize}px`, - ); - }); - - $(document) - .off("click.colorPicker") - .on("click.colorPicker", function (e) { - if (!$(e.target).closest(".color-picker-container").length) { - console.log("Cliccato fuori, nascondo tutte le palette."); - $(".color-picker").hide(); - } - }); - } - - function enableDragDropPartsList() { - const list = $("#partsListAnnotations"); - if (!list.length || typeof $.ui === "undefined" || !$.ui.sortable) { - console.warn("jQuery UI o .sortable non disponibile. Ritento..."); - setTimeout(enableDragDropPartsList, 100); - return; - } - - if (list.hasClass("ui-sortable")) { - list.sortable("destroy"); // evita duplicati - } - - list.sortable({ - items: "li.list-group-item", - placeholder: "list-group-item placeholder", - axis: "y", - containment: "parent", - tolerance: "pointer", - start: function (e, ui) { - ui.item.addClass("dragging"); - }, - stop: function (e, ui) { - ui.item.removeClass("dragging"); - const newOrder = []; - list.find("li").each(function () { - const partNumber = $(this).data("part-number"); - const part = partsListData.find( - (p) => p.part_number == partNumber, - ); - if (part) newOrder.push(part); - }); - partsListData = newOrder; - console.log( - "Ordine parti aggiornato:", - partsListData.map((p) => p.part_number), - ); - markUnsaved(); - updateMarkers(); - }, - }); - } - - // Delegazione evento per il checkbox - $(document) - .off("change.showMix", "#showMixPartsAnnotations") - .on("change.showMix", "#showMixPartsAnnotations", function (e) { - e.preventDefault(); - e.stopPropagation(); - console.log( - "Evento change su #showMixPartsAnnotations, ID elemento:", - $(this).attr("id"), - ); - const isChecked = $(this).is(":checked"); - console.log( - "Checkbox #showMixPartsAnnotations cambiato:", - isChecked, - ); - if (!$("#showMixPartsAnnotations").length) { - console.error( - "Checkbox #showMixPartsAnnotations non trovato nel DOM.", - ); - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - updatePartsList(); - updateMarkers(); - setTimeout(enableDragDropPartsList, 50); - if ( - photoAnnotations[$("#samplePhotoAnnotations").attr("src")] - ?.hasDescriptions - ) { - updateDescriptions(); - } - }); - - // =================== - // LOAD EXISTING PARTS - // =================== - function loadExistingParts(iddatadb, idquotations) { - console.log("loadExistingParts chiamato con:", { - iddatadb, - idquotations, - }); - if (!iddatadb && !idquotations) { - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - const endpoint = idquotations - ? "load_parts_quotation.php" - : "load_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - $.ajax({ - url: endpoint, - method: "GET", - data: data, - success: function (response) { - console.log("Risposta da load_parts:", response); - partsListData = []; - if ( - response.success && - response.parts && - response.parts.length > 0 - ) { - partsListData = response.parts; - response.parts.forEach((part) => { - const defaultColor = part.part_description - .toLowerCase() - .startsWith("mix") - ? "#0000ff" - : "#ff0000"; - partColors[part.part_number] = defaultColor; - }); - updatePartsList(); - // Forza aggiornamento iniziale del checkbox - setTimeout(() => { - $("#showMixPartsAnnotations").trigger("change.showMix"); - }, 100); - } else { - const errorMsg = $( - '", - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - console.error("Errore AJAX in loadExistingParts:", { - status, - error, - responseText: xhr.responseText, - }); - const errorMsg = $( - '", - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } - - // =================== - // MARKERS & DESCRIPTIONS - // =================== - function updateMarkers() { - console.log( - "updateMarkers chiamato, markerObjects:", - Object.keys(markerObjects), - ); - for (let markerId in markerObjects) { - fabricCanvas.remove(markerObjects[markerId]); - delete markerObjects[markerId]; - } - markerObjects = {}; - - const currentPhoto = $("#samplePhotoAnnotations").attr("src"); - const annotations = photoAnnotations[currentPhoto] || { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - const showMixParts = $("#showMixPartsAnnotations").is(":checked"); - - annotations.markers.forEach((marker) => { - const part = partsListData.find( - (p) => p.part_number == marker.partNumber, - ); - const partDescription = part ? part.part_description : ""; - if ( - !showMixParts && - partDescription && - partDescription.toLowerCase().startsWith("mix") - ) { - console.log("Ignoro marker per parte Mix:", marker.partNumber); - return; - } - - const size = partSizes[marker.partNumber] || globalMarkerSize; - const radius = size / 2; - const fontSize = Math.max(10, Math.round(size * 0.65)); - - const markerColor = - marker.color || partColors[marker.partNumber] || "#ff0000"; - - const circle = new fabric.Circle({ - radius: radius, - fill: markerColor, - stroke: markerColor, - strokeWidth: 1, - left: marker.x * photoData.scale, - top: marker.y * photoData.scale, - originX: "center", - originY: "center", - selectable: true, - hasControls: false, - lockScalingX: true, - lockScalingY: true, - lockRotation: true, - }); - - const text = new fabric.Text(marker.partNumber.toString(), { - fontFamily: "Arial", - fontSize: fontSize, - fontWeight: "bold", - fill: "#ffffff", - left: marker.x * photoData.scale, - top: marker.y * photoData.scale, - originX: "center", - originY: "middle", - selectable: true, - hasControls: false, - lockScalingX: true, - lockScalingY: true, - lockRotation: true, - }); - - const group = new fabric.Group([circle, text], { - left: marker.x * photoData.scale, - top: marker.y * photoData.scale, - originX: "center", - originY: "center", - selectable: true, - hasControls: false, - lockScalingX: true, - lockScalingY: true, - lockRotation: true, - }); - - group.markerId = marker.id; - group.partNumber = marker.partNumber; - - group.on("moving", function () { - marker.x = this.left / photoData.scale; - marker.y = this.top / photoData.scale; - console.log("Marker spostato:", { - partNumber: marker.partNumber, - x: marker.x, - y: marker.y, - }); - markUnsaved(); - }); - - fabricCanvas.add(group); - markerObjects[marker.id] = group; - }); - - fabricCanvas.renderAll(); - console.log( - "Canvas aggiornato, numero di marker:", - Object.keys(markerObjects).length, - ); - } - - function updateDescriptions() { - console.log("updateDescriptions chiamato"); - const currentPhoto = $("#samplePhotoAnnotations").attr("src"); - const annotations = photoAnnotations[currentPhoto] || { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - const showMixParts = $("#showMixPartsAnnotations").is(":checked"); - - if (!annotations.hasDescriptions) { - if (descriptionTextbox) { - fabricCanvas.remove(descriptionTextbox); - descriptionTextbox = null; - fabricCanvas.renderAll(); - } - console.log( - "Nessuna descrizione attiva, rimuovo textbox se presente.", - ); - return; - } - - const partsList = partsListData - .filter( - (part) => - showMixParts || - !part.part_description.toLowerCase().startsWith("mix"), - ) - .map((part) => `${part.part_number} ${part.part_description}`); - - const text = partsList.join("\n"); - console.log("Testo descrizione generato:", text); - - if (descriptionTextbox) { - fabricCanvas.remove(descriptionTextbox); - descriptionTextbox = null; - } - - descriptionTextbox = new fabric.Textbox(text, { - left: annotations.descriptionPosition.x * photoData.scale, - top: annotations.descriptionPosition.y * photoData.scale, - width: annotations.descriptionSize.width, - scaleX: 1, - scaleY: 1, - backgroundColor: "transparent", - fontFamily: "Arial", - fontSize: Math.max(16, Math.round(globalMarkerSize * 0.8)), - fill: "#000000", - padding: 10, - editable: false, - selectable: true, - hasControls: true, - borderColor: "#ccc", - cornerColor: "#888", - cornerSize: 10, - transparentCorners: false, - lockRotation: true, - lockScalingFlip: true, - minScaleLimit: 0.1, - }); - - descriptionTextbox.on("scaling", function () { - fitFontToBox(this); - annotations.descriptionSize.width = this.width * this.scaleX; - annotations.descriptionSize.height = this.height * this.scaleY; - console.log( - "Descrizione ridimensionata:", - annotations.descriptionSize, - ); - markUnsaved(); - }); - - descriptionTextbox.on("moving", function () { - annotations.descriptionPosition.x = this.left / photoData.scale; - annotations.descriptionPosition.y = this.top / photoData.scale; - console.log( - "Descrizione spostata:", - annotations.descriptionPosition, - ); - markUnsaved(); - }); - - fabricCanvas.add(descriptionTextbox); - fitFontToBox(descriptionTextbox); - fabricCanvas.renderAll(); - console.log("Descrizione aggiunta al canvas:", text); - } - - function fitFontToBox(textbox) { - let fontSize = 24; - textbox.set("fontSize", fontSize); - textbox.setCoords(); - - while ( - (textbox.textLines.length * textbox.fontSize * 1.2 > - textbox.height * textbox.scaleY || - textbox._getTransformedDimensions().x > - textbox.width * textbox.scaleX) && - fontSize > 8 - ) { - fontSize -= 1; - textbox.set("fontSize", fontSize); - textbox.setCoords(); - } - - while ( - textbox.textLines.length * textbox.fontSize * 1.2 < - textbox.height * textbox.scaleY && - textbox._getTransformedDimensions().x < - textbox.width * textbox.scaleX && - fontSize < 32 - ) { - fontSize += 1; - textbox.set("fontSize", fontSize); - textbox.setCoords(); - } - } - - function clearCanvasMarkers(clearDescriptions = true) { - console.log( - "clearCanvasMarkers chiamato, clearDescriptions:", - clearDescriptions, - ); - const currentPhoto = $("#samplePhotoAnnotations").attr("src"); - if (clearDescriptions && photoAnnotations[currentPhoto]) { - photoAnnotations[currentPhoto].hasDescriptions = false; - photoAnnotations[currentPhoto].descriptionPosition = { - x: 10, - y: 10, - }; - photoAnnotations[currentPhoto].descriptionSize = { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }; - if (descriptionTextbox) { - fabricCanvas.remove(descriptionTextbox); - descriptionTextbox = null; - } - } - - for (let markerId in markerObjects) { - fabricCanvas.remove(markerObjects[markerId]); - delete markerObjects[markerId]; - } - markerObjects = {}; - - const canvas = document.getElementById("photoCanvasAnnotations"); - const ctx = canvas.getContext("2d"); - canvas.width = photoData.naturalWidth; - canvas.height = photoData.naturalHeight; - canvas.style.width = `${photoData.displayWidth}px`; - canvas.style.height = `${photoData.displayHeight}px`; - ctx.clearRect(0, 0, canvas.width, canvas.height); - if ($("#samplePhotoAnnotations")[0].naturalWidth) { - ctx.drawImage( - $("#samplePhotoAnnotations")[0], - 0, - 0, - canvas.width, - canvas.height, - ); - } - updateMarkers(); - if (photoAnnotations[currentPhoto]?.hasDescriptions) { - updateDescriptions(); - } - markUnsaved(); - } - - function undoLastMarker() { - console.log("undoLastMarker chiamato"); - const currentPhoto = $("#samplePhotoAnnotations").attr("src"); - if ( - photoAnnotations[currentPhoto] && - photoAnnotations[currentPhoto].markers.length > 0 - ) { - const lastMarker = photoAnnotations[currentPhoto].markers.pop(); - if (markerObjects[lastMarker.id]) { - fabricCanvas.remove(markerObjects[lastMarker.id]); - delete markerObjects[lastMarker.id]; - fabricCanvas.renderAll(); - } - console.log("Ultimo marker rimosso:", lastMarker); - markUnsaved(); - } - } - - // Delegazione evento per il pulsante "Descrizioni" - $(document) - .off("click.addDescriptions", "#addDescriptionsBtnAnnotations") - .on( - "click.addDescriptions", - "#addDescriptionsBtnAnnotations", - function (e) { - e.preventDefault(); - e.stopPropagation(); - console.log( - "Evento click su #addDescriptionsBtnAnnotations, ID elemento:", - $(this).attr("id"), - ); - if (!$("#addDescriptionsBtnAnnotations").length) { - console.error( - "Pulsante #addDescriptionsBtnAnnotations non trovato nel DOM.", - ); - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - const currentPhoto = $("#samplePhotoAnnotations").attr("src"); - if (!photoAnnotations[currentPhoto]) { - photoAnnotations[currentPhoto] = { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - } - photoAnnotations[currentPhoto].hasDescriptions = true; - updateDescriptions(); - markUnsaved(); - }, - ); - - // Delegazione evento per il pulsante "Rimuovi" - $(document) - .off("click.removeAnnotations", "#removeAnnotationsBtnAnnotations") - .on( - "click.removeAnnotations", - "#removeAnnotationsBtnAnnotations", - function (e) { - e.preventDefault(); - e.stopPropagation(); - console.log( - "Evento click su #removeAnnotationsBtnAnnotations, ID elemento:", - $(this).attr("id"), - ); - if (!$("#removeAnnotationsBtnAnnotations").length) { - console.error( - "Pulsante #removeAnnotationsBtnAnnotations non trovato nel DOM.", - ); - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - clearCanvasMarkers(true); - }, - ); - - // Delegazione evento per il pulsante "Undo" - $(document) - .off("click.undoMarker", "#undoMarkerBtnAnnotations") - .on("click.undoMarker", "#undoMarkerBtnAnnotations", function (e) { - e.preventDefault(); - e.stopPropagation(); - console.log( - "Evento click su #undoMarkerBtnAnnotations, ID elemento:", - $(this).attr("id"), - ); - undoLastMarker(); - }); - - // =================== - // SAVE PHOTO - // =================== - $(document) - .off("click.savePhoto", "#savePhotoBtnAnnotations") - .on("click.savePhoto", "#savePhotoBtnAnnotations", function (e) { - e.preventDefault(); - e.stopPropagation(); - console.log( - "Evento click su #savePhotoBtnAnnotations, ID elemento:", - $(this).attr("id"), - ); - if (!$("#samplePhotoAnnotations").attr("src")) { - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - if (!fabricCanvas) { - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - const canvas = document.getElementById("photoCanvasAnnotations"); - const ctx = canvas.getContext("2d"); - const img = $("#samplePhotoAnnotations")[0]; - - if (!img.complete || img.naturalWidth === 0) { - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - canvas.width = photoData.naturalWidth; - canvas.height = photoData.naturalHeight; - ctx.drawImage(img, 0, 0, canvas.width, canvas.height); - - try { - const fabricDataURL = fabricCanvas.toDataURL({ - format: "png", - multiplier: 1 / photoData.scale, - }); - - const tempImg = new Image(); - tempImg.src = fabricDataURL; - tempImg.onload = function () { - ctx.drawImage(tempImg, 0, 0, canvas.width, canvas.height); - - fetch(fabricDataURL) - .then((res) => res.blob()) - .then((blob) => { - canvas.toBlob(function (blob) { - if (!blob) { - const errorMsg = $( - '', - ); - $("#annotationsModal .modal-body").prepend( - errorMsg, - ); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - const timestamp = new Date() - .toISOString() - .replace(/[:.]/g, "-"); - const iddatadb = - $("#annotationsModal").data("iddatadb"); - const idquotations = - $("#annotationsModal").data("idquotations"); - const id = iddatadb || idquotations; - const endpoint = idquotations - ? "save_annotated_photo_quotation.php" - : "save_annotated_photo.php"; - const finalName = `photo_${id}_${timestamp}.png`; - - const formData = new FormData(); - formData.append("file", blob, finalName); - formData.append("filename", finalName); - formData.append( - idquotations ? "idquotations" : "iddatadb", - id, - ); - - $.ajax({ - url: endpoint, - method: "POST", - data: formData, - processData: false, - contentType: false, - success: function (response) { - if (response.success) { - const successMsg = $( - '", - ); - $( - "#annotationsModal .modal-body", - ).prepend(successMsg); - setTimeout(function () { - successMsg.fadeOut( - 500, - function () { - $(this).remove(); - }, - ); - }, 5000); - - const photoSelector = $( - "#photoSelectorAnnotations", - ); - if (photoSelector.length > 0) { - const newPhotoPath = - response.file_path; - const newPhotoName = - newPhotoPath - .split("/") - .pop(); - const optionCount = - photoSelector.find( - "option", - ).length; - - const newOption = $( - "", - ) - .val(newPhotoPath) - .text( - `Photo ${optionCount + 1} - ${newPhotoName}`, - ); - photoSelector.append(newOption); - photoSelector - .val(newPhotoPath) - .trigger("change"); - } - - unsavedChanges = false; - } else { - const errorMsg = $( - '", - ); - $( - "#annotationsModal .modal-body", - ).prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut( - 500, - function () { - $(this).remove(); - }, - ); - }, 5000); - } - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $( - "#annotationsModal .modal-body", - ).prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - }, "image/png"); - }); - }; - } catch (e) { - const errorMsg = $( - '", - ); - $("#annotationsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }); - - function markUnsaved() { - if (!unsavedChanges) { - unsavedChanges = true; - console.log("Modifiche non salvate rilevate."); - } - } -}); diff --git a/public/userarea/apply_routine.php b/public/userarea/apply_routine.php deleted file mode 100644 index 601fb8f..0000000 --- a/public/userarea/apply_routine.php +++ /dev/null @@ -1,50 +0,0 @@ - '', 'rows' => [], 'columns' => [], 'template_id' => 0, 'filename' => '', 'excel_data' => []]; - -try { - if ($_SERVER['REQUEST_METHOD'] === 'POST') { - $input = json_decode(file_get_contents('php://input'), true); - $template_id = isset($input['template_id']) ? intval($input['template_id']) : 0; - $filename = $input['routine_data']['filename'] ?? ''; - $headerrow = $input['routine_data']['headerrow'] ?? 1; - $excelData = $input['excel_data'] ?? []; - $routineData = $input['routine_data'] ?? []; - - if (!$filename || empty($excelData)) { - throw new Exception("Dati della routine mancanti."); - } - - $routineFile = __DIR__ . '/routines/' . $filename; - if (file_exists($routineFile)) { - include_once $routineFile; - $routineData['xls_headers'] = $_SESSION['headers'] ?? []; - applyRoutine($excelData, $routineData); // Modifica $excelData in place - error_log("Routine {$routineData['name']} applicata (file: {$filename}) per template {$template_id}, header row: {$headerrow}"); - } else { - throw new Exception("File della routine non trovato: $routineFile"); - } - - // Aggiorna la sessione con i dati modificati - $_SESSION['excel_data'] = $excelData; - - $response['excel_data'] = $excelData; - $response['rows'] = array_column($excelData, 'data'); - $response['columns'] = $_SESSION['headers']; - $response['template_id'] = $template_id; - $response['filename'] = $input['filename'] ?? ''; - } else { - $response['error'] = "Richiesta non valida."; - } -} catch (Exception $e) { - $response['error'] = "Errore durante l'applicazione della routine: " . $e->getMessage(); - error_log("Exception in apply_routine.php: " . $e->getMessage()); -} - -ob_end_clean(); -header('Content-Type: application/json'); -echo json_encode($response); -exit; diff --git a/public/userarea/class/chatpdf_helper.php b/public/userarea/class/chatpdf_helper.php new file mode 100644 index 0000000..e1fd8b2 --- /dev/null +++ b/public/userarea/class/chatpdf_helper.php @@ -0,0 +1,88 @@ +apiBase}/sources/add-file"); + $cfile = new CURLFile($pdfPath, 'application/pdf', basename($pdfPath)); + + curl_setopt_array($ch, [ + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => ['file' => $cfile], + CURLOPT_HTTPHEADER => [ + "x-api-key: {$this->apiKey}" + ], + CURLOPT_RETURNTRANSFER => true, + ]); + + $response = curl_exec($ch); + curl_close($ch); + + $result = json_decode($response, true); + return $result['sourceId'] ?? null; + } + + // Esegue una domanda al PDF caricato + public function askPdf($sourceId, $question) + { + $apiKey = $_ENV['CHATPDF_API_KEY'] ?? null; + if (!$apiKey) { + throw new Exception("ChatPDF API key not found in .env"); + } + + $url = "https://api.chatpdf.com/v1/chats/message"; + + $payload = json_encode([ + "sourceId" => $sourceId, + "messages" => [ + [ + "role" => "user", + "content" => $question + ] + ] + ]); + + $ch = curl_init($url); + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => true, + CURLOPT_HTTPHEADER => [ + "x-api-key: $apiKey", + "Content-Type: application/json" + ], + CURLOPT_POSTFIELDS => $payload, + ]); + + $response = curl_exec($ch); + if (curl_errno($ch)) { + throw new Exception('cURL error: ' . curl_error($ch)); + } + curl_close($ch); + + $data = json_decode($response, true); + + // Debug temporaneo + file_put_contents( + __DIR__ . '/../debug_chatpdf.log', + "Question: {$question}\nResponse: {$response}\n\n", + FILE_APPEND + ); + + if (isset($data['content'])) { + return trim($data['content']); + } + + // ChatPDF a volte restituisce una lista di risposte + if (isset($data[0]['content'])) { + return trim($data[0]['content']); + } + + return null; + } +} diff --git a/public/userarea/client_files.php b/public/userarea/client_files.php new file mode 100644 index 0000000..f877fed --- /dev/null +++ b/public/userarea/client_files.php @@ -0,0 +1,249 @@ +getConnection(); + +// === Carica elenco clienti === +$clients = $pdo->query("SELECT idclient, client_name FROM clients ORDER BY client_name")->fetchAll(PDO::FETCH_ASSOC); +?> + + + + + + + Client Files Management + + + + + + + + + +
    + + +
    +
    +
    +

    📁 Client File Management

    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    📄 Upload Mapping File (PDF)
    +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    💰 Upload Price List (PDF)
    +
    + +
    + +
    + +
    +
    +
    +
    + +
    +
    📋 Uploaded Files
    + +
    + + + + + + + + + + + + + +
    IDClientFile TypeFilenameSource IDUploaded ByUpload DateActions
    +
    +
    +
    +
    + + +
    + + + + + + + + + + \ No newline at end of file diff --git a/public/userarea/client_files_delete.php b/public/userarea/client_files_delete.php new file mode 100644 index 0000000..eb51185 --- /dev/null +++ b/public/userarea/client_files_delete.php @@ -0,0 +1,33 @@ +getConnection(); + +header('Content-Type: application/json'); + +$id = intval($_POST['id'] ?? 0); +if ($id <= 0) { + echo json_encode(['status' => 'error', 'message' => 'Invalid file ID']); + exit; +} + +try { + // Recupera il nome del file + $stmt = $pdo->prepare("SELECT filename FROM client_files WHERE id = ?"); + $stmt->execute([$id]); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($row && !empty($row['filename'])) { + $filePath = __DIR__ . '/../uploads/client_files/' . $row['filename']; + if (file_exists($filePath)) { + unlink($filePath); // elimina file fisico + } + } + + // Cancella riga dal DB + $pdo->prepare("DELETE FROM client_files WHERE id = ?")->execute([$id]); + + echo json_encode(['status' => 'ok']); +} catch (Exception $e) { + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} diff --git a/public/userarea/client_files_list.php b/public/userarea/client_files_list.php new file mode 100644 index 0000000..c755478 --- /dev/null +++ b/public/userarea/client_files_list.php @@ -0,0 +1,36 @@ +getConnection(); + +header('Content-Type: application/json'); + +try { + $idclient = intval($_GET['idclient'] ?? 0); + + $query = " + SELECT + cf.id, + c.client_name, + cf.file_type, + cf.filename, + cf.source_id, + cf.upload_date, + cf.notes + FROM client_files cf + LEFT JOIN clients c ON c.idclient = cf.idclient + " . ($idclient > 0 ? "WHERE cf.idclient = :idclient" : "") . " + ORDER BY cf.upload_date DESC + "; + + $stmt = $pdo->prepare($query); + if ($idclient > 0) { + $stmt->bindValue(':idclient', $idclient, PDO::PARAM_INT); + } + $stmt->execute(); + $data = $stmt->fetchAll(PDO::FETCH_ASSOC); + + echo json_encode($data); +} catch (Exception $e) { + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} diff --git a/public/userarea/client_files_upload.php b/public/userarea/client_files_upload.php new file mode 100644 index 0000000..7aa7e5b --- /dev/null +++ b/public/userarea/client_files_upload.php @@ -0,0 +1,98 @@ +getConnection(); + + if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + throw new Exception("Invalid request method."); + } + + $idclient = intval($_POST['idclient'] ?? 0); + $file_type = $_POST['file_type'] ?? ''; + $uploaded_by = $_POST['uploaded_by'] ?? null; // opzionale + $notes = $_POST['notes'] ?? null; + + if ($idclient <= 0 || empty($file_type) || !isset($_FILES['file'])) { + throw new Exception("Missing required parameters."); + } + + // Cartella di upload + $uploadDir = __DIR__ . '/../uploads/client_files/'; + if (!is_dir($uploadDir)) { + mkdir($uploadDir, 0777, true); + } + + $file = $_FILES['file']; + if ($file['error'] !== UPLOAD_ERR_OK) { + throw new Exception("File upload error."); + } + + $filename = time() . '_' . preg_replace('/[^A-Za-z0-9_.-]/', '_', basename($file['name'])); + $targetPath = $uploadDir . $filename; + + if (!move_uploaded_file($file['tmp_name'], $targetPath)) { + throw new Exception("Failed to move uploaded file."); + } + + // === 1️⃣ Inserisci nel DB senza source_id inizialmente === + $stmt = $pdo->prepare(" + INSERT INTO client_files (idclient, file_type, filename, uploaded_by, notes) + VALUES (:idclient, :file_type, :filename, :uploaded_by, :notes) + "); + $stmt->execute([ + ':idclient' => $idclient, + ':file_type' => $file_type, + ':filename' => $filename, + ':uploaded_by' => $uploaded_by, + ':notes' => $notes + ]); + $insertId = $pdo->lastInsertId(); + + // === 2️⃣ Upload verso ChatPDF === + $dotenv = Dotenv::createImmutable(dirname(__DIR__, 2)); + $dotenv->load(); + $apiKey = $_ENV['CHATPDF_API_KEY'] ?? null; + + if (!$apiKey) { + throw new Exception("ChatPDF API key not found in .env"); + } + + $curl = curl_init(); + curl_setopt_array($curl, [ + CURLOPT_URL => "https://api.chatpdf.com/v1/sources/add-file", + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HTTPHEADER => ["x-api-key: $apiKey"], + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => [ + "file" => new CURLFile($targetPath) + ], + ]); + + $response = curl_exec($curl); + $err = curl_error($curl); + curl_close($curl); + + if ($err) throw new Exception("ChatPDF API error: $err"); + + $json = json_decode($response, true); + $sourceId = $json['sourceId'] ?? null; + + // === 3️⃣ Se ChatPDF restituisce un source_id, aggiorniamo il DB === + if ($sourceId) { + $upd = $pdo->prepare("UPDATE client_files SET source_id = :source_id WHERE id = :id"); + $upd->execute([':source_id' => $sourceId, ':id' => $insertId]); + $msg = "File uploaded and ChatPDF registered (sourceId: $sourceId)"; + } else { + $msg = "File uploaded, but ChatPDF did not return a source ID. Response: " . json_encode($json); + } + + echo json_encode(['status' => 'ok', 'message' => $msg, 'source_id' => $sourceId]); +} catch (Exception $e) { + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} diff --git a/public/userarea/cssinclude.php b/public/userarea/cssinclude.php index 58417f9..c2b90d4 100644 --- a/public/userarea/cssinclude.php +++ b/public/userarea/cssinclude.php @@ -19,4 +19,87 @@ - \ No newline at end of file + + + \ No newline at end of file diff --git a/public/userarea/customfield_values_response.json b/public/userarea/customfield_values_response.json deleted file mode 100644 index ce16765..0000000 --- a/public/userarea/customfield_values_response.json +++ /dev/null @@ -1 +0,0 @@ -{"146":[{"IdCustomFieldsValue":235,"Valore":"Pigmentato"},{"IdCustomFieldsValue":236,"Valore":"Anilina"},{"IdCustomFieldsValue":237,"Valore":"Verniciato"},{"IdCustomFieldsValue":238,"Valore":"Laminato"},{"IdCustomFieldsValue":259,"Valore":"Semi-Anilina"},{"IdCustomFieldsValue":274,"Valore":"Scamosciato"},{"IdCustomFieldsValue":305,"Valore":"Pigmented"},{"IdCustomFieldsValue":306,"Valore":"Aniline"},{"IdCustomFieldsValue":307,"Valore":"Patent"},{"IdCustomFieldsValue":308,"Valore":"Metallic"},{"IdCustomFieldsValue":309,"Valore":"Semi-Aniline"},{"IdCustomFieldsValue":310,"Valore":"Suede"},{"IdCustomFieldsValue":311,"Valore":"Nubuck"},{"IdCustomFieldsValue":336,"Valore":"Cavallino"},{"IdCustomFieldsValue":344,"Valore":"Abrasivato"},{"IdCustomFieldsValue":500,"Valore":"Gommato"},{"IdCustomFieldsValue":528,"Valore":"Paillettes"},{"IdCustomFieldsValue":538,"Valore":"PU"},{"IdCustomFieldsValue":559,"Valore":"Tintura di Botte"},{"IdCustomFieldsValue":570,"Valore":"Crosta"},{"IdCustomFieldsValue":572,"Valore":"Semianilina\/Stampato"},{"IdCustomFieldsValue":644,"Valore":"Accoppiato"},{"IdCustomFieldsValue":657,"Valore":"Serigrafato"},{"IdCustomFieldsValue":661,"Valore":"Stampato"},{"IdCustomFieldsValue":691,"Valore":"Brush-Off"},{"IdCustomFieldsValue":697,"Valore":"Crust"},{"IdCustomFieldsValue":707,"Valore":"Lucido Lissato"},{"IdCustomFieldsValue":729,"Valore":"Shearling"},{"IdCustomFieldsValue":733,"Valore":"Printed"},{"IdCustomFieldsValue":750,"Valore":"Ink-Jet"},{"IdCustomFieldsValue":804,"Valore":"Fur"},{"IdCustomFieldsValue":874,"Valore":"Esotico"},{"IdCustomFieldsValue":896,"Valore":"Shearling con lato carne scamosciato"},{"IdCustomFieldsValue":959,"Valore":"Ink-jet\/ Con film PU \"By-Cast\""},{"IdCustomFieldsValue":970,"Valore":"Anilina\/Ink-jet"},{"IdCustomFieldsValue":1020,"Valore":"Coated"},{"IdCustomFieldsValue":1021,"Valore":"By-Cast"},{"IdCustomFieldsValue":1024,"Valore":"Perlato"},{"IdCustomFieldsValue":1025,"Valore":"Pearled"},{"IdCustomFieldsValue":1030,"Valore":"Pelo"},{"IdCustomFieldsValue":1035,"Valore":"Glitterato"},{"IdCustomFieldsValue":1099,"Valore":"Transfer"},{"IdCustomFieldsValue":1111,"Valore":"Coupled"},{"IdCustomFieldsValue":1153,"Valore":"Saffiano"},{"IdCustomFieldsValue":1186,"Valore":"Pigmentato\/Accoppiato"},{"IdCustomFieldsValue":1238,"Valore":"Aniline\/Fixed"},{"IdCustomFieldsValue":1240,"Valore":"Laminated Foil Finish"},{"IdCustomFieldsValue":1348,"Valore":"Con applicazioni"},{"IdCustomFieldsValue":1349,"Valore":"Pony calf"},{"IdCustomFieldsValue":1415,"Valore":"Glittered"},{"IdCustomFieldsValue":1437,"Valore":"Scraped"},{"IdCustomFieldsValue":1445,"Valore":"Resinato"},{"IdCustomFieldsValue":1620,"Valore":"Stampa digitale"},{"IdCustomFieldsValue":1661,"Valore":"Laminato parziale"},{"IdCustomFieldsValue":1734,"Valore":"Hair"},{"IdCustomFieldsValue":1787,"Valore":"Smerigliato Rifinito"},{"IdCustomFieldsValue":1827,"Valore":"Uncoated"},{"IdCustomFieldsValue":1828,"Valore":"Nappa"},{"IdCustomFieldsValue":1942,"Valore":"M\u00e9tallique "},{"IdCustomFieldsValue":1943,"Valore":"Camoscina"},{"IdCustomFieldsValue":1974,"Valore":"Pigment\u00e9"},{"IdCustomFieldsValue":2002,"Valore":"Partial metallic finish"},{"IdCustomFieldsValue":2551,"Valore":"Coated con glitter"},{"IdCustomFieldsValue":3107,"Valore":"Metallic Suede"},{"IdCustomFieldsValue":3208,"Valore":"Plotter"},{"IdCustomFieldsValue":3216,"Valore":"Serigrafia con fissativo"},{"IdCustomFieldsValue":3236,"Valore":"Super Natural"},{"IdCustomFieldsValue":3239,"Valore":"Velour"},{"IdCustomFieldsValue":3251,"Valore":"Canvas"},{"IdCustomFieldsValue":3328,"Valore":"Resina stirata"},{"IdCustomFieldsValue":3335,"Valore":"Lucido"},{"IdCustomFieldsValue":3364,"Valore":"Palmellato"},{"IdCustomFieldsValue":3365,"Valore":"Volanato naturale"},{"IdCustomFieldsValue":3366,"Valore":"Trattamento Scotchgard"},{"IdCustomFieldsValue":3367,"Valore":"Passante in botte"},{"IdCustomFieldsValue":3370,"Valore":"Embroidery"},{"IdCustomFieldsValue":3371,"Valore":"Patchwork lettering"},{"IdCustomFieldsValue":3409,"Valore":"Tinto Pezza"},{"IdCustomFieldsValue":3410,"Valore":"Pronto per Tinta"},{"IdCustomFieldsValue":3411,"Valore":"Tinto Filo"},{"IdCustomFieldsValue":3412,"Valore":"Greggio"},{"IdCustomFieldsValue":3413,"Valore":"Vacchetta"},{"IdCustomFieldsValue":3424,"Valore":"Naturale"},{"IdCustomFieldsValue":3442,"Valore":"Barrel dyeing"},{"IdCustomFieldsValue":3454,"Valore":"Split leather with film"},{"IdCustomFieldsValue":3455,"Valore":"Printed Suede"},{"IdCustomFieldsValue":3460,"Valore":"Pigmented\/Patent"},{"IdCustomFieldsValue":3468,"Valore":"Non rifinito"},{"IdCustomFieldsValue":3482,"Valore":"Cruck"},{"IdCustomFieldsValue":3491,"Valore":"Stampa serigrafica"},{"IdCustomFieldsValue":3494,"Valore":"Fissativo all'acqua"},{"IdCustomFieldsValue":3498,"Valore":"Tintura"},{"IdCustomFieldsValue":3506,"Valore":"Rovesciato"},{"IdCustomFieldsValue":3511,"Valore":"Spalmato"},{"IdCustomFieldsValue":3514,"Valore":"Serigraphy"},{"IdCustomFieldsValue":3867,"Valore":"None"},{"IdCustomFieldsValue":4052,"Valore":"Pigmentato Abrasivato"},{"IdCustomFieldsValue":4082,"Valore":"Full Grain"},{"IdCustomFieldsValue":4109,"Valore":"Opaco"},{"IdCustomFieldsValue":4124,"Valore":"Embossed"},{"IdCustomFieldsValue":4135,"Valore":"Mat"},{"IdCustomFieldsValue":4136,"Valore":"Lisse"},{"IdCustomFieldsValue":4137,"Valore":"Coton"},{"IdCustomFieldsValue":4143,"Valore":"Alo\u00e9"},{"IdCustomFieldsValue":4144,"Valore":"Torino"},{"IdCustomFieldsValue":4145,"Valore":"Microsuede"},{"IdCustomFieldsValue":4151,"Valore":"Miroir"},{"IdCustomFieldsValue":4166,"Valore":"Stampa UV"},{"IdCustomFieldsValue":4185,"Valore":"Lavable"},{"IdCustomFieldsValue":4219,"Valore":"Radika"},{"IdCustomFieldsValue":4220,"Valore":"Natural"},{"IdCustomFieldsValue":4222,"Valore":"Abilo N\u00e9on"},{"IdCustomFieldsValue":4250,"Valore":"Canyon"},{"IdCustomFieldsValue":4257,"Valore":"Alo\u00e9 Shiny"},{"IdCustomFieldsValue":4258,"Valore":"Lisse\/Recoupe"},{"IdCustomFieldsValue":4280,"Valore":"Water-repellent"},{"IdCustomFieldsValue":4283,"Valore":"Lisse\/Entrepeaux"},{"IdCustomFieldsValue":4286,"Valore":"Metallo liquido spray + Stampa"},{"IdCustomFieldsValue":4288,"Valore":"Tinto"},{"IdCustomFieldsValue":4388,"Valore":"Cerato"},{"IdCustomFieldsValue":4389,"Valore":"Mat\/Recoupe"},{"IdCustomFieldsValue":4392,"Valore":"Pigmentato\/Poliuretanico finale"},{"IdCustomFieldsValue":4393,"Valore":"Semianilina Laminato"},{"IdCustomFieldsValue":4394,"Valore":"Semianilina Pigmentato"},{"IdCustomFieldsValue":4399,"Valore":"Primitivo"},{"IdCustomFieldsValue":4400,"Valore":"Ombre"},{"IdCustomFieldsValue":4401,"Valore":"Anilina Pigmentato"},{"IdCustomFieldsValue":4405,"Valore":"Caresse"},{"IdCustomFieldsValue":4429,"Valore":"Ultras\/Recoupe"},{"IdCustomFieldsValue":4552,"Valore":"Semi-Anilina + Stampa ink jet"},{"IdCustomFieldsValue":4563,"Valore":"Torino Ultra Brillante"},{"IdCustomFieldsValue":4573,"Valore":"Supernatural\/aniline"},{"IdCustomFieldsValue":5054,"Valore":"Peau d'ange"},{"IdCustomFieldsValue":5128,"Valore":"Mirage"},{"IdCustomFieldsValue":5129,"Valore":"Mirage\/Relance"},{"IdCustomFieldsValue":5130,"Valore":"Croute Chrome"},{"IdCustomFieldsValue":5309,"Valore":"PU Coated"},{"IdCustomFieldsValue":5315,"Valore":"Pigmentato stampato"},{"IdCustomFieldsValue":5498,"Valore":"Rubberized"},{"IdCustomFieldsValue":5610,"Valore":"By-Cast PU"},{"IdCustomFieldsValue":5615,"Valore":"Lamina liquida"},{"IdCustomFieldsValue":6193,"Valore":"Nubuck\/Rubber coated"},{"IdCustomFieldsValue":8523,"Valore":"Total print"},{"IdCustomFieldsValue":12774,"Valore":"Etoffe"},{"IdCustomFieldsValue":12775,"Valore":"Croute"},{"IdCustomFieldsValue":12776,"Valore":"Miroir Light"},{"IdCustomFieldsValue":12777,"Valore":"Etriviere"},{"IdCustomFieldsValue":12949,"Valore":"Vernice (Vernice\/Semianilina)"},{"IdCustomFieldsValue":13501,"Valore":"Seta Lux"},{"IdCustomFieldsValue":13733,"Valore":"Aniline Pigmented"},{"IdCustomFieldsValue":13807,"Valore":"Naturale\/Semilucido"},{"IdCustomFieldsValue":14047,"Valore":"Fissativo"},{"IdCustomFieldsValue":14140,"Valore":"Nubuk"},{"IdCustomFieldsValue":14141,"Valore":"Satin Soft"},{"IdCustomFieldsValue":14142,"Valore":"Priene\/ Millenium "},{"IdCustomFieldsValue":14887,"Valore":"Pigmented\/Metal"}],"147":[{"IdCustomFieldsValue":239,"Valore":"Cromo"},{"IdCustomFieldsValue":240,"Valore":"Vegetale"},{"IdCustomFieldsValue":272,"Valore":"\/"},{"IdCustomFieldsValue":273,"Valore":"Mista"},{"IdCustomFieldsValue":301,"Valore":"Chrome"},{"IdCustomFieldsValue":302,"Valore":"Vegetal"},{"IdCustomFieldsValue":303,"Valore":"Mixed"},{"IdCustomFieldsValue":519,"Valore":"White"},{"IdCustomFieldsValue":520,"Valore":"Bianca"},{"IdCustomFieldsValue":566,"Valore":"Chrome \/ Synthetic"},{"IdCustomFieldsValue":682,"Valore":"Sintetica"},{"IdCustomFieldsValue":1001,"Valore":"Vegetallizzato"},{"IdCustomFieldsValue":1054,"Valore":"Synthetic"},{"IdCustomFieldsValue":1208,"Valore":"Allume"},{"IdCustomFieldsValue":1264,"Valore":"Minerale"},{"IdCustomFieldsValue":1535,"Valore":"Blanche"},{"IdCustomFieldsValue":2447,"Valore":"Mineral"},{"IdCustomFieldsValue":2590,"Valore":"Semi-Vegetal"},{"IdCustomFieldsValue":2712,"Valore":"Metal free"},{"IdCustomFieldsValue":2737,"Valore":"Semi-Chrome"},{"IdCustomFieldsValue":2777,"Valore":"Wet Blue"},{"IdCustomFieldsValue":3090,"Valore":"Non conciata"},{"IdCustomFieldsValue":3199,"Valore":"Chrome free"},{"IdCustomFieldsValue":3469,"Valore":"Slow vegetal"},{"IdCustomFieldsValue":3527,"Valore":"Wet White"},{"IdCustomFieldsValue":3821,"Valore":"Sintetica + Cromo"},{"IdCustomFieldsValue":3888,"Valore":"Non metallica"},{"IdCustomFieldsValue":4568,"Valore":"Mineral"},{"IdCustomFieldsValue":5390,"Valore":"Cromo \/ Sintetico"},{"IdCustomFieldsValue":5398,"Valore":"Synthetique"},{"IdCustomFieldsValue":5647,"Valore":"Pickel"},{"IdCustomFieldsValue":6192,"Valore":"Chrome\/Mixed"},{"IdCustomFieldsValue":8709,"Valore":"Mixte"},{"IdCustomFieldsValue":11356,"Valore":"Mista Cromo"},{"IdCustomFieldsValue":13713,"Valore":"Bio"},{"IdCustomFieldsValue":13714,"Valore":"Bio\/Metal free"}],"150":[{"IdCustomFieldsValue":261,"Valore":"Pelletteria"},{"IdCustomFieldsValue":262,"Valore":"Calzatura (Tomaio)"},{"IdCustomFieldsValue":263,"Valore":"Calzatura (Fodera)"},{"IdCustomFieldsValue":264,"Valore":"Abbigliamento"},{"IdCustomFieldsValue":265,"Valore":"Arredamento"},{"IdCustomFieldsValue":266,"Valore":"Calzatura\/Pelletteria"},{"IdCustomFieldsValue":267,"Valore":"Cinture"},{"IdCustomFieldsValue":269,"Valore":"Piccola Pelletteria (Portafogli)"},{"IdCustomFieldsValue":270,"Valore":"Valigeria"},{"IdCustomFieldsValue":271,"Valore":"\/"},{"IdCustomFieldsValue":285,"Valore":"Leathergoods"},{"IdCustomFieldsValue":286,"Valore":"Footwear (Upper)"},{"IdCustomFieldsValue":287,"Valore":"Footwear (Lining)"},{"IdCustomFieldsValue":288,"Valore":"Apparel"},{"IdCustomFieldsValue":289,"Valore":"Furnishing"},{"IdCustomFieldsValue":290,"Valore":"Footwear\/Leathergoods"},{"IdCustomFieldsValue":291,"Valore":"Belts"},{"IdCustomFieldsValue":292,"Valore":"Watchstrap"},{"IdCustomFieldsValue":293,"Valore":"Small Leathergood"},{"IdCustomFieldsValue":338,"Valore":"Calzatura"},{"IdCustomFieldsValue":440,"Valore":"Footwear"},{"IdCustomFieldsValue":474,"Valore":"Apparel Trim"},{"IdCustomFieldsValue":495,"Valore":"Pelletteria (Fodera)"},{"IdCustomFieldsValue":582,"Valore":"Leathergoods (Bag)"},{"IdCustomFieldsValue":598,"Valore":"Pelletteria (Borsa)"},{"IdCustomFieldsValue":637,"Valore":"Shoes - Leathergoods"},{"IdCustomFieldsValue":676,"Valore":"Footwear (Insole)"},{"IdCustomFieldsValue":687,"Valore":"Piccola Pelletteria (Cinture)"},{"IdCustomFieldsValue":688,"Valore":"Cinturini da orologio"},{"IdCustomFieldsValue":692,"Valore":"Apparel (Outer)"},{"IdCustomFieldsValue":693,"Valore":"Apparel (Inner)"},{"IdCustomFieldsValue":695,"Valore":"Calzatura (Sottopiedi)"},{"IdCustomFieldsValue":742,"Valore":"Packaging"},{"IdCustomFieldsValue":756,"Valore":"Maroquinerie"},{"IdCustomFieldsValue":757,"Valore":"Maroquinerie (Sac a main)"},{"IdCustomFieldsValue":758,"Valore":"Maroquinerie (Petite maroquinerie)"},{"IdCustomFieldsValue":759,"Valore":"Maroquinerie (Ceintures)"},{"IdCustomFieldsValue":760,"Valore":"Maroquinerie (Bracelets de montres)"},{"IdCustomFieldsValue":761,"Valore":"Maroquinerie (Doublure)"},{"IdCustomFieldsValue":767,"Valore":"Bracelets de montres"},{"IdCustomFieldsValue":775,"Valore":"Pelletteria (Borsa) \/ Piccola Pelletteria (Portafogli)"},{"IdCustomFieldsValue":779,"Valore":"Leathergoods \/Finishedgoods"},{"IdCustomFieldsValue":807,"Valore":"Leathergoods (Lining)"},{"IdCustomFieldsValue":821,"Valore":"Accessori da Abbigliamento"},{"IdCustomFieldsValue":823,"Valore":"Gioielleria"},{"IdCustomFieldsValue":840,"Valore":"Jewellery"},{"IdCustomFieldsValue":855,"Valore":"Piccola Pelletteria"},{"IdCustomFieldsValue":889,"Valore":"Small Leathergood (Belt)"},{"IdCustomFieldsValue":898,"Valore":"Pelletteria (Borsa) \/ Gioielleria"},{"IdCustomFieldsValue":902,"Valore":"V\u00eatements"},{"IdCustomFieldsValue":912,"Valore":"Abbigliamento (Guanti)"},{"IdCustomFieldsValue":986,"Valore":"Leathergoods (Wallet)"},{"IdCustomFieldsValue":1009,"Valore":"Gioielleria \/ Bigiotteria"},{"IdCustomFieldsValue":1010,"Valore":"Bigiotteria"},{"IdCustomFieldsValue":1027,"Valore":"Abbigliamento esterno"},{"IdCustomFieldsValue":1028,"Valore":"Abbigliamento interno"},{"IdCustomFieldsValue":1032,"Valore":"Calzatura sfoderata"},{"IdCustomFieldsValue":1055,"Valore":"Leathergoods (Body of the bag)"},{"IdCustomFieldsValue":1082,"Valore":"Leathergoods (Belt)"},{"IdCustomFieldsValue":1104,"Valore":"Calzatura (Soletto)"},{"IdCustomFieldsValue":1204,"Valore":"Calzatura (fodera\/soletto)"},{"IdCustomFieldsValue":1205,"Valore":"Shoes"},{"IdCustomFieldsValue":1207,"Valore":"Pelletteria \/ Abbigliamento"},{"IdCustomFieldsValue":1236,"Valore":"Ombrelli"},{"IdCustomFieldsValue":1383,"Valore":"Abbigliamento\/Calzatura"},{"IdCustomFieldsValue":1421,"Valore":"Calzatura (Tacco)"},{"IdCustomFieldsValue":1467,"Valore":"Furniture"},{"IdCustomFieldsValue":1514,"Valore":"Footwear (Upper\/Lining)"},{"IdCustomFieldsValue":1662,"Valore":"Leathergoods (Exterior)"},{"IdCustomFieldsValue":1670,"Valore":"Chaussures"},{"IdCustomFieldsValue":1780,"Valore":"Abbigliamento\/Calzatura\/Pelletteria"},{"IdCustomFieldsValue":1970,"Valore":"Accessories"},{"IdCustomFieldsValue":1971,"Valore":"Carta da parati"},{"IdCustomFieldsValue":2087,"Valore":"Glasses case"},{"IdCustomFieldsValue":2190,"Valore":"Calzatura (Tomaio\/Fodera)"},{"IdCustomFieldsValue":2240,"Valore":"Pelletteria \/ Calzatura"},{"IdCustomFieldsValue":2530,"Valore":"Calzatura (Suola)"},{"IdCustomFieldsValue":2570,"Valore":"Occhiali"},{"IdCustomFieldsValue":2635,"Valore":"Footwear (Sandal)"},{"IdCustomFieldsValue":2639,"Valore":"Lining"},{"IdCustomFieldsValue":2671,"Valore":"Portachiavi"},{"IdCustomFieldsValue":3098,"Valore":"Pellicceria"},{"IdCustomFieldsValue":3200,"Valore":"Car seat upholstery"},{"IdCustomFieldsValue":3209,"Valore":"Fodera"},{"IdCustomFieldsValue":3243,"Valore":"Accessoristica"},{"IdCustomFieldsValue":3253,"Valore":"Cuscini da Viaggio"},{"IdCustomFieldsValue":3357,"Valore":"Coulisse"},{"IdCustomFieldsValue":3361,"Valore":"Leathergoods (Handbag)"},{"IdCustomFieldsValue":3369,"Valore":"Leathergoods (Knapsack)"},{"IdCustomFieldsValue":3445,"Valore":"Footwear (Lake shoe)"},{"IdCustomFieldsValue":3453,"Valore":"Apparel (Hat)"},{"IdCustomFieldsValue":3470,"Valore":"Bike saddle"},{"IdCustomFieldsValue":3476,"Valore":"Apparel (Shirts)"},{"IdCustomFieldsValue":3477,"Valore":"Apparel (Jackets)"},{"IdCustomFieldsValue":3478,"Valore":"Leathergoods (Flap)"},{"IdCustomFieldsValue":3484,"Valore":"Upholstery"},{"IdCustomFieldsValue":3485,"Valore":"Saddlery"},{"IdCustomFieldsValue":3519,"Valore":"Apparel (Lining)"},{"IdCustomFieldsValue":3837,"Valore":"Swimwear"},{"IdCustomFieldsValue":3847,"Valore":"Accoppiatura tessuti"},{"IdCustomFieldsValue":3876,"Valore":"Luggage"},{"IdCustomFieldsValue":3891,"Valore":"Pelletteria (Rinforzo)"},{"IdCustomFieldsValue":4041,"Valore":"Bijoux (Lining)"},{"IdCustomFieldsValue":4081,"Valore":"Label"},{"IdCustomFieldsValue":4189,"Valore":"Case"},{"IdCustomFieldsValue":4268,"Valore":"Abbigliamento (Camicia)"},{"IdCustomFieldsValue":4390,"Valore":"Bijoux"},{"IdCustomFieldsValue":4421,"Valore":"Apparel (tights)"},{"IdCustomFieldsValue":4424,"Valore":"Maglieria"},{"IdCustomFieldsValue":4425,"Valore":"Abbigliamento (Sciarpe)"},{"IdCustomFieldsValue":4588,"Valore":"Forniture"},{"IdCustomFieldsValue":4642,"Valore":"Calzatura (Tomaio\/Soletto)"},{"IdCustomFieldsValue":4746,"Valore":"Leathergoods\/Footwear"},{"IdCustomFieldsValue":4749,"Valore":"Orthopedic \/ comfort Shoes"},{"IdCustomFieldsValue":5308,"Valore":"Swimsuit"},{"IdCustomFieldsValue":5394,"Valore":"Pelletteria \/ Accessori"},{"IdCustomFieldsValue":5435,"Valore":"Accessoire"},{"IdCustomFieldsValue":6265,"Valore":"V\u00eatements\/Maroquinerie"},{"IdCustomFieldsValue":12514,"Valore":"\u00c9quitation"},{"IdCustomFieldsValue":12714,"Valore":"Montre"},{"IdCustomFieldsValue":13149,"Valore":"Calzatura (Tomaio\/Sottopiede)"},{"IdCustomFieldsValue":13486,"Valore":"Glasses"},{"IdCustomFieldsValue":13487,"Valore":"Sunglasses"},{"IdCustomFieldsValue":13897,"Valore":"Bagage"},{"IdCustomFieldsValue":13977,"Valore":"Apparel\/Leathergoods\/Footwear"},{"IdCustomFieldsValue":14000,"Valore":"Garment"},{"IdCustomFieldsValue":14023,"Valore":"Leathergoods (Waist bag)"},{"IdCustomFieldsValue":14681,"Valore":"Chaussures\/Maroquinerie"},{"IdCustomFieldsValue":14698,"Valore":"Small Leathergood (Key ring)"},{"IdCustomFieldsValue":14836,"Valore":"Abbigliamento (Costume da bagno)"},{"IdCustomFieldsValue":14991,"Valore":"Footwear\/Leathergoods\/Apparel"},{"IdCustomFieldsValue":15095,"Valore":"Leathergoods (Body of the bag\/Lining)"}],"156":[{"IdCustomFieldsValue":243,"Valore":"Bottone"},{"IdCustomFieldsValue":244,"Valore":"Cerniera"},{"IdCustomFieldsValue":245,"Valore":"Accessorio Metallico"},{"IdCustomFieldsValue":246,"Valore":"Accessorio Plastico"},{"IdCustomFieldsValue":247,"Valore":"Sottotacco"},{"IdCustomFieldsValue":304,"Valore":"Suola"},{"IdCustomFieldsValue":313,"Valore":"Tacco"},{"IdCustomFieldsValue":314,"Valore":"Composite"},{"IdCustomFieldsValue":315,"Valore":"Cuoio\/Pelle (1\/2 Vitello)"},{"IdCustomFieldsValue":316,"Valore":"Cuoio\/Pelle (Bovino)"},{"IdCustomFieldsValue":317,"Valore":"Cuoio\/Pelle (Capra)"},{"IdCustomFieldsValue":318,"Valore":"Cuoio\/Pelle (Coccodrillo)"},{"IdCustomFieldsValue":319,"Valore":"Cuoio\/Pelle (Crosta)"},{"IdCustomFieldsValue":320,"Valore":"Cuoio\/Pelle (Nabuck)"},{"IdCustomFieldsValue":321,"Valore":"Cuoio\/Pelle (Ovocaprino)"},{"IdCustomFieldsValue":322,"Valore":"Cuoio\/Pelle (Rettile)"},{"IdCustomFieldsValue":323,"Valore":"Cuoio\/Pelle (Vitello)"},{"IdCustomFieldsValue":324,"Valore":"Borsa"},{"IdCustomFieldsValue":325,"Valore":"Calzatura"},{"IdCustomFieldsValue":326,"Valore":"Cintura"},{"IdCustomFieldsValue":327,"Valore":"Portafoglio"},{"IdCustomFieldsValue":328,"Valore":"Tessile (Sintetico)"},{"IdCustomFieldsValue":329,"Valore":"Tessile (Ortogonale\/A maglia)"},{"IdCustomFieldsValue":330,"Valore":"Tessile (PVC)"},{"IdCustomFieldsValue":331,"Valore":"Tessile (Spalmato)"},{"IdCustomFieldsValue":332,"Valore":"Tessile (Stampato)"},{"IdCustomFieldsValue":333,"Valore":"Tessile (Accoppiato)"},{"IdCustomFieldsValue":335,"Valore":"Cuoio\/Pelle (Cavallino)"},{"IdCustomFieldsValue":342,"Valore":"Cuoio\/Pelle"},{"IdCustomFieldsValue":343,"Valore":"Tessile"},{"IdCustomFieldsValue":404,"Valore":"Leather (1\/2 Calf)"},{"IdCustomFieldsValue":405,"Valore":"Leather (Calf)"},{"IdCustomFieldsValue":406,"Valore":"Leather (Buffalo)"},{"IdCustomFieldsValue":407,"Valore":"Leather (Goat)"},{"IdCustomFieldsValue":408,"Valore":"Leather (Lamb)"},{"IdCustomFieldsValue":409,"Valore":"Leather (Exotic)"},{"IdCustomFieldsValue":410,"Valore":"Textile"},{"IdCustomFieldsValue":411,"Valore":"Final product"},{"IdCustomFieldsValue":412,"Valore":"Button"},{"IdCustomFieldsValue":413,"Valore":"Handbag"},{"IdCustomFieldsValue":414,"Valore":"Belt"},{"IdCustomFieldsValue":415,"Valore":"Heel"},{"IdCustomFieldsValue":416,"Valore":"Metallic accessories"},{"IdCustomFieldsValue":420,"Valore":"Leather"},{"IdCustomFieldsValue":446,"Valore":"Leather (Ram)"},{"IdCustomFieldsValue":480,"Valore":"Cuoio\/Pelle (Cervo)"},{"IdCustomFieldsValue":481,"Valore":"Cuoio\/Pelle (Vitellino)"},{"IdCustomFieldsValue":483,"Valore":"Wallet"},{"IdCustomFieldsValue":529,"Valore":"Cuoio\/Pelle (Nappa)"},{"IdCustomFieldsValue":533,"Valore":"Leather (Shearling)"},{"IdCustomFieldsValue":534,"Valore":"Leather (Cow)"},{"IdCustomFieldsValue":536,"Valore":"Cuoio\/Pelle (Agnello)"},{"IdCustomFieldsValue":537,"Valore":"Sottopiede"},{"IdCustomFieldsValue":547,"Valore":"Porta I-Pad"},{"IdCustomFieldsValue":558,"Valore":"Cuoio\/Pelle (Daino)"},{"IdCustomFieldsValue":571,"Valore":"Cuoio\/Pelle (Bufalo)"},{"IdCustomFieldsValue":597,"Valore":"Composito"},{"IdCustomFieldsValue":616,"Valore":"Leather (front calf)"},{"IdCustomFieldsValue":643,"Valore":"Cuoio\/Pelle (Canguro)"},{"IdCustomFieldsValue":653,"Valore":"Sole"},{"IdCustomFieldsValue":654,"Valore":"Cuoio\/Pelle (Montone)"},{"IdCustomFieldsValue":655,"Valore":"Cuoio\/Pelle (Volpe)"},{"IdCustomFieldsValue":660,"Valore":"Accessorio \/ Pitone"},{"IdCustomFieldsValue":666,"Valore":"Guanti"},{"IdCustomFieldsValue":667,"Valore":"Prodotto finito"},{"IdCustomFieldsValue":678,"Valore":"Colorante"},{"IdCustomFieldsValue":684,"Valore":"Elaphe Radiata"},{"IdCustomFieldsValue":689,"Valore":"Cuoio\/Pelle (Toro)"},{"IdCustomFieldsValue":690,"Valore":"Semilavorato"},{"IdCustomFieldsValue":696,"Valore":"Cuoio\/Pelle (Spalle)"},{"IdCustomFieldsValue":699,"Valore":"Leathergoods\/Footwear"},{"IdCustomFieldsValue":701,"Valore":"Cuoio\/Pelle (Visone)"},{"IdCustomFieldsValue":702,"Valore":"Wire"},{"IdCustomFieldsValue":705,"Valore":"Tessile (con Applicazioni)"},{"IdCustomFieldsValue":708,"Valore":"Cuoio\/Pelle (Incrociati)"},{"IdCustomFieldsValue":714,"Valore":"Cuoio\/Pelle (Cammello)"},{"IdCustomFieldsValue":717,"Valore":"Shoulder"},{"IdCustomFieldsValue":718,"Valore":"Handle"},{"IdCustomFieldsValue":719,"Valore":"Backpack"},{"IdCustomFieldsValue":731,"Valore":"Panel"},{"IdCustomFieldsValue":734,"Valore":"Textile (Coupled)"},{"IdCustomFieldsValue":736,"Valore":"Accessories"},{"IdCustomFieldsValue":738,"Valore":"Buckle"},{"IdCustomFieldsValue":740,"Valore":"Cuoio\/Pelle (Gropponi)"},{"IdCustomFieldsValue":743,"Valore":"Glittered Textile"},{"IdCustomFieldsValue":748,"Valore":"Leather (Deer)"},{"IdCustomFieldsValue":762,"Valore":"Cuir"},{"IdCustomFieldsValue":763,"Valore":"Doublure (Cro\u00fbte bovin P.U. Newcalf gris F\/32 F1.5\/1.7mm, T1.5\/2.0m2)"},{"IdCustomFieldsValue":764,"Valore":"Pieces Metallique"},{"IdCustomFieldsValue":765,"Valore":"Bracelets de montres"},{"IdCustomFieldsValue":768,"Valore":"Leather vs Textile"},{"IdCustomFieldsValue":770,"Valore":"Cuoio\/Pelle (Coniglio)"},{"IdCustomFieldsValue":792,"Valore":"Leather (Goat) vs Leather (Calf)"},{"IdCustomFieldsValue":797,"Valore":"Insock"},{"IdCustomFieldsValue":809,"Valore":"Leather (Shoulder)"},{"IdCustomFieldsValue":810,"Valore":"Cuoio\/Pelle (Fianchi)"},{"IdCustomFieldsValue":812,"Valore":"Zaino"},{"IdCustomFieldsValue":824,"Valore":"Shoe"},{"IdCustomFieldsValue":834,"Valore":"Glittered Textile"},{"IdCustomFieldsValue":835,"Valore":"Cuoio\/Pelle (Alligatore)"},{"IdCustomFieldsValue":838,"Valore":"Pannello"},{"IdCustomFieldsValue":841,"Valore":"Bracelet"},{"IdCustomFieldsValue":842,"Valore":"Chain"},{"IdCustomFieldsValue":843,"Valore":"Necklace"},{"IdCustomFieldsValue":847,"Valore":"Componente per calzatura"},{"IdCustomFieldsValue":849,"Valore":"Bracciale"},{"IdCustomFieldsValue":852,"Valore":"Cuoio\/Pelle (Cavallo)"},{"IdCustomFieldsValue":854,"Valore":"Nappa"},{"IdCustomFieldsValue":856,"Valore":"Cuoio\/Pelle (Suino)"},{"IdCustomFieldsValue":857,"Valore":"Bag"},{"IdCustomFieldsValue":862,"Valore":"PVC"},{"IdCustomFieldsValue":865,"Valore":"Cuoio\/Pelle Esotico (Ayers)"},{"IdCustomFieldsValue":877,"Valore":"Cuir (Veau)"},{"IdCustomFieldsValue":884,"Valore":"Leather (Pig)"},{"IdCustomFieldsValue":886,"Valore":"Leather (Baby Calf)"},{"IdCustomFieldsValue":888,"Valore":"Small Leathergood (Belt)"},{"IdCustomFieldsValue":899,"Valore":"Accoppiato (Tessile\/Pelle)"},{"IdCustomFieldsValue":900,"Valore":"Accoppiato (Pelle\/Pelle)"},{"IdCustomFieldsValue":901,"Valore":"Cuoio\/Pelle (Pitone)"},{"IdCustomFieldsValue":911,"Valore":"Culatte"},{"IdCustomFieldsValue":919,"Valore":"Leather (Kangaroo)"},{"IdCustomFieldsValue":934,"Valore":"Accessorio"},{"IdCustomFieldsValue":937,"Valore":"Leather (Bovine)"},{"IdCustomFieldsValue":938,"Valore":"Leather (Coupled)"},{"IdCustomFieldsValue":943,"Valore":"Textile (Glittered)"},{"IdCustomFieldsValue":945,"Valore":"Textile (Woven\/Knitted)"},{"IdCustomFieldsValue":946,"Valore":"Textile (Lining)"},{"IdCustomFieldsValue":949,"Valore":"Cuoio\/Pelle (Caribu')"},{"IdCustomFieldsValue":952,"Valore":"Tessile (Fodera)"},{"IdCustomFieldsValue":954,"Valore":"Metallic logo"},{"IdCustomFieldsValue":957,"Valore":"Plastic accessories"},{"IdCustomFieldsValue":961,"Valore":"Tessile (Paglia)"},{"IdCustomFieldsValue":962,"Valore":"Cuir (1\/2 Veau)"},{"IdCustomFieldsValue":965,"Valore":"Metallic \/ Plastic trims"},{"IdCustomFieldsValue":966,"Valore":"Prodotto chimico"},{"IdCustomFieldsValue":967,"Valore":"Cuoio\/Pelle (Culatta)"},{"IdCustomFieldsValue":974,"Valore":"I-Pad Holder"},{"IdCustomFieldsValue":979,"Valore":"Tessue"},{"IdCustomFieldsValue":984,"Valore":"Cuoio\/Pelle (Bovina)"},{"IdCustomFieldsValue":987,"Valore":"Footwear"},{"IdCustomFieldsValue":988,"Valore":"Textile (PVC)"},{"IdCustomFieldsValue":994,"Valore":"AYERS F.C. MAC."},{"IdCustomFieldsValue":995,"Valore":"Quadrante di borsa completo di maniglia"},{"IdCustomFieldsValue":1005,"Valore":"Leather (Baby calf with hair on printed)"},{"IdCustomFieldsValue":1007,"Valore":"Metallic Trims"},{"IdCustomFieldsValue":1012,"Valore":"Accessoire metallique"},{"IdCustomFieldsValue":1019,"Valore":"Fibbia"},{"IdCustomFieldsValue":1033,"Valore":"Component for Footwear"},{"IdCustomFieldsValue":1037,"Valore":"Cuoio\/Pelle (Capretto)"},{"IdCustomFieldsValue":1038,"Valore":"Leather (Crust)"},{"IdCustomFieldsValue":1040,"Valore":"Cuoio\/Pelle (Esotico)"},{"IdCustomFieldsValue":1045,"Valore":"Componente di pelletteria (tintura costola)"},{"IdCustomFieldsValue":1046,"Valore":"Tessile (Accoppiato con pelle)"},{"IdCustomFieldsValue":1049,"Valore":"Tessile (Accopiato con PU)"},{"IdCustomFieldsValue":1077,"Valore":"Sintetici"},{"IdCustomFieldsValue":1107,"Valore":"Textile (Synthetic)"},{"IdCustomFieldsValue":1126,"Valore":"Sughero"},{"IdCustomFieldsValue":1158,"Valore":"Accoppiato"},{"IdCustomFieldsValue":1159,"Valore":"Zip"},{"IdCustomFieldsValue":1178,"Valore":"Cellulosa"},{"IdCustomFieldsValue":1179,"Valore":"Pochette"},{"IdCustomFieldsValue":1218,"Valore":"Cuir (Chevre)"},{"IdCustomFieldsValue":1260,"Valore":"Watch strap"},{"IdCustomFieldsValue":1261,"Valore":"Lamina"},{"IdCustomFieldsValue":1356,"Valore":"Pietra verniciata"},{"IdCustomFieldsValue":1362,"Valore":"Cartone"},{"IdCustomFieldsValue":1369,"Valore":"Upper"},{"IdCustomFieldsValue":1373,"Valore":"Cuoio\/Pelle (Struzzo)"},{"IdCustomFieldsValue":1375,"Valore":"Prodotto liquido"},{"IdCustomFieldsValue":1376,"Valore":"Cuoio\/Pelle (Lapin Rex)"},{"IdCustomFieldsValue":1378,"Valore":"Wood Button"},{"IdCustomFieldsValue":1381,"Valore":"Lattice"},{"IdCustomFieldsValue":1419,"Valore":"Coupled"},{"IdCustomFieldsValue":1428,"Valore":"Tessile (Lana)"},{"IdCustomFieldsValue":1430,"Valore":"Tomaia"},{"IdCustomFieldsValue":1435,"Valore":"Tessile (PU)"},{"IdCustomFieldsValue":1446,"Valore":"Filo"},{"IdCustomFieldsValue":1447,"Valore":"Polvere"},{"IdCustomFieldsValue":1452,"Valore":"Leather (Sheep)"},{"IdCustomFieldsValue":1465,"Valore":"Textile (Printed)"},{"IdCustomFieldsValue":1487,"Valore":"Plastic sample"},{"IdCustomFieldsValue":1495,"Valore":"Pigmento"},{"IdCustomFieldsValue":1502,"Valore":"Shanks"},{"IdCustomFieldsValue":1506,"Valore":"Button (Urea)"},{"IdCustomFieldsValue":1521,"Valore":"Pietra"},{"IdCustomFieldsValue":1523,"Valore":"Fabric sample"},{"IdCustomFieldsValue":1525,"Valore":"Cuoio\/Pelle (Pesce)"},{"IdCustomFieldsValue":1526,"Valore":"Button (Sydney)"},{"IdCustomFieldsValue":1563,"Valore":"Metal Powder"},{"IdCustomFieldsValue":1569,"Valore":"Liquid product"},{"IdCustomFieldsValue":1582,"Valore":"Paint"},{"IdCustomFieldsValue":1588,"Valore":"Laminated paper"},{"IdCustomFieldsValue":1589,"Valore":"Accessoire"},{"IdCustomFieldsValue":1597,"Valore":"Lucido"},{"IdCustomFieldsValue":1623,"Valore":"Cuoio\/Pelle (Anguilla)"},{"IdCustomFieldsValue":1626,"Valore":"Tessile (Cotone)"},{"IdCustomFieldsValue":1663,"Valore":"ABS"},{"IdCustomFieldsValue":1664,"Valore":"Leather (Bos Taurus)"},{"IdCustomFieldsValue":1731,"Valore":"Leather (Ayers)"},{"IdCustomFieldsValue":1732,"Valore":"Leather (Colubro)"},{"IdCustomFieldsValue":1733,"Valore":"Leather (Python)"},{"IdCustomFieldsValue":1736,"Valore":"Heel with Insole"},{"IdCustomFieldsValue":1737,"Valore":"Cuoio\/Pelle (Lapin)"},{"IdCustomFieldsValue":1739,"Valore":"Cuoio\/Pelle (Caimano)"},{"IdCustomFieldsValue":1743,"Valore":"Cuir (Agneau)"},{"IdCustomFieldsValue":1760,"Valore":"Leather (Kid)"},{"IdCustomFieldsValue":1781,"Valore":"Packaging Box"},{"IdCustomFieldsValue":1782,"Valore":"Packaging Cloth"},{"IdCustomFieldsValue":1803,"Valore":"Textile (Coated)"},{"IdCustomFieldsValue":1811,"Valore":"Leather (Reclaimed) "},{"IdCustomFieldsValue":1882,"Valore":"Accoppiato (Tessile\/Tessile)"},{"IdCustomFieldsValue":1913,"Valore":"Lycra"},{"IdCustomFieldsValue":1930,"Valore":"Cuoio\/Pelle (Lucertola)"},{"IdCustomFieldsValue":1981,"Valore":"Leather (Baby Goat)"},{"IdCustomFieldsValue":1987,"Valore":"Cover"},{"IdCustomFieldsValue":2003,"Valore":"Tracolla"},{"IdCustomFieldsValue":2079,"Valore":"Leather (Bull)"},{"IdCustomFieldsValue":2080,"Valore":"Leather (Ovine)"},{"IdCustomFieldsValue":2176,"Valore":"Tessile (Poliestere)"},{"IdCustomFieldsValue":2184,"Valore":"Cuoio\/Pelle (Lama)"},{"IdCustomFieldsValue":2203,"Valore":"Accessorio in pelle"},{"IdCustomFieldsValue":2259,"Valore":"Leather (Eel)"},{"IdCustomFieldsValue":2273,"Valore":"Accoppiato (Accessorio\/Pelle)"},{"IdCustomFieldsValue":2274,"Valore":"Accoppiato (Accessorio\/Tessile)"},{"IdCustomFieldsValue":2276,"Valore":"Accessorio in tessuto"},{"IdCustomFieldsValue":2376,"Valore":"Cuoio rigenerato"},{"IdCustomFieldsValue":2460,"Valore":"Regenerated Leather"},{"IdCustomFieldsValue":2465,"Valore":"Resina acrilica"},{"IdCustomFieldsValue":2467,"Valore":"Bonded Leather"},{"IdCustomFieldsValue":2515,"Valore":"Tessile (Seta)"},{"IdCustomFieldsValue":2528,"Valore":"Cuoio"},{"IdCustomFieldsValue":2540,"Valore":"Paper packaging"},{"IdCustomFieldsValue":2541,"Valore":"Plastic packaging"},{"IdCustomFieldsValue":2576,"Valore":"Zip in Nylon"},{"IdCustomFieldsValue":2577,"Valore":"Nylon Zip"},{"IdCustomFieldsValue":2634,"Valore":"Footwear (Sandal)"},{"IdCustomFieldsValue":2644,"Valore":"Leather (Alligator)"},{"IdCustomFieldsValue":2716,"Valore":"Powder"},{"IdCustomFieldsValue":2770,"Valore":"Tissu"},{"IdCustomFieldsValue":2773,"Valore":"TBC"},{"IdCustomFieldsValue":2781,"Valore":"Leather (Nappa)"},{"IdCustomFieldsValue":3048,"Valore":"Leather (Bovine Split)"},{"IdCustomFieldsValue":3086,"Valore":"Valigia"},{"IdCustomFieldsValue":3087,"Valore":"Leather (Fox)"},{"IdCustomFieldsValue":3089,"Valore":"Cuoio\/Pelle (Mucca)"},{"IdCustomFieldsValue":3204,"Valore":"Tessile (Raso)"},{"IdCustomFieldsValue":3205,"Valore":"Ecopelle"},{"IdCustomFieldsValue":3212,"Valore":"Tessile (Termosaldatura)"},{"IdCustomFieldsValue":3215,"Valore":"Watch case"},{"IdCustomFieldsValue":3226,"Valore":"Shoulder strap"},{"IdCustomFieldsValue":3244,"Valore":"Tessile (Microfibra)"},{"IdCustomFieldsValue":3252,"Valore":"Spandex"},{"IdCustomFieldsValue":3259,"Valore":"Glue"},{"IdCustomFieldsValue":3264,"Valore":"EVA"},{"IdCustomFieldsValue":3284,"Valore":"Leather (Horse)"},{"IdCustomFieldsValue":3308,"Valore":"Soletto"},{"IdCustomFieldsValue":3312,"Valore":"Textile (PU)"},{"IdCustomFieldsValue":3316,"Valore":"Cufflinks"},{"IdCustomFieldsValue":3348,"Valore":"Synthetic Fur"},{"IdCustomFieldsValue":3355,"Valore":"Resina poliuretanica ad acqua"},{"IdCustomFieldsValue":3356,"Valore":"Resina siliconica"},{"IdCustomFieldsValue":3437,"Valore":"Leather (Whips)"},{"IdCustomFieldsValue":3438,"Valore":"Leather (Karung)"},{"IdCustomFieldsValue":3448,"Valore":"Swimming cap"},{"IdCustomFieldsValue":3458,"Valore":"Leather (Crocodile)"},{"IdCustomFieldsValue":3459,"Valore":"Leather (Crocodile Niloticus)"},{"IdCustomFieldsValue":3464,"Valore":"Leather (Cayman)"},{"IdCustomFieldsValue":3466,"Valore":"Leather (Ostrich)"},{"IdCustomFieldsValue":3471,"Valore":"Accessorio Metallico (Ottone)"},{"IdCustomFieldsValue":3486,"Valore":"Leather (Fish)"},{"IdCustomFieldsValue":3495,"Valore":"Textile (Woven)"},{"IdCustomFieldsValue":3510,"Valore":"Tessile (Ortogonale)"},{"IdCustomFieldsValue":3512,"Valore":"Lacquer"},{"IdCustomFieldsValue":3513,"Valore":"Textile (Cotton)"},{"IdCustomFieldsValue":3522,"Valore":"Cuoio\/Pelle (Coccodrillo Porosus)"},{"IdCustomFieldsValue":3737,"Valore":"Cuir (Alligator)"},{"IdCustomFieldsValue":3752,"Valore":"Canvas"},{"IdCustomFieldsValue":3834,"Valore":"Leather (Lizard)"},{"IdCustomFieldsValue":3844,"Valore":"LV"},{"IdCustomFieldsValue":3850,"Valore":"Textile (Synthetic & blend)"},{"IdCustomFieldsValue":3854,"Valore":"Pelliccia ecologica"},{"IdCustomFieldsValue":3856,"Valore":"Insole"},{"IdCustomFieldsValue":3861,"Valore":"Textile (Natural) + Prints\/Coating"},{"IdCustomFieldsValue":3875,"Valore":"Trolley"},{"IdCustomFieldsValue":3877,"Valore":"Rubber"},{"IdCustomFieldsValue":3878,"Valore":"Rubber + Plastic"},{"IdCustomFieldsValue":4032,"Valore":"Fake leather"},{"IdCustomFieldsValue":4097,"Valore":"Produit fini"},{"IdCustomFieldsValue":4121,"Valore":"Materiali adesivi in Nylon"},{"IdCustomFieldsValue":4138,"Valore":"Cuir (Porosus)"},{"IdCustomFieldsValue":4139,"Valore":"Cuir (Niloticus)"},{"IdCustomFieldsValue":4141,"Valore":"Gloves"},{"IdCustomFieldsValue":4146,"Valore":"Tessile (Rafia)"},{"IdCustomFieldsValue":4159,"Valore":"Raw material"},{"IdCustomFieldsValue":4165,"Valore":"Textile (Lace)"},{"IdCustomFieldsValue":4169,"Valore":"Tessile (Tulle)"},{"IdCustomFieldsValue":4188,"Valore":"Polycarbonate"},{"IdCustomFieldsValue":4190,"Valore":"Wax"},{"IdCustomFieldsValue":4202,"Valore":"Tessile (Rete)"},{"IdCustomFieldsValue":4203,"Valore":"Tessile (Neoprene)"},{"IdCustomFieldsValue":4232,"Valore":"Sludge"},{"IdCustomFieldsValue":4249,"Valore":"Feather"},{"IdCustomFieldsValue":4264,"Valore":"Legno"},{"IdCustomFieldsValue":4281,"Valore":"Textile (Nylon)"},{"IdCustomFieldsValue":4285,"Valore":"Textile (Knitted)"},{"IdCustomFieldsValue":4402,"Valore":"Cuoio\/Pelle (Porosus)"},{"IdCustomFieldsValue":4422,"Valore":"Tights"},{"IdCustomFieldsValue":4564,"Valore":"Sock"},{"IdCustomFieldsValue":4698,"Valore":"Wood"},{"IdCustomFieldsValue":4720,"Valore":"Cuoio\/Pelle (Ovinocaprino)"},{"IdCustomFieldsValue":5063,"Valore":"Synth\u00e9tique"},{"IdCustomFieldsValue":5089,"Valore":"Solid Product"},{"IdCustomFieldsValue":5106,"Valore":"Cuoio\/Pelle (Cocco)"},{"IdCustomFieldsValue":5314,"Valore":"Cuoio\/Pelle (\u00bd bovina)"},{"IdCustomFieldsValue":5372,"Valore":"Plastique accessoires"},{"IdCustomFieldsValue":5484,"Valore":"Hat"},{"IdCustomFieldsValue":5689,"Valore":"Produit liquide"},{"IdCustomFieldsValue":6528,"Valore":"Textile accessories"},{"IdCustomFieldsValue":8580,"Valore":"Poussi\u00e8re"},{"IdCustomFieldsValue":8778,"Valore":"Eco-Leather"},{"IdCustomFieldsValue":9269,"Valore":"Polietilene"},{"IdCustomFieldsValue":9602,"Valore":"Silk"},{"IdCustomFieldsValue":11227,"Valore":"Bois"},{"IdCustomFieldsValue":11228,"Valore":"Produit solide"},{"IdCustomFieldsValue":12432,"Valore":"Polyester"},{"IdCustomFieldsValue":12597,"Valore":"Mousse"},{"IdCustomFieldsValue":12612,"Valore":"Papier"},{"IdCustomFieldsValue":12689,"Valore":"Accessoires en plastique"},{"IdCustomFieldsValue":13244,"Valore":"Cuir (Autreches)"},{"IdCustomFieldsValue":13256,"Valore":"TPU"},{"IdCustomFieldsValue":13257,"Valore":"Gomma"},{"IdCustomFieldsValue":13726,"Valore":"Micro"},{"IdCustomFieldsValue":14025,"Valore":"Tessile (Nylon)"},{"IdCustomFieldsValue":14173,"Valore":"Poliuretano"},{"IdCustomFieldsValue":14238,"Valore":"Accessorio plastico"},{"IdCustomFieldsValue":14239,"Valore":"Plastica"},{"IdCustomFieldsValue":14633,"Valore":"Cuir (Bovin)"},{"IdCustomFieldsValue":14927,"Valore":"Cuoio\/Pelle (Varano)"},{"IdCustomFieldsValue":15048,"Valore":"Plexiglas"}],"163":[{"IdCustomFieldsValue":248,"Valore":"a cura del laboratorio secondo la UNI EN ISO 2418:2006 "},{"IdCustomFieldsValue":251,"Valore":"a cura del committente "},{"IdCustomFieldsValue":278,"Valore":"done by the laboratory according to the UNI EN ISO 2418:2006 "},{"IdCustomFieldsValue":281,"Valore":"done by the client "},{"IdCustomFieldsValue":649,"Valore":"the specimen has been sampled from the footwear supplied by the client"},{"IdCustomFieldsValue":677,"Valore":"materiale campionato da borsa fornita dal cliente"},{"IdCustomFieldsValue":727,"Valore":"the specimen has been sampled from the bag supplied by the client"},{"IdCustomFieldsValue":755,"Valore":"par le client"},{"IdCustomFieldsValue":878,"Valore":"effectu\u00e9e par le laboratoire selon la norme UNI EN ISO 2418:2006"},{"IdCustomFieldsValue":1029,"Valore":"the specimen has been sampled from the wallet supplied by the client"},{"IdCustomFieldsValue":1627,"Valore":"materiale campionato da calzatura fornita dal cliente"},{"IdCustomFieldsValue":1628,"Valore":"materiale campionato da portafogli fornito dal cliente"},{"IdCustomFieldsValue":4716,"Valore":"Grab, sampled by the Lab"},{"IdCustomFieldsValue":5355,"Valore":"Material sampled by the Lab."},{"IdCustomFieldsValue":9142,"Valore":"materiale campionato da cappello fornito dal cliente"}],"165":[{"IdCustomFieldsValue":825,"Valore":"Nessuno, come da accordi con il cliente"},{"IdCustomFieldsValue":826,"Valore":"None, as agreed with the client"},{"IdCustomFieldsValue":1632,"Valore":"Aucun, selon accords avec le client"},{"IdCustomFieldsValue":2088,"Valore":"24\u00b12h; 21\u00b11\u00b0C; 65\u00b12%U.R. (Se richiesto dal Metodo di Prova, analisi eseguita in atmosfera standard)"},{"IdCustomFieldsValue":2089,"Valore":"24\u00b12h; 21\u00b11\u00b0C; 65\u00b12% R.H. (If required by the test method, analysis carried out in standard atmosphere)"},{"IdCustomFieldsValue":2450,"Valore":"(According to UNI EN ISO 2419:2012) 23\u00b0+\/-2\u00b0C; 50+\/-5% R.H. (If required by the test method, trial carried out in standard atmosphere)"},{"IdCustomFieldsValue":2552,"Valore":"Atmosfera di condizionamento e di prova: 20\u00b12\u00b0, 65\u00b15% UR"},{"IdCustomFieldsValue":3187,"Valore":"Il campione \u00e8 conservato a temperatura <4\u00b0C"},{"IdCustomFieldsValue":3188,"Valore":"the sample is stored at temperature <4\u00b0C"},{"IdCustomFieldsValue":6133,"Valore":"24\u00b12h; 21\u00b11\u00b0C; 65\u00b12%U.R. (Si prevu par le m\u00e9thode du test, analyse execut\u00e9e en atmosph\u00e8re standardis\u00e9e)"},{"IdCustomFieldsValue":15005,"Valore":"24\u00b12h; 23\u00b12\u00b0C; 50\u00b15%U.R. (Se richiesto dal Metodo di Prova, analisi eseguita in atmosfera standard)"},{"IdCustomFieldsValue":15006,"Valore":"24\u00b12h; 23\u00b12\u00b0C; 50\u00b15% R.H. (If required by the test method, analysis carried out in standard atmosphere)"},{"IdCustomFieldsValue":15007,"Valore":"24\u00b12h; 23\u00b12\u00b0C; 50\u00b15%U.R. (Si prevu par le m\u00e9thode du test, analyse execut\u00e9e en atmosph\u00e8re standardis\u00e9e)"}],"169":[{"IdCustomFieldsValue":672,"Valore":"Si"},{"IdCustomFieldsValue":673,"Valore":"No"},{"IdCustomFieldsValue":778,"Valore":"Si se FAIL"},{"IdCustomFieldsValue":4408,"Valore":"Procedura Standard"}],"170":[{"IdCustomFieldsValue":674,"Valore":"No"},{"IdCustomFieldsValue":675,"Valore":"Si"},{"IdCustomFieldsValue":777,"Valore":"Si se FAIL"},{"IdCustomFieldsValue":4409,"Valore":"Procedura Standard"}],"171":[{"IdCustomFieldsValue":668,"Valore":"Si"},{"IdCustomFieldsValue":669,"Valore":"No"},{"IdCustomFieldsValue":670,"Valore":"Si se FAIL"},{"IdCustomFieldsValue":671,"Valore":"Si FINE MESE"},{"IdCustomFieldsValue":1013,"Valore":"SI OGNI GIOVED\u00ec"},{"IdCustomFieldsValue":1185,"Valore":"SI due volte alla settimana"},{"IdCustomFieldsValue":2216,"Valore":"SI una volta alla settimana"},{"IdCustomFieldsValue":4410,"Valore":"Procedura Standard"},{"IdCustomFieldsValue":5722,"Valore":"SI stesso giorno"}],"181":[{"IdCustomFieldsValue":744,"Valore":"Il campione \u00e8 preparato secondo la ISO 4044 (quando richiesto dal metodo di prova)."},{"IdCustomFieldsValue":745,"Valore":"Sample is prepared according to ISO 4044 (whenever requested by the test method)"},{"IdCustomFieldsValue":753,"Valore":"L\u2019\u00e9chantillon est pr\u00e9par\u00e9 conform\u00e9ment \u00e0 la norme ISO 4044 (lorsque cela est requis par la m\u00e9thode d\u2019essai)."}],"236":[{"IdCustomFieldsValue":1468,"Valore":"Consegnato a mano"},{"IdCustomFieldsValue":1469,"Valore":"Inviato tramite corriere"},{"IdCustomFieldsValue":4945,"Valore":"Navetta Scandicci"}],"241":[{"IdCustomFieldsValue":1603,"Valore":"a Pacchetto"},{"IdCustomFieldsValue":1604,"Valore":">3"},{"IdCustomFieldsValue":1605,"Valore":"<=3"}],"246":[{"IdCustomFieldsValue":1753,"Valore":"BV Shangai"},{"IdCustomFieldsValue":1755,"Valore":"BV Hamburg- Eva Maria Benkhoff"},{"IdCustomFieldsValue":1756,"Valore":"BV Turkey"},{"IdCustomFieldsValue":1757,"Valore":"BV UK"},{"IdCustomFieldsValue":1937,"Valore":"BV Vietnam"},{"IdCustomFieldsValue":1938,"Valore":"BV Schwerin"},{"IdCustomFieldsValue":1939,"Valore":"BV Guangzhou"},{"IdCustomFieldsValue":1940,"Valore":"BV France"},{"IdCustomFieldsValue":1941,"Valore":"No outsourcing"},{"IdCustomFieldsValue":1944,"Valore":"Coventya"},{"IdCustomFieldsValue":1945,"Valore":"Cimac- P.Biglia"},{"IdCustomFieldsValue":2290,"Valore":"Ricotest"},{"IdCustomFieldsValue":2403,"Valore":"LBS"},{"IdCustomFieldsValue":2696,"Valore":"BV Korea"},{"IdCustomFieldsValue":2998,"Valore":"BV Hong Kong"},{"IdCustomFieldsValue":3058,"Valore":"J.S. Hamilton Poland S.A."},{"IdCustomFieldsValue":3191,"Valore":"BV Schwerin - BV Turkey"},{"IdCustomFieldsValue":3341,"Valore":"BV Guangzhou, BV Shangai"},{"IdCustomFieldsValue":3350,"Valore":"BV Guangzhou, BV Honk Kong"},{"IdCustomFieldsValue":3406,"Valore":"BV Putian - Lily Li"},{"IdCustomFieldsValue":4239,"Valore":"BV India"},{"IdCustomFieldsValue":4282,"Valore":"Laboraitore Eric Beucher"},{"IdCustomFieldsValue":4420,"Valore":"HerAmbiente "},{"IdCustomFieldsValue":4679,"Valore":"Chemi-Lab"},{"IdCustomFieldsValue":5745,"Valore":"BV USA, Buffalo - NY "},{"IdCustomFieldsValue":6450,"Valore":"BV Turkey- Ahmet Korkut + BV Hong Kong- Jimmy Wong\/Tasman Tai\r\n"},{"IdCustomFieldsValue":8098,"Valore":"BV Vietnam- Joy Nguyen + BV Turkey- Ahmet Korkut"},{"IdCustomFieldsValue":8755,"Valore":"Appliance Engineering Technology France SAS"},{"IdCustomFieldsValue":9316,"Valore":"BV Vietnam- Joy Nguyen + BV Guangzhou"},{"IdCustomFieldsValue":9483,"Valore":"Neosis s.r.l"},{"IdCustomFieldsValue":9645,"Valore":"Environ Lab"},{"IdCustomFieldsValue":11325,"Valore":"Neosis s.r.l + BV Honk Kong"},{"IdCustomFieldsValue":11342,"Valore":"Beta analythics"},{"IdCustomFieldsValue":12678,"Valore":"BV Honk Kong + BV Shangai"},{"IdCustomFieldsValue":13717,"Valore":"BV Thailand"},{"IdCustomFieldsValue":13917,"Valore":"BV France, BV Shangai"},{"IdCustomFieldsValue":14877,"Valore":"BV Shangai - BV Hong Kong"}],"252":[{"IdCustomFieldsValue":1887,"Valore":"Regular"},{"IdCustomFieldsValue":1888,"Valore":"Express (1-2 Working Days)"},{"IdCustomFieldsValue":1889,"Valore":"Urgent (3 Working Days)"}],"253":[{"IdCustomFieldsValue":1891,"Valore":"Yes"},{"IdCustomFieldsValue":1892,"Valore":"No"}],"261":[{"IdCustomFieldsValue":1978,"Valore":"2C Cina"},{"IdCustomFieldsValue":2442,"Valore":"N\/A"}],"771":[{"IdCustomFieldsValue":8595,"Valore":"PASS"},{"IdCustomFieldsValue":8596,"Valore":"FAIL"},{"IdCustomFieldsValue":8598,"Valore":"N\/A"}],"772":[{"IdCustomFieldsValue":8599,"Valore":"PASS"},{"IdCustomFieldsValue":8600,"Valore":"FAIL"},{"IdCustomFieldsValue":8601,"Valore":"N\/A"}],"773":[{"IdCustomFieldsValue":8602,"Valore":"PASS"},{"IdCustomFieldsValue":8603,"Valore":"FAIL"},{"IdCustomFieldsValue":8604,"Valore":"N\/A"},{"IdCustomFieldsValue":8605,"Valore":"DATA"}],"1083":[{"IdCustomFieldsValue":13482,"Valore":"Moncler Compliance_GT"},{"IdCustomFieldsValue":13488,"Valore":"Moncler Ufficio tecnico_MC"},{"IdCustomFieldsValue":13495,"Valore":"Moncler Compliance_EM"},{"IdCustomFieldsValue":13496,"Valore":"Moncler Compliance_MB"},{"IdCustomFieldsValue":13497,"Valore":"Moncler Compliance_CB"},{"IdCustomFieldsValue":13526,"Valore":"Moncler Compliance_CS"},{"IdCustomFieldsValue":13530,"Valore":"Moncler Compliance_FZ"},{"IdCustomFieldsValue":13554,"Valore":"Moncler Ufficio tecnico_AZ"},{"IdCustomFieldsValue":13662,"Valore":"Moncler Ufficio tecnico_LL"},{"IdCustomFieldsValue":13727,"Valore":"Moncler Ufficio tecnico_AU"},{"IdCustomFieldsValue":13945,"Valore":"Moncler Compliance_BZ"},{"IdCustomFieldsValue":14006,"Valore":"Moncler Compliance_GR"},{"IdCustomFieldsValue":14818,"Valore":"Moncler Ufficio tecnico_LC"},{"IdCustomFieldsValue":14910,"Valore":"Moncler Ufficio tecnico_FV"}]} \ No newline at end of file diff --git a/public/userarea/delete_part.php b/public/userarea/delete_part.php deleted file mode 100644 index fc5309a..0000000 --- a/public/userarea/delete_part.php +++ /dev/null @@ -1,29 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents('php://input'), true); - -$partId = $data['part_id'] ?? null; - -if (!$partId) { - echo json_encode(['success' => false, 'message' => 'ID parte mancante']); - exit; -} - -try { - $stmt = $pdo->prepare("DELETE FROM identification_parts WHERE id = :part_id"); - $stmt->execute([':part_id' => $partId]); - $rowCount = $stmt->rowCount(); - if ($rowCount > 0) { - echo json_encode(['success' => true, 'message' => 'Parte eliminata con successo']); - } else { - echo json_encode(['success' => false, 'message' => 'Nessuna parte trovata con ID ' . $partId]); - } -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nell\'eliminazione: ' . $e->getMessage()]); -} diff --git a/public/userarea/delete_part_quotation.php b/public/userarea/delete_part_quotation.php deleted file mode 100644 index ace1700..0000000 --- a/public/userarea/delete_part_quotation.php +++ /dev/null @@ -1,28 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents('php://input'), true); - -$partId = $data['part_id'] ?? null; - -if (!$partId) { - echo json_encode(['success' => false, 'message' => 'ID parte mancante']); - exit; -} - -try { - $stmt = $pdo->prepare("DELETE FROM identification_parts WHERE id = :part_id"); - $stmt->execute([':part_id' => $partId]); - $rowCount = $stmt->rowCount(); - if ($rowCount > 0) { - echo json_encode(['success' => true, 'message' => 'Parte eliminata con successo']); - } else { - echo json_encode(['success' => false, 'message' => 'Nessuna parte trovata con ID ' . $partId]); - } -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nell\'eliminazione: ' . $e->getMessage()]); -} diff --git a/public/userarea/delete_photo.php b/public/userarea/delete_photo.php deleted file mode 100644 index 8e96d30..0000000 --- a/public/userarea/delete_photo.php +++ /dev/null @@ -1,37 +0,0 @@ - false, 'message' => 'Richiesta non valida']); - exit; -} - -$photoId = intval($_POST['photo_id']); - -$db = DBHandlerSelect::getInstance(); -$pdo = $db->getConnection(); - -// Recupera il percorso del file -$stmt = $pdo->prepare("SELECT file_path FROM datadb_photos WHERE id = ?"); -$stmt->execute([$photoId]); -$photo = $stmt->fetch(PDO::FETCH_ASSOC); - -if (!$photo) { - echo json_encode(['success' => false, 'message' => 'Foto non trovata']); - exit; -} - -// Elimina il file dal server -$filePath = '../photostrf/' . $photo['file_path']; -if (file_exists($filePath)) { - unlink($filePath); -} - -// Elimina il record dal database -$stmt = $pdo->prepare("DELETE FROM datadb_photos WHERE id = ?"); -$stmt->execute([$photoId]); - -echo json_encode(['success' => true, 'message' => 'Foto eliminata con successo']); diff --git a/public/userarea/delete_record.php b/public/userarea/delete_record.php deleted file mode 100644 index 87f0b9c..0000000 --- a/public/userarea/delete_record.php +++ /dev/null @@ -1,64 +0,0 @@ - false, 'message' => 'ID non valido']); - exit; -} - -// Connessione al database -try { - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); -} catch (Exception $e) { - http_response_code(500); - echo json_encode(['success' => false, 'message' => 'Errore di connessione al database: ' . $e->getMessage()]); - error_log("Errore di connessione al database: " . $e->getMessage()); - exit; -} - -// Inizia una transazione -$pdo->beginTransaction(); - -try { - // Elimina i dettagli associati dal tavolo import_data_details - $stmt = $pdo->prepare("DELETE FROM import_data_details WHERE id = ?"); - $stmt->execute([$iddatadb]); - - // Elimina il record principale dal tavolo datadb - $stmt = $pdo->prepare("DELETE FROM datadb WHERE iddatadb = ?"); - $stmt->execute([$iddatadb]); - - // Verifica se il record è stato eliminato - if ($stmt->rowCount() > 0) { - $pdo->commit(); - echo json_encode(['success' => true, 'message' => 'Record eliminato con successo']); - error_log("Record con iddatadb=$iddatadb eliminato con successo"); - } else { - $pdo->rollBack(); - http_response_code(404); - echo json_encode(['success' => false, 'message' => 'Record non trovato']); - error_log("Record con iddatadb=$iddatadb non trovato"); - } -} catch (Exception $e) { - $pdo->rollBack(); - http_response_code(500); - echo json_encode(['success' => false, 'message' => 'Errore durante la cancellazione: ' . $e->getMessage()]); - error_log("Errore durante la cancellazione del record con iddatadb=$iddatadb: " . $e->getMessage()); -} diff --git a/public/userarea/delete_template_xls.php b/public/userarea/delete_template_xls.php deleted file mode 100644 index 13cbe68..0000000 --- a/public/userarea/delete_template_xls.php +++ /dev/null @@ -1,49 +0,0 @@ -getConnection(); - - if (!$pdo) { - throw new Exception('Database connection failed'); - } - - // Verifica se l'ID esiste - $stmtCheck = $pdo->prepare("SELECT id FROM excel_templates WHERE id = ?"); - $stmtCheck->execute([$id]); - if ($stmtCheck->rowCount() === 0) { - throw new Exception('Template not found'); - } - - // Esegui l'eliminazione - $stmt = $pdo->prepare("DELETE FROM excel_templates WHERE id = ?"); - $stmt->execute([$id]); - - if ($stmt->rowCount() > 0) { - $message = "Template deleted successfully!"; - $status = "success"; - } else { - throw new Exception('Failed to delete template'); - } -} catch (Exception $e) { - $message = $e->getMessage(); - $status = "error"; -} - -// Reindirizza con un messaggio -header("Location: templates_dashboard.php?status=$status&message=" . urlencode($message)); -exit; diff --git a/public/userarea/edit_template_xls.php b/public/userarea/edit_template_xls.php deleted file mode 100644 index c3dd001..0000000 --- a/public/userarea/edit_template_xls.php +++ /dev/null @@ -1,434 +0,0 @@ -getConnection(); -$stmt = $pdo->prepare("SELECT * FROM excel_templates WHERE id = ?"); -$stmt->execute([$id]); -$template = $stmt->fetch(PDO::FETCH_ASSOC); - -if (!$template) { - header("Location: template_dashboard.php?status=error&message=" . urlencode("Template not found")); - exit; -} - -// Recupera tutte le routine dal database -$stmt = $pdo->prepare("SELECT * FROM routine"); -$stmt->execute(); -$routines = $stmt->fetchAll(PDO::FETCH_ASSOC); -?> - - - - - - - - - - - - - Edit Template <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - -
    - - -
    -
    -
    -
    -
    Update XLS Template
    -
    -
    -

    Edit the following form in order to update the selected import XLS template

    -

    Mandatory Fields

    -
      -
    • Template Name
    • -
    • Row Header and Column Header: where the title of the excel starts
    • -
    • Schema
    • -
    -
    -
    - -
    -
    -
    -
    -
    Edit Template:
    -
    -
    -
    -
    -
    -
    - - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - - -
    - -
    - - - -
    - -
    - - - -
    - -
    - - Cancel -
    -
    -
    -
    -
    -
    -
    - - -
    - - - - - \ No newline at end of file diff --git a/public/userarea/export_to_lims.js b/public/userarea/export_to_lims.js deleted file mode 100644 index 74e2be2..0000000 --- a/public/userarea/export_to_lims.js +++ /dev/null @@ -1,239 +0,0 @@ -document.addEventListener("DOMContentLoaded", () => { - console.log("export_to_lims.js loaded"); - - // Debug: verifica che i pulsanti siano trovati - const exportButtons = document.querySelectorAll(".export-lims-btn"); - console.log(`Found ${exportButtons.length} export-lims-btn buttons`); - - if (exportButtons.length === 0) { - console.warn("No .export-lims-btn buttons found in the DOM"); - return; - } - - exportButtons.forEach((btn) => { - btn.addEventListener("click", (e) => { - e.preventDefault(); - const rowIndex = btn.dataset.row; - const iddatadb = btn.dataset.iddatadb; - console.log( - `Export to LIMS clicked for row ${rowIndex}, iddatadb: ${iddatadb}`, - ); - - // Mostra il modale di conferma - const confirmModalElement = - document.getElementById("exportConfirmModal"); - if (!confirmModalElement) { - console.error("exportConfirmModal not found in the DOM"); - alert("Errore: Modale di conferma non trovato"); - return; - } - - const confirmModal = new bootstrap.Modal(confirmModalElement, { - keyboard: false, - }); - document.getElementById("exportIddatadb").textContent = iddatadb; - confirmModal.show(); - - // Gestisci il click su "Conferma" - const confirmBtn = document.getElementById("exportConfirmBtn"); - if (!confirmBtn) { - console.error("exportConfirmBtn not found in the DOM"); - confirmModal.hide(); - alert("Errore: Pulsante di conferma non trovato"); - return; - } - - const confirmHandler = async () => { - console.log(`Confirmed export for iddatadb: ${iddatadb}`); - confirmModal.hide(); - - const formData = new FormData(); - formData.append("iddatadb", iddatadb); - - try { - const response = await fetch("export_to_lims.php", { - method: "POST", - body: formData, - }); - if (!response.ok) - throw new Error( - `HTTP error! status: ${response.status}`, - ); - const data = await response.json(); - - console.log("Export response:", data); - - // Mostra il modale di risposta - const responseModalElement = document.getElementById( - "exportResponseModal", - ); - if (!responseModalElement) { - console.error( - "exportResponseModal not found in the DOM", - ); - alert("Errore: Modale di risposta non trovato"); - return; - } - - const responseModal = new bootstrap.Modal( - responseModalElement, - { - keyboard: false, - }, - ); - const responseMessage = document.getElementById( - "exportResponseMessage", - ); - if (data.success) { - responseMessage.innerHTML = `${data.message.replace(/\n/g, "
    ")}
    ID CommessaWeb: ${data.idcommessaweb}`; - document.getElementById( - "exportResponseModalLabel", - ).textContent = "Esportazione Completata"; - responseModal.show(); - - // Aggiorna la UI per riflettere lo stato 'To LIMS' - const statusCell = btn - .closest(".grid-row") - .querySelector( - '.grid-cell[data-col="status"] .status-badge', - ); - if (statusCell) { - statusCell.classList.remove("status-i", "status-P"); - statusCell.classList.add("status-l"); - statusCell.textContent = "To LIMS"; - } - - // Gestisci la chiusura del modale di risposta - responseModalElement.addEventListener( - "hidden.bs.modal", - () => { - console.log( - "exportResponseModal closed, cleaning up", - ); - // Rimuovi tutti i backdrop residui - document - .querySelectorAll(".modal-backdrop") - .forEach((backdrop) => { - console.log( - "Removing backdrop:", - backdrop, - ); - backdrop.remove(); - }); - // Ripristina il body - document.body.classList.remove("modal-open"); - document.body.style.paddingRight = ""; - // Nascondi l'overlay - const overlay = document.querySelector( - ".overlay.toggle-icon", - ); - if (overlay) { - overlay.style.display = "none"; - } - }, - { once: true }, - ); - } else { - responseMessage.textContent = `Errore durante la generazione dei payload: ${data.message}`; - document.getElementById( - "exportResponseModalLabel", - ).textContent = "Errore Esportazione"; - responseModal.show(); - - // Gestisci la chiusura del modale di risposta anche in caso di errore - responseModalElement.addEventListener( - "hidden.bs.modal", - () => { - console.log( - "exportResponseModal closed, cleaning up", - ); - // Rimuovi tutti i backdrop residui - document - .querySelectorAll(".modal-backdrop") - .forEach((backdrop) => { - console.log( - "Removing backdrop:", - backdrop, - ); - backdrop.remove(); - }); - // Ripristina il body - document.body.classList.remove("modal-open"); - document.body.style.paddingRight = ""; - // Nascondi l'overlay - const overlay = document.querySelector( - ".overlay.toggle-icon", - ); - if (overlay) { - overlay.style.display = "none"; - } - }, - { once: true }, - ); - } - } catch (error) { - console.error("Export error:", error); - const responseModalElement = document.getElementById( - "exportResponseModal", - ); - if (!responseModalElement) { - console.error( - "exportResponseModal not found in the DOM", - ); - alert("Errore: Modale di risposta non trovato"); - return; - } - const responseModal = new bootstrap.Modal( - responseModalElement, - { - keyboard: false, - }, - ); - document.getElementById( - "exportResponseMessage", - ).textContent = - `Errore durante la generazione dei payload: ${error.message}`; - document.getElementById( - "exportResponseModalLabel", - ).textContent = "Errore Esportazione"; - responseModal.show(); - - // Gestisci la chiusura del modale di risposta in caso di errore - responseModalElement.addEventListener( - "hidden.bs.modal", - () => { - console.log( - "exportResponseModal closed, cleaning up", - ); - // Rimuovi tutti i backdrop residui - document - .querySelectorAll(".modal-backdrop") - .forEach((backdrop) => { - console.log("Removing backdrop:", backdrop); - backdrop.remove(); - }); - // Ripristina il body - document.body.classList.remove("modal-open"); - document.body.style.paddingRight = ""; - // Nascondi l'overlay - const overlay = document.querySelector( - ".overlay.toggle-icon", - ); - if (overlay) { - overlay.style.display = "none"; - } - }, - { once: true }, - ); - } - - // Rimuovi il listener dopo l'esecuzione - confirmBtn.removeEventListener("click", confirmHandler); - }; - - // Rimuovi eventuali listener precedenti - confirmBtn.removeEventListener("click", confirmHandler); - confirmBtn.addEventListener("click", confirmHandler); - }); - }); -}); diff --git a/public/userarea/export_to_lims.php b/public/userarea/export_to_lims.php deleted file mode 100644 index e7f8dfa..0000000 --- a/public/userarea/export_to_lims.php +++ /dev/null @@ -1,291 +0,0 @@ -getConnection(); - -header("Content-Type: application/json"); - -// 🔹 Configura directory log (creala se non esiste) -$logDir = __DIR__ . '/logs/api/'; -if (!is_dir($logDir)) { - mkdir($logDir, 0755, true); -} - -// 🔹 Base URL API -$apiBaseUrl = 'https://93.43.5.102/limsapi/api/odata/'; - -// 🔹 Funzione per validare e convertire date -function validateDate($value) -{ - // Prova a validare come data (accetta formati comuni) - $date = DateTime::createFromFormat('Y-m-d', $value) ?: DateTime::createFromFormat('Y-m-d H:i:s', $value); - if ($date) { - return $date->format('Y-m-d\TH:i:sP'); // Formato ISO 8601 - } - return null; // Imposta null se non è una data valida -} - -try { - $iddatadb = $_POST['iddatadb'] ?? null; - if (!$iddatadb) { - throw new Exception("Missing iddatadb"); - } - - // 🔹 STEP 1+2: Fetch Cliente ID from datadb and Schema ID from excel_templates - $stmt = $pdo->prepare(" - SELECT d.idclient AS clienteId, et.idschema AS schemaId - FROM datadb as d - INNER JOIN excel_templates as et ON d.templateid = et.id - WHERE d.iddatadb = :iddatadb - LIMIT 1 -"); - $stmt->execute(['iddatadb' => $iddatadb]); - $result = $stmt->fetch(PDO::FETCH_ASSOC); - - if (!$result) { - throw new Exception("No Cliente/Schema found for iddatadb {$iddatadb}"); - } - - $clienteId = (int) $result['clienteId']; - $schemaId = (int) $result['schemaId']; - - // 🔹 STEP 3: Fetch Parts (including idmatrice) - $stmt = $pdo->prepare(" - SELECT part_number, part_description, material, color, mix, idmatrice - FROM identification_parts - WHERE iddatadb = :iddatadb - "); - $stmt->execute(['iddatadb' => $iddatadb]); - $parts = $stmt->fetchAll(PDO::FETCH_ASSOC); - - // 🔹 STEP 4: Fetch Field Values with Labels - $stmt = $pdo->prepare(" - SELECT - idd.field_value, - m.field_label, - m.schema_id, - m.field_id - FROM - import_data_details as idd - JOIN template_mapping m ON idd.mapping_id = m.id - WHERE idd.id = :iddatadb - "); - $stmt->execute(['iddatadb' => $iddatadb]); - $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); - - $fieldValues = []; - $valueMap = []; - foreach ($rows as $row) { - $fieldValues[] = [ - "IdCommesseCustomFields" => (int) $row['field_id'], - "Valore" => $row['field_value'], - "FieldLabel" => $row['field_label'] - ]; - $valueMap[(int) $row['field_id']] = $row['field_value']; - } - - // Logga i fieldValues in error_log - $logFieldValues = "FieldValues dal DB (iddatadb={$iddatadb}):\n" . json_encode($fieldValues, JSON_PRETTY_PRINT); - error_log($logFieldValues); - - // 🔹 Initialize API client - $api = VisualLimsApiClient::getInstance(); - - // 🔹 STEP 5: Create CommessaWeb (NOT WebOrder) - $commessaWebPayload = [ - "Cliente" => $clienteId, - "SchemaCustomField" => $schemaId, - "Richiedente" => "Test Web Import", - "Descrizione" => "TEST CommessaWeb", - ]; - - // Costruisci log curl-like per STEP 5 - $jsonPayload = json_encode($commessaWebPayload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - $logContentStep5 = "curl --location --request POST '{$apiBaseUrl}CommessaWeb' \\\n" . - "--header 'Content-Type: application/json' \\\n" . - "--header 'Authorization: Bearer ••••••' \\\n" . - "--data '{$jsonPayload}'"; - - $commessaWeb = $api->post("CommessaWeb", $commessaWebPayload); - - $logContentStep5 .= "\n\nRESPONSE:\n" . json_encode($commessaWeb, JSON_PRETTY_PRINT); - - // Salva log - $logFileStep5 = $logDir . "commessa_create_step5_" . $iddatadb . "_" . time() . ".txt"; - file_put_contents($logFileStep5, $logContentStep5); - - $commessaId = $commessaWeb["IdCommessa"]; - $commessaWebCode = substr($commessaWeb["CodiceCommessa"] ?? "TEST CommessaWeb", 0, 30); // Limite a 30 caratteri - - // 🔹 STEP 6: Create Campioni (Samples) for each part - $campioni = []; - $logContentStep6 = ""; - - foreach ($parts as $index => $part) { - $matriceId = (int) ($part["idmatrice"] ?? 0); - - if ($matriceId <= 0) { - throw new Exception("Invalid or missing idmatrice for part: " . ($part["part_number"] ?? "Unknown")); - } - - $campionePayload = [ - "Commessa" => $commessaId, - "Matrice" => $matriceId, - "SottoMatrice" => null, - "SchemaCustomField" => $schemaId, - "NoteWeb" => $part["part_description"] ?? "" - ]; - - // Costruisci curl-like per questo campione - $jsonPayload = json_encode($campionePayload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - $logContentStep6 .= "CAMPIONE #{$index}\n" . - "curl --location --request POST '{$apiBaseUrl}Campione' \\\n" . - "--header 'Content-Type: application/json' \\\n" . - "--header 'Authorization: Bearer ••••••' \\\n" . - "--data '{$jsonPayload}'\n\n"; - - $campione = $api->post("Campione", $campionePayload); - - $logContentStep6 .= "RESPONSE:\n" . json_encode($campione, JSON_PRETTY_PRINT) . "\n\n---\n"; - - $campione["PartNumber"] = $part["part_number"] ?? ""; - $campione["Material"] = $part["material"] ?? ""; - $campione["Color"] = $part["color"] ?? ""; - $campione["Mix"] = $part["mix"] ?? ""; - - $campioni[] = $campione; - } - - // Salva log per STEP 6 - $logFileStep6 = $logDir . "commessa_{$commessaId}_campioni_step6_" . time() . ".txt"; - file_put_contents($logFileStep6, $logContentStep6); - - // 🔹 STEP 7: Update Custom Fields for CommessaWeb - if (!empty($fieldValues)) { - // GET con espansione per CustomField - $expand = "CommesseCustomFields(\$expand=CustomField)"; - $commessaWithFields = $api->get("CommessaWeb(" . $commessaId . ")?\$expand=" . $expand); - - // Logga il GET - $logContentGet = "curl --location --request GET '{$apiBaseUrl}CommessaWeb({$commessaId})?\$expand=CommesseCustomFields(\$expand=CustomField)' \\\n" . - "--header 'Authorization: Bearer ••••••'\n\n" . - "RESPONSE:\n" . json_encode($commessaWithFields, JSON_PRETTY_PRINT); - $logFileGet = $logDir . "commessa_{$commessaId}_get_step7_" . time() . ".txt"; - file_put_contents($logFileGet, $logContentGet); - - // Prepara payload PATCH - $commessaCustomFields = []; - foreach ($commessaWithFields["CommesseCustomFields"] as $customField) { - $definitionId = (int) ($customField["CustomField"]["IdCustomField"] ?? 0); - $fieldId = (int) $customField["IdCommesseCustomFields"]; - $currentValue = $customField["Valore"] ?? ''; - $fieldType = $customField["CustomField"]["Tipo"] ?? ''; - $newValue = isset($valueMap[$definitionId]) ? $valueMap[$definitionId] : $currentValue; - - // Valida se il campo è di tipo Data - if ($fieldType === 'Data' && $newValue !== $currentValue) { - $newValue = validateDate($newValue); - } - - $commessaCustomFields[] = [ - "IdCommesseCustomFields" => $fieldId, - "Valore" => $newValue - ]; - } - - if (!empty($commessaCustomFields)) { - $updatePayload = ["CommesseCustomFields" => $commessaCustomFields]; - - // Logga payload e response - $jsonPayload = json_encode($updatePayload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - $logContentStep7 = "curl --location --request PATCH '{$apiBaseUrl}CommessaWeb({$commessaId})' \\\n" . - "--header 'Content-Type: application/json' \\\n" . - "--header 'Authorization: Bearer ••••••' \\\n" . - "--data '{$jsonPayload}'"; - - $patchResponse = $api->patch("CommessaWeb({$commessaId})", $updatePayload); - - $logContentStep7 .= "\n\nRESPONSE:\n" . json_encode($patchResponse, JSON_PRETTY_PRINT); - $logFileStep7 = $logDir . "commessa_{$commessaId}_update_step7_" . time() . ".txt"; - file_put_contents($logFileStep7, $logContentStep7); - } - } - - // 🔹 STEP 8: Update datadb with idcommessaweb, commessaweb, and status - $stmt = $pdo->prepare(" - UPDATE datadb - SET idcommessaweb = :idcommessaweb, commessaweb = :commessaweb, status = 'l' - WHERE iddatadb = :iddatadb - "); - $stmt->execute([ - 'idcommessaweb' => $commessaId, - 'commessaweb' => $commessaWebCode, - 'iddatadb' => $iddatadb - ]); - - // 🔹 STEP 9: Send CommessaWeb to laboratory (commentato come richiesto) - /* - $sendResult = $api->post("CommessaWeb({$commessaId})/InviaCommessa", []); - - // Logga il POST - $logContentStep9 = "curl --location --request POST '{$apiBaseUrl}CommessaWeb({$commessaId})/InviaCommessa' \\\n" . - "--header 'Content-Type: application/json' \\\n" . - "--header 'Authorization: Bearer ••••••' \\\n" . - "--data '{}'\n\n" . - "RESPONSE:\n" . json_encode($sendResult, JSON_PRETTY_PRINT); - $logFileStep9 = $logDir . "commessa_{$commessaId}_send_step9_" . time() . ".txt"; - file_put_contents($logFileStep9, $logContentStep9); - */ - - // 🔹 STEP 10: GET di controllo post-PATCH - $expand = "CommesseCustomFields(\$expand=CustomField)"; - $commessaAfterPatch = $api->get("CommessaWeb(" . $commessaId . ")?\$expand=" . $expand); - - // Logga il GET di controllo - $logContentStep10 = "curl --location --request GET '{$apiBaseUrl}CommessaWeb({$commessaId})?\$expand=CommesseCustomFields(\$expand=CustomField)' \\\n" . - "--header 'Authorization: Bearer ••••••'\n\n" . - "RESPONSE:\n" . json_encode($commessaAfterPatch, JSON_PRETTY_PRINT); - $logFileStep10 = $logDir . "commessa_{$commessaId}_get_step10_" . time() . ".txt"; - file_put_contents($logFileStep10, $logContentStep10); - - // 🔹 STEP 11: Prepare final response - $finalCommessa = [ - "Cliente" => $clienteId, - "SchemaCustomField" => $schemaId, - "Richiedente" => $commessaWeb["Richiedente"] ?? "Web Import", - "Descrizione" => $commessaWeb["Descrizione"] ?? "", - "CommesseCustomFields" => $commessaAfterPatch["CommesseCustomFields"] ?? [], - "Campioni" => $campioni, - "Inviata" => 0 // Non inviato, come richiesto - ]; - - echo json_encode([ - "success" => true, - "commessaWeb" => $finalCommessa, - "commessaWebApiResponse" => $commessaWeb, // Incluso per debug - "totalCampioni" => count($campioni), - "totalCustomFields" => count($commessaAfterPatch["CommesseCustomFields"] ?? []), - "message" => "Export successful", - "logFiles" => [ - "step5_create" => $logFileStep5, - "step6_campioni" => $logFileStep6, - "step7_patch" => $logFileStep7, - "step10_get" => $logFileStep10 - ] - ]); -} catch (Exception $e) { - error_log("LIMS Export Error: " . $e->getMessage() . "\nTrace: " . $e->getTraceAsString()); - - echo json_encode([ - "success" => false, - "message" => "Export failed: " . $e->getMessage(), - "logFiles" => [ - "step5_create" => $logFileStep5 ?? null, - "step6_campioni" => $logFileStep6 ?? null, - "step7_patch" => $logFileStep7 ?? null, - "step10_get" => $logFileStep10 ?? null - ] - ]); -} diff --git a/public/userarea/fetch_tracking_info.php b/public/userarea/fetch_tracking_info.php deleted file mode 100644 index 1ed680c..0000000 --- a/public/userarea/fetch_tracking_info.php +++ /dev/null @@ -1,150 +0,0 @@ - false, 'message' => 'Numero di tracking o corriere non fornito']); -} - -$trackingNumber = $_POST['tracking_number']; -$courierCode = $_POST['courier_code']; - -// Lista dei corrieri validi per validazione -$validCarriers = ['tnt-it', 'dhl', 'gls', 'sda', 'ups']; -if (!in_array($courierCode, $validCarriers)) { - sendResponse(['success' => false, 'message' => 'Corriere non valido']); -} - -// Imposta il nome del corriere in base al codice -$carrierNames = [ - 'tnt-it' => 'TNT Italy', - 'dhl' => 'DHL', - 'gls' => 'GLS', - 'sda' => 'SDA', - 'ups' => 'UPS' -]; -$courierName = $carrierNames[$courierCode]; - -// Funzione per fare una richiesta cURL a TrackingMore -function makeRequest($url, $data, $apiKey, $method = 'POST') -{ - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, [ - 'Tracking-Api-Key: ' . $apiKey, - 'Content-Type: application/json' - ]); - if ($method === 'POST') { - curl_setopt($ch, CURLOPT_POST, true); - $jsonData = json_encode($data, JSON_PRETTY_PRINT); - curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData); - file_put_contents('debug.log', "Encoded JSON Data: $jsonData\n", FILE_APPEND); - } - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - $response = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - $error = curl_error($ch); - curl_close($ch); - - file_put_contents('debug.log', "Request URL: $url\nRequest Data: " . json_encode($data) . "\nResponse: $response\nHTTP Code: $httpCode\nError: $error\n", FILE_APPEND); - - if ($response === false) { - return [ - 'success' => false, - 'code' => $httpCode, - 'message' => 'Errore nella richiesta API: ' . $error - ]; - } - - $decodedResponse = json_decode($response, true); - if ($decodedResponse === null) { - return [ - 'success' => false, - 'code' => $httpCode, - 'message' => 'Risposta API non valida (non è JSON)' - ]; - } - - $decodedResponse['success'] = isset($decodedResponse['meta']['code']) && ($decodedResponse['meta']['code'] === 200 || $decodedResponse['meta']['code'] === 201); - $decodedResponse['http_code'] = $httpCode; - return $decodedResponse; -} - -// Step 1: Prova a creare il tracking -$createUrl = 'https://api.trackingmore.com/v4/trackings/create'; -$createData = [ - 'tracking_number' => $trackingNumber, - 'courier_code' => $courierCode -]; -$createResponse = makeRequest($createUrl, $createData, $apiKey); -file_put_contents('debug.log', "Create Response: " . json_encode($createResponse) . "\n", FILE_APPEND); - -$trackingInfo = null; -if ($createResponse['success']) { - // Creazione riuscita, usa i dati restituiti - $trackingInfo = $createResponse['data']; -} else { - // Controlla se l'errore è "Tracking No. already exists" (4101) - if (isset($createResponse['meta']['code']) && $createResponse['meta']['code'] === 4101) { - // Il tracking esiste già, usa /trackings (GET) con tracking_number e courier_code - $getUrl = 'https://api.trackingmore.com/v4/get?tracking_numbers=' . urlencode($trackingNumber); - $getResponse = makeRequest($getUrl, [], $apiKey, 'GET'); - file_put_contents('debug.log', "Get Response: " . json_encode($getResponse) . "\n", FILE_APPEND); - - if ($getResponse['success'] && !empty($getResponse['data']['items']) && !empty($getResponse['data']['items'][0])) { - $trackingInfo = $getResponse['data']['items'][0]; - } else { - $errorMessage = isset($getResponse['meta']['message']) ? $getResponse['meta']['message'] : 'Errore sconosciuto'; - sendResponse(['success' => false, 'message' => 'Errore nel recupero del tracking esistente: ' . $errorMessage]); - } - } else { - // Altro errore nella creazione - $errorMessage = isset($createResponse['meta']['message']) ? $createResponse['meta']['message'] : 'Errore sconosciuto'; - sendResponse(['success' => false, 'message' => 'Errore nella creazione del tracking: ' . $errorMessage]); - } -} - -if (!$trackingInfo) { - sendResponse(['success' => false, 'message' => 'Nessuna informazione di tracking trovata']); -} - -// Estrai la data di consegna e il firmatario -$deliveryDate = 'Non disponibile'; -$signedBy = 'Non disponibile'; -if (isset($trackingInfo['origin_info']['trackinfo']) && is_array($trackingInfo['origin_info']['trackinfo'])) { - foreach ($trackingInfo['origin_info']['trackinfo'] as $checkpoint) { - if (isset($checkpoint['checkpoint_delivery_status']) && $checkpoint['checkpoint_delivery_status'] === 'delivered') { - $deliveryDate = $checkpoint['checkpoint_date'] ?? 'Non disponibile'; - $signedBy = $trackingInfo['signed_by'] ?? 'Non disponibile'; - break; - } - } -} - -// Restituisci i dati al frontend -sendResponse([ - 'success' => true, - 'deliveryDate' => $deliveryDate, - 'signedBy' => $signedBy, - 'carrierName' => $courierName -]); diff --git a/public/userarea/fetch_tracking_info17track.php b/public/userarea/fetch_tracking_info17track.php deleted file mode 100644 index 381ce14..0000000 --- a/public/userarea/fetch_tracking_info17track.php +++ /dev/null @@ -1,166 +0,0 @@ - false, 'message' => 'Numero di tracking non fornito']); -} - -$trackingNumber = $_POST['tracking_number']; - -// Funzione per fare una richiesta cURL a 17Track -function makeRequest($url, $data, $apiKey, $method = 'POST') -{ - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, [ - '17token: ' . $apiKey, - 'Content-Type: application/json' - ]); - if ($method === 'POST') { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); - } - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - $response = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - $error = curl_error($ch); - curl_close($ch); - - file_put_contents('debug.log', "Request URL: $url\nRequest Data: " . json_encode($data) . "\nResponse: $response\nHTTP Code: $httpCode\nError: $error\n", FILE_APPEND); - - if ($response === false || $httpCode !== 200) { - return [ - 'success' => false, - 'code' => $httpCode, - 'message' => 'Errore nella richiesta API: HTTP ' . $httpCode . ' - ' . $error - ]; - } - - $decodedResponse = json_decode($response, true); - if ($decodedResponse === null) { - return [ - 'success' => false, - 'code' => $httpCode, - 'message' => 'Risposta API non valida (non è JSON)' - ]; - } - - return $decodedResponse; -} - -// Step 1: Prova con auto-detection -$trackUrl = 'https://api.17track.net/track/v2/register'; -$trackData = [ - [ - 'number' => $trackingNumber, - 'carrier' => null, - 'auto_detection' => true - ] -]; -$registerResponse = makeRequest($trackUrl, $trackData, $apiKey); - -file_put_contents('debug.log', "Register Response (Auto-detect): " . json_encode($registerResponse) . "\n", FILE_APPEND); - -if (!isset($registerResponse['data']['accepted']) || empty($registerResponse['data']['accepted'])) { - $errorMessage = $registerResponse['data']['rejected'][0]['error']['message'] ?? 'Errore sconosciuto'; - sendResponse(['success' => false, 'message' => 'Errore nella registrazione del tracking: ' . $errorMessage]); -} - -// Step 2: Recupera i dettagli con riprova -$getUrl = 'https://api.17track.net/track/v2/gettrackinfo'; -$getData = [['number' => $trackingNumber]]; -$maxAttempts = 3; -$delaySeconds = 5; - -for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) { - $trackResponse = makeRequest($getUrl, $getData, $apiKey); - file_put_contents('debug.log', "Track Response (Attempt $attempt): " . json_encode($trackResponse) . "\n", FILE_APPEND); - - if (isset($trackResponse['data']['accepted']) && !empty($trackResponse['data']['accepted'])) { - break; - } - - if ($attempt < $maxAttempts) { - sleep($delaySeconds); - } -} - -// Se auto-detection ha successo, procedi -if (isset($trackResponse['data']['accepted']) && !empty($trackResponse['data']['accepted'])) { - $trackingInfo = $trackResponse['data']['accepted'][0]['track'] ?? null; - if (!$trackingInfo) { - sendResponse(['success' => false, 'message' => 'Nessuna informazione di tracking trovata']); - } - - $deliveryDate = 'Non disponibile'; - $signedBy = 'Non disponibile'; - $carrierName = $trackingInfo['carrier']['name'] ?? 'Sconosciuto'; - - if (isset($trackingInfo['z0']['e']) && $trackingInfo['z0']['e'] == 40) { - $deliveryDate = $trackingInfo['z0']['z'] ?? 'Non disponibile'; - $signedBy = $trackingInfo['z0']['d'] ?? 'Non disponibile'; - } - - sendResponse([ - 'success' => true, - 'deliveryDate' => $deliveryDate, - 'signedBy' => $signedBy, - 'carrierName' => $carrierName - ]); -} - -// Step 3: Se auto-detection fallisce, prova una lista di corrieri comuni -$commonCarriers = [ - ['code' => 100003, 'name' => 'TNT'], // TNT - ['code' => 100001, 'name' => 'DHL'], // DHL Express - ['code' => 100065, 'name' => 'DHL eCommerce'], // DHL eCommerce - ['code' => 100002, 'name' => 'UPS'] // UPS -]; - -$possibleCarriers = []; -foreach ($commonCarriers as $carrier) { - $trackData = [ - [ - 'number' => $trackingNumber, - 'carrier' => $carrier['code'], - 'auto_detection' => false - ] - ]; - $registerResponse = makeRequest($trackUrl, $trackData, $apiKey); - - if (isset($registerResponse['data']['accepted']) && !empty($registerResponse['data']['accepted'])) { - $possibleCarriers[] = $carrier['name']; - } - sleep(1); // Piccolo ritardo per evitare limiti di rate -} - -if (!empty($possibleCarriers)) { - sendResponse([ - 'success' => false, - 'message' => 'Auto-detection fallita. Seleziona un corriere tra quelli possibili.', - 'possibleCarriers' => $possibleCarriers - ]); -} else { - sendResponse(['success' => false, 'message' => 'Nessun corriere identificato per questo numero di tracking']); -} diff --git a/public/userarea/fetch_tracking_infotracking.php b/public/userarea/fetch_tracking_infotracking.php deleted file mode 100644 index 08ee258..0000000 --- a/public/userarea/fetch_tracking_infotracking.php +++ /dev/null @@ -1,166 +0,0 @@ - false, 'message' => 'Numero di tracking non fornito']); -} - -$trackingNumber = $_POST['tracking_number']; - -// Funzione per fare una richiesta cURL a TrackingMore -function makeRequest($url, $data, $apiKey, $method = 'POST') -{ - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, [ - 'Tracking-Api-Key: ' . $apiKey, - 'Content-Type: application/json' - ]); - if ($method === 'POST') { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); - } - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - $response = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - $error = curl_error($ch); - curl_close($ch); - - file_put_contents('debug.log', "Request URL: $url\nRequest Data: " . json_encode($data) . "\nResponse: $response\nHTTP Code: $httpCode\nError: $error\n", FILE_APPEND); - - if ($response === false || ($httpCode !== 200 && $httpCode !== 201)) { - return [ - 'success' => false, - 'code' => $httpCode, - 'message' => 'Errore nella richiesta API: HTTP ' . $httpCode . ' - ' . $error - ]; - } - - $decodedResponse = json_decode($response, true); - if ($decodedResponse === null) { - return [ - 'success' => false, - 'code' => $httpCode, - 'message' => 'Risposta API non valida (non è JSON)' - ]; - } - - $decodedResponse['success'] = isset($decodedResponse['meta']['code']) && ($decodedResponse['meta']['code'] === 200 || $decodedResponse['meta']['code'] === 201); - return $decodedResponse; -} - -// Step 1: Identifica il corriere -$detectUrl = 'https://api.trackingmore.com/v4/couriers/detect'; -$detectData = ['tracking_number' => $trackingNumber]; -$detectResponse = makeRequest($detectUrl, $detectData, $apiKey); -file_put_contents('debug.log', "Detect Response: " . json_encode($detectResponse) . "\n", FILE_APPEND); - -if (!$detectResponse['success']) { - $errorMessage = isset($detectResponse['meta']['message']) ? $detectResponse['meta']['message'] : 'Errore sconosciuto'; - sendResponse(['success' => false, 'message' => 'Errore nella rilevazione del corriere: ' . $errorMessage]); -} - -$couriers = $detectResponse['data'] ?? []; -if (empty($couriers)) { - sendResponse(['success' => false, 'message' => 'Corriere non identificato per il numero di tracking']); -} - -// Prendi il primo corriere per ora -$courierCode = $couriers[0]['courier_code'] ?? null; -$courierName = $couriers[0]['courier_name'] ?? 'Sconosciuto'; -if (!$courierCode) { - sendResponse(['success' => false, 'message' => 'Corriere non identificato']); -} - -// Step 2: Crea un tracking -$createUrl = 'https://api.trackingmore.com/v4/trackings/create'; -$createData = [ - 'tracking_number' => $trackingNumber, - 'courier_code' => $courierCode -]; -$createResponse = makeRequest($createUrl, $createData, $apiKey); -file_put_contents('debug.log', "Create Response: " . json_encode($createResponse) . "\n", FILE_APPEND); - -if (!$createResponse['success']) { - $errorMessage = isset($createResponse['meta']['message']) ? $createResponse['meta']['message'] : 'Errore sconosciuto'; - sendResponse(['success' => false, 'message' => 'Errore nella creazione del tracking: ' . $errorMessage]); -} - -// Step 3: Recupera i dettagli del tracking con riprova -$getUrl = 'https://api.trackingmore.com/v4/trackings/get?tracking_number=' . urlencode($trackingNumber); -$maxAttempts = 3; -$delaySeconds = 5; - -for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) { - $trackResponse = makeRequest($getUrl, [], $apiKey, 'GET'); - file_put_contents('debug.log', "Track Response (Attempt $attempt): " . json_encode($trackResponse) . "\n", FILE_APPEND); - - if ($trackResponse['success'] && !empty($trackResponse['data'])) { - break; - } - - if ($attempt < $maxAttempts) { - sleep($delaySeconds); - } -} - -if (!$trackResponse['success']) { - $errorMessage = isset($trackResponse['meta']['message']) ? $trackResponse['meta']['message'] : 'Errore sconosciuto'; - sendResponse(['success' => false, 'message' => 'Errore nel recupero delle informazioni: ' . $errorMessage]); -} - -$trackingInfo = $trackResponse['data'] ?? null; -if (!$trackingInfo) { - // Se ci sono più corrieri rilevati, restituisci una lista per la tendina - if (count($couriers) > 1) { - $possibleCarriers = array_map(function ($courier) { - return ['code' => $courier['courier_code'], 'name' => $courier['courier_name']]; - }, $couriers); - sendResponse([ - 'success' => false, - 'message' => 'Dati non trovati. Seleziona un corriere tra quelli rilevati.', - 'possibleCarriers' => $possibleCarriers - ]); - } - sendResponse(['success' => false, 'message' => 'Nessuna informazione di tracking trovata']); -} - -// Estrai la data di consegna e il firmatario -$deliveryDate = 'Non disponibile'; -$signedBy = 'Non disponibile'; -foreach ($trackingInfo['trackinfo'] as $checkpoint) { - if ($checkpoint['status'] === 'delivered') { - $deliveryDate = $checkpoint['Date']; - $signedBy = $checkpoint['signed_by'] ?? 'Non disponibile'; - break; - } -} - -// Restituisci i dati al frontend -sendResponse([ - 'success' => true, - 'deliveryDate' => $deliveryDate, - 'signedBy' => $signedBy, - 'carrierName' => $courierName -]); diff --git a/public/userarea/get_clienti.php b/public/userarea/get_clienti.php deleted file mode 100644 index c07c32b..0000000 --- a/public/userarea/get_clienti.php +++ /dev/null @@ -1,74 +0,0 @@ - 'IdCliente,Nominativo,CodiceNazioneFatturazione', - '$orderby' => 'Nominativo asc' - ]; - - // Costruisce query string con encoding corretto - $queryString = http_build_query($params); - - // Componi endpoint finale - $endpoint = "Cliente?$queryString"; - - // Funzione per eseguire la chiamata con retry - function makeApiRequest($api, $endpoint, $maxRetries = 3) - { - for ($retry = 0; $retry < $maxRetries; $retry++) { - try { - // Tenta la chiamata API - $data = $api->get($endpoint); - // Salva risposta per debug - file_put_contents(__DIR__ . '/clienti_response.json', json_encode($data, JSON_PRETTY_PRINT)); - return $data; - } catch (Exception $e) { - $errorMessage = $e->getMessage(); - // Controlla se l'errore è legato all'autenticazione (HTTP 400 con messaggio specifico) - if (strpos($errorMessage, 'HTTP 400') !== false && strpos($errorMessage, 'Cannot persist the object') !== false) { - // Forza il refresh del token - try { - // Assumi che VisualLimsApiClient abbia un metodo per il refresh del token - $api->refreshToken(); // Da implementare in VisualLimsApiClient se non esiste - error_log("Tentativo $retry: Refresh token eseguito per endpoint $endpoint"); - } catch (Exception $refreshEx) { - error_log("Errore durante il refresh del token: " . $refreshEx->getMessage()); - throw new Exception("Impossibile eseguire il refresh del token: " . $refreshEx->getMessage()); - } - // Ritarda leggermente prima del retry - usleep(500000); // 500ms - continue; - } - // Altri errori non gestiti dal retry - throw $e; - } - } - throw new Exception("Massimo numero di tentativi raggiunto per $endpoint"); - } - - // Esegui la chiamata con retry - $data = makeApiRequest($api, $endpoint); - - echo json_encode($data); -} catch (Exception $e) { - http_response_code(500); - $errorResponse = [ - 'error' => $e->getMessage(), - 'file' => $e->getFile(), - 'line' => $e->getLine(), - 'trace' => $e->getTraceAsString() - ]; - error_log("Errore in get_clienti.php: " . json_encode($errorResponse)); - echo json_encode($errorResponse); -} diff --git a/public/userarea/get_commessaweb.php b/public/userarea/get_commessaweb.php deleted file mode 100644 index 9422528..0000000 --- a/public/userarea/get_commessaweb.php +++ /dev/null @@ -1,39 +0,0 @@ - 'OrderCustomFields']; - - // Debug: salva URL usato - $base_url = 'https://93.43.5.102/limsapi/api/odata/'; - $query = http_build_query($options); - $full_url = $base_url . $endpoint . ($query ? '?' . $query : ''); - file_put_contents(__DIR__ . '/last_url.txt', $full_url . PHP_EOL, FILE_APPEND); - - // Chiamata API - $data = $api->get($endpoint, $options); - - // Salva il JSON in locale - file_put_contents(__DIR__ . '/commessaweb_schema_response.json', json_encode($data, JSON_PRETTY_PRINT)); - - echo json_encode($data); -} catch (Exception $e) { - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - http_response_code(500); - echo json_encode(['error' => $e->getMessage()]); -} diff --git a/public/userarea/get_customfield_values.php b/public/userarea/get_customfield_values.php deleted file mode 100644 index 5770073..0000000 --- a/public/userarea/get_customfield_values.php +++ /dev/null @@ -1,41 +0,0 @@ - ერთი default - if (empty($fieldIds)) { - $fieldIds = [156]; - } - - $results = []; - - foreach ($fieldIds as $customFieldId) { - $endpoint = "CustomField($customFieldId)?\$expand=CustomFieldsValues"; - $data = $api->get($endpoint); - - $results[$customFieldId] = $data['CustomFieldsValues'] ?? []; - } - - // Debug ფაილი - file_put_contents(__DIR__ . '/customfield_values_response.json', json_encode($results)); - - echo json_encode($results); -} catch (Exception $e) { - http_response_code(500); - echo json_encode([ - 'error' => $e->getMessage() - ]); -} diff --git a/public/userarea/get_macro_matrici.php b/public/userarea/get_macro_matrici.php deleted file mode 100644 index 33b181e..0000000 --- a/public/userarea/get_macro_matrici.php +++ /dev/null @@ -1,59 +0,0 @@ -load(); -} catch (Exception $e) { - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore caricamento .env: ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - echo json_encode(['success' => false, 'message' => 'Errore caricamento configurazione: ' . $e->getMessage()]); - exit(1); -} - -// Recupera le variabili d'ambiente -$dbHost = $_ENV['DB_HOST']; -$dbName = $_ENV['DB_DATABASE']; -$dbUser = $_ENV['DB_USERNAME']; -$dbPass = $_ENV['DB_PASSWORD']; -$dbPrefix = $_ENV['DB_PREFIX']; - -// Debug: Log database connection details (excluding password) -file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . " - DB Connection: host=$dbHost, dbname=$dbName, user=$dbUser, prefix=$dbPrefix" . PHP_EOL, FILE_APPEND); - -// Connessione al database MySQL -try { - $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass); - $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -} catch (PDOException $e) { - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore connessione DB: ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - echo json_encode(['success' => false, 'message' => 'Errore connessione al database: ' . $e->getMessage()]); - exit(1); -} - -try { - // Query per recuperare i valori distinti di MacroMatrice, escludendo quelli che iniziano con '*' e ordinandoli - $query = "SELECT DISTINCT MacroMatrice FROM {$dbPrefix}matrici WHERE MacroMatrice IS NOT NULL AND MacroMatrice NOT LIKE '*%' ORDER BY MacroMatrice ASC"; - $stmt = $pdo->prepare($query); - $stmt->execute(); - $macroMatrici = $stmt->fetchAll(PDO::FETCH_COLUMN); - - // Debug: Log del numero di MacroMatrice recuperate - file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - Retrieved ' . count($macroMatrici) . ' MacroMatrice from database' . PHP_EOL, FILE_APPEND); - - // Restituisci risposta JSON - echo json_encode(['success' => true, 'value' => $macroMatrici]); -} catch (PDOException $e) { - // Log errore e restituisci risposta di errore - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore nel recupero delle MacroMatrice: ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - echo json_encode(['success' => false, 'message' => 'Errore nel recupero delle MacroMatrice: ' . $e->getMessage()]); - exit(1); -} diff --git a/public/userarea/get_matrice.php b/public/userarea/get_matrice.php deleted file mode 100644 index ed1be73..0000000 --- a/public/userarea/get_matrice.php +++ /dev/null @@ -1,36 +0,0 @@ - 100] - - // Debug: salva URL usato - $base_url = 'https://93.43.5.102/limsapi/api/odata/'; - $query = http_build_query($options); - $full_url = $base_url . $endpoint . ($query ? '?' . $query : ''); - file_put_contents(__DIR__ . '/last_url.txt', $full_url . PHP_EOL, FILE_APPEND); - - // Chiamata API - $data = $api->get($endpoint, $options); - - // Salva il JSON in locale - file_put_contents(__DIR__ . '/matrici_response.json', json_encode($data, JSON_PRETTY_PRINT)); - - echo json_encode($data); -} catch (Exception $e) { - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - http_response_code(500); - echo json_encode(['error' => $e->getMessage()]); -} diff --git a/public/userarea/get_matrici_db.php b/public/userarea/get_matrici_db.php deleted file mode 100644 index 1052aac..0000000 --- a/public/userarea/get_matrici_db.php +++ /dev/null @@ -1,59 +0,0 @@ -load(); -} catch (Exception $e) { - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore caricamento .env: ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - echo json_encode(['success' => false, 'message' => 'Errore caricamento configurazione: ' . $e->getMessage()]); - exit(1); -} - -// Recupera le variabili d'ambiente -$dbHost = $_ENV['DB_HOST']; -$dbName = $_ENV['DB_DATABASE']; -$dbUser = $_ENV['DB_USERNAME']; -$dbPass = $_ENV['DB_PASSWORD']; -$dbPrefix = $_ENV['DB_PREFIX']; - -// Debug: Log database connection details (excluding password) -file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . " - DB Connection: host=$dbHost, dbname=$dbName, user=$dbUser, prefix=$dbPrefix" . PHP_EOL, FILE_APPEND); - -// Connessione al database MySQL -try { - $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass); - $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -} catch (PDOException $e) { - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore connessione DB: ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - echo json_encode(['success' => false, 'message' => 'Errore connessione al database: ' . $e->getMessage()]); - exit(1); -} - -try { - // Query per recuperare le matrici, includendo MacroMatrice, escludendo quelle che iniziano con '*' e ordinandole - $query = "SELECT IdMatrice, NomeMatrice, MacroMatrice FROM {$dbPrefix}matrici WHERE NomeMatrice NOT LIKE '*%' ORDER BY NomeMatrice ASC"; - $stmt = $pdo->prepare($query); - $stmt->execute(); - $matrici = $stmt->fetchAll(PDO::FETCH_ASSOC); - - // Debug: Log del numero di matrici recuperate - file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - Retrieved ' . count($matrici) . ' matrices from database' . PHP_EOL, FILE_APPEND); - - // Restituisci risposta JSON - echo json_encode(['success' => true, 'value' => $matrici]); -} catch (PDOException $e) { - // Log errore e restituisci risposta di errore - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore nel recupero delle matrici: ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - echo json_encode(['success' => false, 'message' => 'Errore nel recupero delle matrici: ' . $e->getMessage()]); - exit(1); -} diff --git a/public/userarea/get_metadata.php b/public/userarea/get_metadata.php deleted file mode 100644 index 96ef2f7..0000000 --- a/public/userarea/get_metadata.php +++ /dev/null @@ -1,37 +0,0 @@ -get($endpoint, $options); - - // Salva il file XML in locale - file_put_contents(__DIR__ . '/metadata_response.xml', $data); - - // Restituisci il contenuto XML - echo $data; -} catch (Exception $e) { - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - http_response_code(500); - echo '' . htmlspecialchars($e->getMessage()) . ''; -} diff --git a/public/userarea/get_rapporto_prova.php b/public/userarea/get_rapporto_prova.php deleted file mode 100644 index 16e8020..0000000 --- a/public/userarea/get_rapporto_prova.php +++ /dev/null @@ -1,26 +0,0 @@ -get($endpoint); - - file_put_contents(__DIR__ . '/rapporto_expanded.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); - echo json_encode($data); -} catch (Exception $e) { - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - http_response_code(500); - echo json_encode(['error' => $e->getMessage()]); -} diff --git a/public/userarea/get_schema_details.php b/public/userarea/get_schema_details.php deleted file mode 100644 index ff645b1..0000000 --- a/public/userarea/get_schema_details.php +++ /dev/null @@ -1,30 +0,0 @@ -get($endpoint); - - // Salva la risposta per debug - file_put_contents(__DIR__ . '/schema_dettagli_response.json', json_encode($data)); - - echo json_encode($data); -} catch (Exception $e) { - http_response_code(500); - echo json_encode([ - 'error' => $e->getMessage() - ]); -} diff --git a/public/userarea/get_schemi.php b/public/userarea/get_schemi.php deleted file mode 100644 index b788aa7..0000000 --- a/public/userarea/get_schemi.php +++ /dev/null @@ -1,36 +0,0 @@ - 100] - - // Debug: salva URL usato - $base_url = 'https://93.43.5.102/limsapi/api/odata/'; - $query = http_build_query($options); - $full_url = $base_url . $endpoint . ($query ? '?' . $query : ''); - file_put_contents(__DIR__ . '/last_url.txt', $full_url . PHP_EOL, FILE_APPEND); - - // Chiamata API - $data = $api->get($endpoint, $options); - - // Salva il JSON in locale - file_put_contents(__DIR__ . '/schemi_base_response.json', json_encode($data, JSON_PRETTY_PRINT)); - - echo json_encode($data); -} catch (Exception $e) { - file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - http_response_code(500); - echo json_encode(['error' => $e->getMessage()]); -} diff --git a/public/userarea/get_schemi_custom_fields.php b/public/userarea/get_schemi_custom_fields.php deleted file mode 100644 index 3f2533e..0000000 --- a/public/userarea/get_schemi_custom_fields.php +++ /dev/null @@ -1,26 +0,0 @@ -```php -get("SchemaCustomField"); // Recupera la lista degli schemi custom fields - - // Salva la risposta in un file per debug - file_put_contents(__DIR__ . '/schemi_custom_fields_response.json', json_encode($data)); - - echo json_encode($data); -} catch (Exception $e) { - http_response_code(500); - echo json_encode([ - 'error' => $e->getMessage() - ]); -} -?> \ No newline at end of file diff --git a/public/userarea/historical_trf.php b/public/userarea/historical_trf.php deleted file mode 100644 index 9be255d..0000000 --- a/public/userarea/historical_trf.php +++ /dev/null @@ -1,1324 +0,0 @@ -getConnection(); - -// Retrieve all mappings -$stmt = $pdo->prepare("SELECT id, excel_column, data_type, is_required, manual_default, is_manual, field_label, field_id, main_field FROM template_mapping WHERE template_id = ?"); -$stmt->execute([$template_id]); -$allMappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - -if (empty($allMappings)) { - header("Location: xlstemplates_grid.php?status=error&message=" . urlencode("Nessun mapping trovato per il template")); - exit; -} - -// Trova il main_field -$mainFieldMapping = null; -foreach ($allMappings as $mapping) { - if ($mapping['main_field'] == 1) { - $mainFieldMapping = $mapping; - break; - } -} -if (!$mainFieldMapping) { - $mainFieldMapping = reset(array_filter($allMappings, fn($m) => !$m['is_manual'])); -} - -// Retrieve data from datadb -if ($mode === 'edit' && !empty($selected_ids)) { - $placeholders = implode(',', array_fill(0, count($selected_ids), '?')); - $stmt = $pdo->prepare(" - SELECT d.*, CONCAT(u.first_name, ' ', u.last_name) AS user_name - FROM datadb d - LEFT JOIN auth_users u ON d.user_id = u.id - WHERE d.templateid = ? AND d.status = ? AND d.iddatadb IN ($placeholders) - "); - $params = array_merge([$template_id, $status], $selected_ids); - $stmt->execute($params); - $importedData = $stmt->fetchAll(PDO::FETCH_ASSOC); - $total_records = count($importedData); - $total_pages = 1; -} else { - $stmt = $pdo->prepare("SELECT COUNT(*) FROM datadb WHERE templateid = ? AND status = ?"); - $stmt->execute([$template_id, $status]); - $total_records = $stmt->fetchColumn(); - $total_pages = ceil($total_records / $limit); - - $stmt = $pdo->prepare(" - SELECT d.*, CONCAT(u.first_name, ' ', u.last_name) AS user_name - FROM datadb d - LEFT JOIN auth_users u ON d.user_id = u.id - WHERE d.templateid = ? AND d.status = ? - LIMIT ? OFFSET ? - "); - $stmt->execute([$template_id, $status, $limit, $offset]); - $importedData = $stmt->fetchAll(PDO::FETCH_ASSOC); -} - -error_log("Record caricati: " . count($importedData)); - -$insertedIds = array_column($importedData, 'iddatadb'); - -// Retrieve manual details -$manualDetails = []; -if (!empty($insertedIds)) { - $placeholders = implode(',', array_fill(0, count($insertedIds), '?')); - $stmt = $pdo->prepare(" - SELECT d.id AS detail_id, d.id AS datadb_id, d.mapping_id, d.field_value, m.field_label, m.data_type, m.is_required, m.manual_default - FROM import_data_details d - JOIN template_mapping m ON d.mapping_id = m.id - WHERE d.id IN ($placeholders) - "); - $stmt->execute($insertedIds); - $manualDetails = $stmt->fetchAll(PDO::FETCH_ASSOC); -} - -// Retrieve global mapping for slugs -$stmt = $pdo->query("SELECT mysql_column_name, user_friendly_slug FROM column_mapping"); -$slugMapping = []; -foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { - $slugMapping[$row['mysql_column_name']] = $row['user_friendly_slug']; -} -?> - - - - - - - - - - - - Dati Storici - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - -
    - - -
    -
    -
    -
    -
    -
    -
    Dati Storici
    -
    -
    - - -
    -
    -
    -
    - -
    - Nessun dato trovato per il template e lo status selezionato. -
    - - -
    -
    -
    - Visualizzazione di - di record -
    -
    - - -
    -
    - - - - - - - - - - - - - prepare("SELECT field_value FROM import_data_details WHERE id = ? AND mapping_id = ?"); - $stmt->execute([$row['iddatadb'], $mainFieldMapping['id']]); - $mainValue = $stmt->fetchColumn() ?? ''; - } - ?> - - - - - - - - - -
    FileAzioni
    File - -
    - -
    - -
    -
    - -
    -
    - Visualizzazione di - di record -
    -
    - - - -
    -
    - -
    - -
    -
    -
    -
    - "; - if ($mainFieldMapping['data_type'] === 'SceltaMultipla') { - $fieldValue = $mainFieldMapping['manual_default'] ?? ''; - echo ""; - echo ""; - } else { - $fieldValue = $mainFieldMapping['manual_default'] ?? ''; - if ($mainFieldMapping['data_type'] === 'DATE' && $mainFieldMapping['manual_default'] === 'today') { - $fieldValue = date('Y-m-d'); - } - if ($mainFieldMapping['data_type'] === 'DATE') { - echo ""; - } elseif ($mainFieldMapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo ""; - } - echo "
    "; - } else { - echo "
    "; - } - // Status (subito dopo main_field) - $fixedColumnsReduced = ['status']; - foreach ($fixedColumnsReduced as $col) { - echo "
    "; - } - // Campi automatici (escluso main_field) - $autoIndex = ($mainFieldMapping && !$mainFieldMapping['is_manual']) ? 1 : 0; - foreach ($allMappings as $mapping) { - if (!$mapping['is_manual'] && $mapping['main_field'] != 1) { - $inputClass = 'auto-input'; - if ($mapping['is_required']) $inputClass .= ' required-input'; - echo "
    "; - if ($mapping['data_type'] === 'SceltaMultipla') { - $fieldValue = $mapping['manual_default'] ?? ''; - echo ""; - echo ""; - } else { - echo "
    "; - } - echo "
    "; - $autoIndex++; - } - } - // Campi manuali (escluso main_field) - $manualIndex = ($mainFieldMapping && $mainFieldMapping['is_manual']) ? 1 : 0; - foreach ($allMappings as $mapping) { - if ($mapping['is_manual'] && $mapping['main_field'] != 1) { - $fieldValue = $mapping['manual_default'] ?? ''; - if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') { - $fieldValue = date('Y-m-d'); - } - $inputClass = 'manual-input'; - if ($mapping['is_required']) $inputClass .= ' required-input'; - echo "
    "; - if ($mapping['data_type'] === 'SceltaMultipla') { - echo ""; - echo ""; - } elseif ($mapping['data_type'] === 'DATE') { - echo ""; - echo ""; - } elseif ($mapping['data_type'] === 'INT') { - echo ""; - echo ""; - } else { - echo ""; - echo ""; - } - echo "
    "; - $manualIndex++; - } - } - // Colonne Import Reference Code, filename_import - echo "
    "; // Import Reference Code - echo "
    "; // filename_import - // AWB Number e Tracking Info - echo "
    "; - echo "
    "; - ?> -
    -
    -
    Azioni
    -
    - " . htmlspecialchars($mainFieldMapping['field_label']) . "
    "; - $headerIndex++; - } - // Header per status (subito dopo main_field) - foreach ($fixedColumnsReduced as $col) { - $displayName = $slugMapping[$col] ?? $col; - echo "
    $displayName
    "; - $headerIndex++; - } - // Header per campi automatici (escluso main_field) - foreach ($allMappings as $mapping) { - if (!$mapping['is_manual'] && $mapping['main_field'] != 1) { - echo "
    " . htmlspecialchars($mapping['field_label']) . "
    "; - $headerIndex++; - } - } - // Header per campi manuali (escluso main_field) - foreach ($allMappings as $mapping) { - if ($mapping['is_manual'] && $mapping['main_field'] != 1) { - echo "
    " . htmlspecialchars($mapping['field_label']) . "
    "; - $headerIndex++; - } - } - // Header per Import Reference Code, filename_import - echo "
    Import Reference Code
    "; - $headerIndex++; - echo "
    File
    "; - $headerIndex++; - // Header per AWB Number e Tracking Info - echo "
    AWB Number
    "; - $headerIndex++; - echo "
    Tracking Info
    "; - ?> -
    - $row): ?> -
    -
    -
    - - - - - - - -
    -
    - $d['datadb_id'] == $row['iddatadb']); - // Campo con main_field = 1 - if ($mainFieldMapping) { - $detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mainFieldMapping['id']); - $detail = reset($detail) ?: ['field_value' => $mainFieldMapping['manual_default']]; - $fieldValue = $detail['field_value'] ?? $mainFieldMapping['manual_default'] ?? ''; - $requiredClass = ($mainFieldMapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : ''; - $inputClass = $mainFieldMapping['is_manual'] ? 'manual-input' : 'auto-input'; - if ($mainFieldMapping['is_required']) $inputClass .= ' required-input'; - $indexField = $mainFieldMapping['is_manual'] ? "manual_0" : "auto_0"; - echo "
    "; - if ($mainFieldMapping['data_type'] === 'SceltaMultipla') { - echo ""; - } elseif ($mainFieldMapping['data_type'] === 'DATE') { - echo ""; - } elseif ($mainFieldMapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo "
    "; - $cellIndex++; - } - // Status (subito dopo main_field) - $fixedColumnsReduced = ['status']; - foreach ($fixedColumnsReduced as $col) { - $value = $row[$col] ?? ''; - echo "
    "; - if ($col === 'status') { - $badgeClass = $value === 'i' ? 'status-i' : ($value === 'P' ? 'status-P' : 'status-l'); - $badgeText = $value === 'i' ? 'Imported' : ($value === 'P' ? 'Progress' : 'LIMS'); - // Aggiungi il numero di commessaweb se lo status è 'l' - if ($value === 'l') { - $commessaWeb = isset($row['commessaweb']) ? htmlspecialchars($row['commessaweb']) : ''; - $badgeText .= " ($commessaWeb)"; - } - echo "" . htmlspecialchars($badgeText) . ""; - echo ""; - } - echo "
    "; - $cellIndex++; - } - // Campi automatici (escluso main_field) - $autoIndex = ($mainFieldMapping && !$mainFieldMapping['is_manual']) ? 1 : 0; - foreach ($allMappings as $mapping) { - if (!$mapping['is_manual'] && $mapping['main_field'] != 1) { - $detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']); - $detail = reset($detail) ?: ['field_value' => $mapping['manual_default']]; - $fieldValue = $detail['field_value'] ?? $mapping['manual_default'] ?? ''; - $requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : ''; - $inputClass = 'auto-input'; - if ($mapping['is_required']) $inputClass .= ' required-input'; - echo "
    "; - if ($mapping['data_type'] === 'SceltaMultipla') { - echo ""; - } elseif ($mapping['data_type'] === 'DATE') { - echo ""; - } elseif ($mapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo "
    "; - $cellIndex++; - $autoIndex++; - } - } - // Campi manuali (escluso main_field) - $manualIndex = ($mainFieldMapping && $mainFieldMapping['is_manual']) ? 1 : 0; - foreach ($allMappings as $mapping) { - if ($mapping['is_manual'] && $mapping['main_field'] != 1) { - $detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']); - $detail = reset($detail) ?: ['field_value' => $mapping['manual_default']]; - $fieldValue = $detail['field_value'] ?? $mapping['manual_default'] ?? ''; - if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today' && empty($fieldValue)) { - $fieldValue = date('Y-m-d'); - } - $requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : ''; - $inputClass = 'manual-input'; - if ($mapping['is_required']) $inputClass .= ' required-input'; - echo "
    "; - if ($mapping['data_type'] === 'SceltaMultipla') { - echo ""; - } elseif ($mapping['data_type'] === 'DATE') { - echo ""; - } elseif ($mapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo "
    "; - $cellIndex++; - $manualIndex++; - } - } - // Colonne Import Reference Code e filename_import - echo "
    "; - echo "" . htmlspecialchars($row['importreferencecode']) . ""; - echo ""; - echo "
    "; - $cellIndex++; - echo "
    "; - echo "File"; - echo ""; - echo "
    "; - $cellIndex++; - // Colonne AWB Number e Tracking Info - ?> -
    - - > - -
    -
    - Shipment Info - -
    -
    - -
    - - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/import_dashboard.php b/public/userarea/import_dashboard.php deleted file mode 100644 index a35f1cb..0000000 --- a/public/userarea/import_dashboard.php +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - Template Buttons - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - - - -
    - - - -
    -
    - - -
    -
    -
    Active Templates
    -
    -
    - - -
    -
    -
    - -
    -
    -
    - - -
    - - - - - - - - \ No newline at end of file diff --git a/public/userarea/import_edit.php b/public/userarea/import_edit.php deleted file mode 100644 index 5c4560a..0000000 --- a/public/userarea/import_edit.php +++ /dev/null @@ -1,1039 +0,0 @@ -getConnection(); - -// Genera un UUID univoco per importreferencecode -$importReferenceCode = date('YmdHis') . '-' . uniqid(); - -// Recupera il mapping per il template -$stmt = $pdo->prepare("SELECT excel_column, mysql_column, data_type, is_required, default_value FROM excel_column_mappings WHERE template_id = ?"); -$stmt->execute([$template_id]); -$mappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - -if (empty($mappings)) { - header("Location: import_xls.php?id=$template_id&status=error&message=" . urlencode("Nessun mapping trovato per il template")); - exit; -} - -// Recupera il client_specific_fields dal template -$stmt = $pdo->prepare("SELECT client_specific_fields FROM excel_templates WHERE id = ?"); -$stmt->execute([$template_id]); -$template = $stmt->fetch(PDO::FETCH_ASSOC); -$clientSpecificFields = $template && !empty($template['client_specific_fields']) ? json_decode($template['client_specific_fields'], true) : []; - -// Crea un array per il mapping -$columnMapping = []; -foreach ($mappings as $mapping) { - $excelColumnIndex = array_search($mapping['excel_column'], $columns); - if ($excelColumnIndex !== false) { - $columnMapping[$excelColumnIndex] = [ - 'mysql_column' => $mapping['mysql_column'], - 'data_type' => $mapping['data_type'], - 'is_required' => $mapping['is_required'], - 'default_value' => $mapping['default_value'] - ]; - } -} - -// Inserisci le righe selezionate in datadb -$insertedIds = []; -foreach ($selected_rows as $rowIndex) { - $row = $rows[$rowIndex]; - $values = []; - $placeholders = []; - $columnsToInsert = []; - - foreach ($columnMapping as $excelIndex => $mapping) { - $mysqlColumn = $mapping['mysql_column']; - $value = $row[$excelIndex] ?? $mapping['default_value']; - - if ($mapping['is_required'] && (is_null($value) || $value === '')) { - $value = $mapping['default_value']; - if (is_null($value)) { - header("Location: import_xls.php?id=$template_id&status=error&message=" . urlencode("Valore richiesto mancante per la colonna $mysqlColumn")); - exit; - } - } - - switch ($mapping['data_type']) { - case 'INT': - $value = is_numeric($value) ? (int)$value : ($mapping['default_value'] ?? null); - break; - case 'DATE': - $value = !empty($value) ? date('Y-m-d', strtotime($value)) : ($mapping['default_value'] ?? null); - break; - case 'CHAR': - $value = !empty($value) ? substr($value, 0, 1) : ($mapping['default_value'] ?? null); - break; - case 'VARCHAR': - default: - $value = !empty($value) ? htmlspecialchars($value) : ($mapping['default_value'] ?? null); - break; - } - - if (!is_null($value)) { - $columnsToInsert[] = $mysqlColumn; - $placeholders[] = '?'; - $values[] = $value; - } - } - - $columnsToInsert[] = 'importreferencecode'; - $placeholders[] = '?'; - $values[] = $importReferenceCode; - - $columnsToInsert[] = 'filename_import'; - $placeholders[] = '?'; - $values[] = $newFilename; - - $columnsToInsert[] = 'status'; - $placeholders[] = '?'; - $values[] = 'i'; - - $columnsToInsert[] = 'user_id'; - $placeholders[] = '?'; - $values[] = $user_id; - - $columnsToInsert[] = 'limscode'; - $placeholders[] = '?'; - $values[] = null; - - $columnsToInsert[] = 'importdate'; - $placeholders[] = '?'; - $values[] = date('Y-m-d'); - - $sql = "INSERT INTO datadb (" . implode(', ', $columnsToInsert) . ") VALUES (" . implode(', ', $placeholders) . ")"; - $stmt = $pdo->prepare($sql); - $stmt->execute($values); - - $insertedIds[] = $pdo->lastInsertId(); -} - -// Recupera i dati appena inseriti con i nomi degli utenti -$stmt = $pdo->prepare(" - SELECT d.*, CONCAT(u.first_name, ' ', u.last_name) AS user_name - FROM datadb d - LEFT JOIN auth_users u ON d.user_id = u.id - WHERE d.iddatadb IN (" . implode(',', array_fill(0, count($insertedIds), '?')) . ") -"); -$stmt->execute($insertedIds); -$importedData = $stmt->fetchAll(PDO::FETCH_ASSOC); - -// Recupera il mapping globale per mostrare gli slug leggibili -$stmt = $pdo->query("SELECT mysql_column_name, user_friendly_slug FROM column_mapping"); -$slugMapping = []; -foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { - $slugMapping[$row['mysql_column_name']] = $row['user_friendly_slug']; -} -?> - - - - - - - - - - - - - - Edit Imported Data - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - -
    - - -
    -
    - - -
    -
    -
    -
    -
    Modifica Dati Importati
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    "; - $headerIndex++; - } - } - // Aggiungi gli input per i campi aggiuntivi sopra l'header - foreach ($clientSpecificFields as $fieldName => $fieldDetails) { - $fieldValue = $fieldDetails['default_value']; - if ($fieldDetails['type'] === 'date' && $fieldDetails['default_value'] === 'today') { - $fieldValue = date('Y-m-d'); - } - $requiredAttr = $fieldDetails['is_required'] ? 'required' : ''; - echo "
    "; - if ($fieldDetails['type'] === 'date') { - echo ""; - } elseif ($fieldDetails['type'] === 'boolean') { - echo ""; - } else { - echo ""; - } - echo ""; - echo "
    "; - $headerIndex++; - } - // Spazi vuoti per AWB Number e Tracking Info - echo "
    "; - echo "
    "; - ?> -
    - - -
    -
    Save
    -
    Photos
    -
    Parts
    - $displayName
    "; - $headerIndex++; - } - } - // Aggiungi gli header per i campi aggiuntivi - foreach ($clientSpecificFields as $fieldName => $fieldDetails) { - echo "
    $fieldName
    "; - $headerIndex++; - } - ?> -
    AWB Number
    -
    -
    Tracking Info
    -
    -
    - - - $row): ?> -
    -
    - -
    -
    - -
    -
    - -
    - $value) { - $visible = !in_array($col, ['iddatadb', 'importreferencecode', 'limscode', 'user_name']); - if ($visible) { - ?> -
    - - - - - File - - - - - - - - - - - - -
    - - - $fieldDetails) { - ?> -
    - "; - } elseif ($fieldDetails['type'] === 'boolean') { - echo ""; - } else { - echo ""; - } - ?> -
    - - -
    - - - -
    -
    - Shipment Info - -
    -
    - -
    - - - - -
    -
    -
    - - - -
    - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/import_edit2 - bck080725.php b/public/userarea/import_edit2 - bck080725.php deleted file mode 100644 index 91310a8..0000000 --- a/public/userarea/import_edit2 - bck080725.php +++ /dev/null @@ -1,1072 +0,0 @@ -getConnection(); - -// Genera un UUID univoco per importreferencecode -$importReferenceCode = date('YmdHis') . '-' . uniqid(); - -// Recupera tutti i mapping dal template (automatici e manuali) -$stmt = $pdo->prepare("SELECT id, field_id, field_id AS excel_column, field_id AS mysql_column, data_type, is_required, manual_default, is_manual, field_label FROM template_mapping WHERE template_id = ?"); -$stmt->execute([$template_id]); -$allMappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - -if (empty($allMappings)) { - header("Location: import_xls.php?id=$template_id&status=error&message=" . urlencode("Nessun mapping trovato per il template")); - exit; -} - -// Separa i mapping automatici (is_manual = 0) da quelli manuali (is_manual = 1) -$autoMappings = array_filter($allMappings, fn($m) => !$m['is_manual']); -$manualMappings = array_filter($allMappings, fn($m) => $m['is_manual']); - -// Inserisci le righe selezionate in datadb -$insertedIds = []; -foreach ($selected_rows as $rowIndex) { - $row = $rows[$rowIndex]; - $values = []; - $placeholders = []; - $columnsToInsert = []; - - // Aggiungi i campi mappati dall'XLS (automatici) - foreach ($autoMappings as $mapping) { - $excelColumnIndex = array_search(trim($mapping['excel_column']), array_map('trim', $columns)); - if ($excelColumnIndex !== false) { - $mysqlColumn = $mapping['mysql_column']; - $value = $row[$excelColumnIndex] ?? $mapping['manual_default']; - - if ($mapping['is_required'] && (is_null($value) || $value === '')) { - $value = $mapping['manual_default']; - if (is_null($value)) { - header("Location: import_xls.php?id=$template_id&status=error&message=" . urlencode("Valore richiesto mancante per la colonna $mysqlColumn")); - exit; - } - } - - switch ($mapping['data_type']) { - case 'INT': - $value = is_numeric($value) ? (int)$value : ($mapping['manual_default'] ?? 0); - break; - case 'DATE': - $value = !empty($value) ? date('Y-m-d', strtotime($value)) : ($mapping['manual_default'] ?? null); - if ($mapping['manual_default'] === 'today' && is_null($value)) { - $value = date('Y-m-d'); - } - break; - case 'CHAR': - $value = !empty($value) ? substr($value, 0, 1) : ($mapping['manual_default'] ?? ''); - break; - case 'Testo': - case 'VARCHAR': - default: - $value = !empty($value) ? htmlspecialchars($value) : ($mapping['manual_default'] ?? ''); - break; - } - - if (!is_null($value)) { - $columnsToInsert[] = $mysqlColumn; - $placeholders[] = '?'; - $values[] = $value; - } - } - } - - // Aggiungi i campi generici - $columnsToInsert[] = 'importreferencecode'; - $placeholders[] = '?'; - $values[] = $importReferenceCode; - - $columnsToInsert[] = 'filename_import'; - $placeholders[] = '?'; - $values[] = $newFilename; - - $columnsToInsert[] = 'status'; - $placeholders[] = '?'; - $values[] = 'i'; - - $columnsToInsert[] = 'user_id'; - $placeholders[] = '?'; - $values[] = $user_id; - - $columnsToInsert[] = 'limscode'; - $placeholders[] = '?'; - $values[] = null; - - $columnsToInsert[] = 'importdate'; - $placeholders[] = '?'; - $values[] = date('Y-m-d'); - - $sql = "INSERT INTO datadb (" . implode(', ', $columnsToInsert) . ") VALUES (" . implode(', ', $placeholders) . ")"; - $stmt = $pdo->prepare($sql); - $stmt->execute($values); - - $iddatadb = $pdo->lastInsertId(); - $insertedIds[] = $iddatadb; - - // Inserisci tutti i campi (automatici e manuali) in import_data_details - foreach ($allMappings as $mapping) { - $fieldValue = ''; - if (!$mapping['is_manual']) { // Campi automatici dall'XLS - $excelColumnIndex = array_search(trim($mapping['excel_column']), array_map('trim', $columns)); - if ($excelColumnIndex !== false) { - $fieldValue = $row[$excelColumnIndex] ?? $mapping['manual_default']; - } else { - $fieldValue = $mapping['manual_default'] ?? ''; - } - switch ($mapping['data_type']) { - case 'INT': - $fieldValue = is_numeric($fieldValue) ? (int)$fieldValue : ($mapping['manual_default'] ?? 0); - break; - case 'DATE': - $fieldValue = !empty($fieldValue) ? date('Y-m-d', strtotime($fieldValue)) : ($mapping['manual_default'] ?? ''); - if ($mapping['manual_default'] === 'today' && empty($fieldValue)) { - $fieldValue = date('Y-m-d'); - } - break; - case 'CHAR': - $fieldValue = !empty($fieldValue) ? substr($fieldValue, 0, 1) : ($mapping['manual_default'] ?? ''); - break; - case 'Testo': - case 'VARCHAR': - default: - $fieldValue = !empty($fieldValue) ? htmlspecialchars($fieldValue) : ($mapping['manual_default'] ?? ''); - break; - } - } else { // Campi manuali - $fieldValue = $mapping['manual_default'] ?? ''; - if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') { - $fieldValue = date('Y-m-d'); - } elseif (!empty($mapping['manual_default'])) { - $fieldValue = $mapping['manual_default']; - } - } - // Log dettagliato prima dell'inserimento - error_log("Inserting - Mapping ID: " . $mapping['id'] . ", Field Value: " . var_export($fieldValue, true) . ", Is Manual: " . $mapping['is_manual'] . ", Excel Column: " . ($mapping['excel_column'] ?? 'N/A') . ", Manual Default: " . ($mapping['manual_default'] ?? 'N/A')); - - $stmt = $pdo->prepare("INSERT INTO import_data_details (id, mapping_id, field_value) VALUES (?, ?, ?)"); - $stmt->execute([$iddatadb, $mapping['id'], $fieldValue]); - // Log della query eseguita - error_log("Executed Query for ID $iddatadb, Mapping ID: " . $mapping['id'] . ", Field Value: " . $fieldValue); - } -} - -// Recupera i dati appena inseriti con i nomi degli utenti -$stmt = $pdo->prepare(" - SELECT d.*, CONCAT(u.first_name, ' ', u.last_name) AS user_name - FROM datadb d - LEFT JOIN auth_users u ON d.user_id = u.id - WHERE d.iddatadb IN (" . implode(',', array_fill(0, count($insertedIds), '?')) . ") -"); -$stmt->execute($insertedIds); -$importedData = $stmt->fetchAll(PDO::FETCH_ASSOC); - -// Recupera i dettagli manuali da import_data_details -$stmt = $pdo->prepare(" - SELECT d.id AS detail_id, d.id AS datadb_id, d.mapping_id, d.field_value, m.field_id, m.data_type, m.is_required, m.manual_default - FROM import_data_details d - JOIN template_mapping m ON d.mapping_id = m.id - WHERE d.id IN (" . implode(',', array_fill(0, count($insertedIds), '?')) . ") -"); -$stmt->execute($insertedIds); -$manualDetails = $stmt->fetchAll(PDO::FETCH_ASSOC); - -// Recupera il mapping globale per mostrare gli slug leggibili -$stmt = $pdo->query("SELECT mysql_column_name, user_friendly_slug FROM column_mapping"); -$slugMapping = []; -foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { - $slugMapping[$row['mysql_column_name']] = $row['user_friendly_slug']; -} -?> - - - - - - - - - - - - Edit Imported Data - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - -
    - - -
    -
    - -
    -
    -
    -
    -
    Modifica Dati Importati
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    "; - $headerIndex++; - } - } - // Aggiungi spazi vuoti per i campi automatici (senza propagate-btn) - foreach ($autoMappings as $autoMapping) { - echo "
    "; - $headerIndex++; - } - // Aggiungi gli input per i campi manuali con propagate-btn - foreach ($manualMappings as $manualMapping) { - $fieldValue = $manualMapping['manual_default']; - if ($manualMapping['data_type'] === 'DATE' && $manualMapping['manual_default'] === 'today') { - $fieldValue = date('Y-m-d'); - } - $requiredAttr = $manualMapping['is_required'] ? 'required' : ''; - echo "
    "; - if ($manualMapping['data_type'] === 'DATE') { - echo ""; - } elseif ($manualMapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo ""; - echo "
    "; - $headerIndex++; - } - // Spazi per AWB e Tracking Info - echo "
    "; - echo "
    "; - ?> -
    - - -
    -
    Save
    -
    Photos
    -
    Parts
    - $displayName
    "; - $headerIndex++; - } - } - // Prima i campi automatici (excel_column non vuoto) - foreach ($autoMappings as $mapping) { - echo "
    " . htmlspecialchars($mapping['field_label']) . "
    "; - $headerIndex++; - } - // Poi i campi manuali - foreach ($manualMappings as $mapping) { - echo "
    " . htmlspecialchars($mapping['field_label']) . "
    "; - $headerIndex++; - } - ?> -
    AWB Number
    -
    -
    Tracking Info
    -
    -
    - - - $row): ?> -
    -
    - -
    -
    - -
    -
    - -
    - "; - if ($col === 'importdate') { - echo "" . htmlspecialchars($value) . ""; - echo ""; - } elseif ($col === 'filename_import') { - echo "File"; - echo ""; - } elseif ($col === 'status') { - echo "" . htmlspecialchars($value === 'i' ? 'Imported' : ($value === 'P' ? 'Progress' : 'LIMS')) . ""; - echo ""; - } elseif ($col === 'user_id') { - echo "" . htmlspecialchars($row['user_name'] ?? 'Utente Sconosciuto') . ""; - echo ""; - } else { - echo ""; - } - echo "
    "; - $cellIndex++; - } - } - // Aggiungi i campi automatici da import_data_details - $rowDetails = array_filter($manualDetails, fn($d) => $d['datadb_id'] == $row['iddatadb']); - foreach ($autoMappings as $mapping) { - $detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']); - $detail = reset($detail) ?: ['field_value' => $mapping['manual_default']]; - $fieldValue = $detail['field_value'] ?? $mapping['manual_default']; - $requiredAttr = $mapping['is_required'] ? 'required' : ''; - echo "
    "; - if ($mapping['data_type'] === 'DATE') { - echo ""; - } elseif ($mapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo "
    "; - $cellIndex++; - } - // Aggiungi i campi manuali da import_data_details - foreach ($manualMappings as $mapping) { - $detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']); - $detail = reset($detail) ?: ['field_value' => $mapping['manual_default']]; - $fieldValue = $detail['field_value'] ?? $mapping['manual_default']; - if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today' && empty($fieldValue)) { - $fieldValue = date('Y-m-d'); - } - $requiredAttr = $mapping['is_required'] ? 'required' : ''; - echo "
    "; - if ($mapping['data_type'] === 'DATE') { - echo ""; - } elseif ($mapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo "
    "; - $cellIndex++; - } - ?> - -
    - - - -
    -
    - Shipment Info - -
    -
    - -
    - - - -
    -
    - - -
    - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/import_edit2.php b/public/userarea/import_edit2.php deleted file mode 100644 index e8544ab..0000000 --- a/public/userarea/import_edit2.php +++ /dev/null @@ -1,1606 +0,0 @@ -getConnection(); - -// Genera un UUID univoco per importreferencecode -$importReferenceCode = date('YmdHis') . '-' . uniqid(); - -// Recupera tutti i mapping dal template, includendo is_visible_import -$stmt = $pdo->prepare("SELECT id, excel_column, data_type, is_required, manual_default, is_manual, field_label, field_id, main_field, is_visible_import FROM template_mapping WHERE template_id = ?"); -$stmt->execute([$template_id]); -$allMappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - -if (empty($allMappings)) { - header("Location: import_xls.php?id=$template_id&status=error&message=" . urlencode("Nessun mapping trovato per il template")); - exit; -} - -// Trova il campo main_field -$mainFieldMapping = null; -foreach ($allMappings as $mapping) { - if ($mapping['main_field'] == 1 && $mapping['is_visible_import'] == 1) { - $mainFieldMapping = $mapping; - break; - } -} - -// Recupera l'idclient di default dal template (se presente) -$template_stmt = $pdo->prepare("SELECT idclient FROM excel_templates WHERE id = ?"); -$template_stmt->execute([$template_id]); -$template = $template_stmt->fetch(PDO::FETCH_ASSOC); -$default_idclient = $template['idclient'] ?? null; - -$insertedIds = $_POST['inserted_ids'] ?? $_SESSION['inserted_ids']; - -// Recupera i dati appena inseriti con i nomi degli utenti -$stmt = $pdo->prepare(" - SELECT d.*, CONCAT(u.first_name, ' ', u.last_name) AS user_name - FROM datadb d - LEFT JOIN auth_users u ON d.user_id = u.id - WHERE d.iddatadb IN (" . implode(',', array_fill(0, count($insertedIds), '?')) . ") -"); -$stmt->execute($insertedIds); -$importedData = $stmt->fetchAll(PDO::FETCH_ASSOC); - -// Recupera i dettagli manuali da import_data_details -$stmt = $pdo->prepare(" - SELECT d.id AS detail_id, d.id AS datadb_id, d.mapping_id, d.field_value, m.field_label, m.data_type, m.is_required, m.manual_default - FROM import_data_details d - JOIN template_mapping m ON d.mapping_id = m.id - WHERE d.id IN (" . implode(',', array_fill(0, count($insertedIds), '?')) . ") -"); -$stmt->execute($insertedIds); -$manualDetails = $stmt->fetchAll(PDO::FETCH_ASSOC); - -// Recupera il mapping globale per mostrare gli slug leggibili -$stmt = $pdo->query("SELECT mysql_column_name, user_friendly_slug FROM column_mapping"); -$slugMapping = []; -foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { - $slugMapping[$row['mysql_column_name']] = $row['user_friendly_slug']; -} -?> - - - - - - - - - - - - - - Edit Imported Data - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - -
    - - -
    -
    - -
    -
    -
    -
    -
    Modifica Dati Importati
    - -
    -
    -
    -
    -
    -
    -
    -
    - -
    - -
    - "; - echo ""; - echo ""; - echo ""; - } elseif ($mainFieldMapping['data_type'] === 'Data') { - echo ""; - echo ""; - } elseif ($mainFieldMapping['data_type'] === 'INT') { - echo ""; - echo ""; - } else { - echo ""; - echo ""; - } - ?> -
    - -
    - - - -
    -
    - "; - echo ""; - echo ""; - echo "
    "; - } else { - echo "
    "; - } - $autoIndex++; - } - } - $manualIndex = 0; - foreach ($allMappings as $mapping) { - if ($mapping['is_manual'] && $mapping['main_field'] != 1 && $mapping['is_visible_import'] == 1) { - $fieldValue = $mapping['manual_default'] ?? ''; - if ($mapping['data_type'] === 'Data' && $mapping['manual_default'] === 'today') { - $fieldValue = date('Y-m-d'); - } - $inputClass = 'manual-input'; - if ($mapping['is_required']) $inputClass .= ' required-input'; - echo "
    "; - if ($mapping['data_type'] === 'SceltaMultipla') { - echo ""; - } elseif ($mapping['data_type'] === 'Data') { - echo ""; - } elseif ($mapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo ""; - echo "
    "; - $manualIndex++; - } - } - // Aggiunta per Tested Component (senza propagate) - echo "
    "; - echo "
    "; - echo "
    "; - echo "
    "; - echo "
    "; - echo "
    "; - ?> -
    - -
    -
    Actions
    - -
    - -
    -
    - -
    Client
    -
    -
    Status
    -
    - " . htmlspecialchars($mapping['field_label']) . "
    "; - $headerIndex++; - } - } - foreach ($allMappings as $mapping) { - if ($mapping['is_manual'] && $mapping['main_field'] != 1 && $mapping['is_visible_import'] == 1) { - echo "
    " . htmlspecialchars($mapping['field_label']) . "
    "; - $headerIndex++; - } - } - // Aggiunta header per Tested Component - echo "
    Tested Component
    "; - $headerIndex++; - echo "
    AWB Number
    "; - $headerIndex++; - echo "
    Tracking Info
    "; - $headerIndex++; - echo "
    Import Reference Code
    "; - $headerIndex++; - echo "
    " . ($slugMapping['filename_import'] ?? 'filename_import') . "
    "; - $headerIndex++; - echo "
    " . ($slugMapping['importdate'] ?? 'importdate') . "
    "; - ?> -
    - - $row): ?> -
    -
    - - hasRole('Admin'))) : ?> - - - - - - -
    - - $d['mapping_id'] == $mainFieldMapping['id'] && $d['datadb_id'] == $row['iddatadb']); - $detail = reset($detail) ?: ['field_value' => $mainFieldMapping['manual_default']]; - $fieldValue = $detail['field_value'] ?? $mainFieldMapping['manual_default'] ?? ''; - if ($mainFieldMapping['data_type'] === 'Data' && $mainFieldMapping['manual_default'] === 'today' && empty($fieldValue)) { - $fieldValue = date('Y-m-d'); - } - $requiredClass = ($mainFieldMapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : ''; - $inputClass = $mainFieldMapping['is_manual'] ? 'manual-input' : 'auto-input'; - if ($mainFieldMapping['is_required']) $inputClass .= ' required-input'; - ?> -
    - - - - > - - > - - > - -
    - -
    - -
    -
    - - - - -
    - $d['datadb_id'] == $row['iddatadb']); - $autoIndex = 0; - foreach ($allMappings as $mapping) { - if (!$mapping['is_manual'] && $mapping['main_field'] != 1 && $mapping['is_visible_import'] == 1) { - $detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']); - $detail = reset($detail) ?: ['field_value' => $mapping['manual_default']]; - $fieldValue = $detail['field_value'] ?? $mapping['manual_default'] ?? ''; - $requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : ''; - $inputClass = 'auto-input'; - if ($mapping['is_required']) $inputClass .= ' required-input'; - echo "
    "; - if ($mapping['data_type'] === 'SceltaMultipla') { - echo ""; - } elseif ($mapping['data_type'] === 'Data') { - echo ""; - } elseif ($mapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo "
    "; - $cellIndex++; - $autoIndex++; - } - } - $manualIndex = 0; - foreach ($allMappings as $mapping) { - if ($mapping['is_manual'] && $mapping['main_field'] != 1 && $mapping['is_visible_import'] == 1) { - $detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']); - $detail = reset($detail) ?: ['field_value' => $mapping['manual_default']]; - $fieldValue = $detail['field_value'] ?? $mapping['manual_default'] ?? ''; - if ($mapping['data_type'] === 'Data' && $mapping['manual_default'] === 'today' && empty($fieldValue)) { - $fieldValue = date('Y-m-d'); - } - $requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : ''; - $inputClass = 'manual-input'; - if ($mapping['is_required']) $inputClass .= ' required-input'; - echo "
    "; - if ($mapping['data_type'] === 'SceltaMultipla') { - echo ""; - } elseif ($mapping['data_type'] === 'Data') { - echo ""; - } elseif ($mapping['data_type'] === 'INT') { - echo ""; - } else { - echo ""; - } - echo "
    "; - $cellIndex++; - $manualIndex++; - } - } - // Aggiunta cella per Tested Component - echo "
    "; - echo ""; - echo ""; - echo "
    "; - $cellIndex++; - ?> -
    - - - -
    -
    - Shipment Info - -
    -
    - - -
    - -
    - File - -
    - -
    - - -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/import_insert.php b/public/userarea/import_insert.php deleted file mode 100644 index 7f7cc0b..0000000 --- a/public/userarea/import_insert.php +++ /dev/null @@ -1,173 +0,0 @@ -getConnection(); - -// Genera un UUID univoco per importreferencecode -$importReferenceCode = date('YmdHis') . '-' . uniqid(); - -// Recupera tutti i mapping dal template -$stmt = $pdo->prepare("SELECT id, excel_column, data_type, is_required, manual_default, is_manual, field_label, field_id, main_field FROM template_mapping WHERE template_id = ?"); -$stmt->execute([$template_id]); -$allMappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - -if (empty($allMappings)) { - header("Location: import_xls.php?id=$template_id&status=error&message=" . urlencode("Nessun mapping trovato per il template")); - exit; -} - -// Trova il campo main_field -$mainFieldMapping = null; -foreach ($allMappings as $mapping) { - if ($mapping['main_field'] == 1) { - $mainFieldMapping = $mapping; - break; - } -} - -// Inserisci le righe selezionate in datadb -$insertedIds = []; -foreach ($selected_rows as $rowIndex) { - $row = $rows[$rowIndex] ?? null; - $excelrow = $excelrows[$rowIndex] ?? null; - - if ($row === null || $excelrow === null) { - error_log("Errore: riga o excelrow mancante per rowIndex $rowIndex"); - continue; - } - - // Recupera l'idclient di default dal template - $template_stmt = $pdo->prepare("SELECT idclient FROM excel_templates WHERE id = ?"); - $template_stmt->execute([$template_id]); - $template = $template_stmt->fetch(PDO::FETCH_ASSOC); - $default_idclient = $template['idclient'] ?? null; - - $values = [ - $template_id, - $importReferenceCode, - $newFilename, - 'i', - $user_id, - null, - date('Y-m-d'), - $excelrow, - $default_idclient // Aggiungi idclient - ]; - $sql = "INSERT INTO datadb (templateid, importreferencecode, filename_import, status, user_id, limscode, importdate, excelrow, idclient) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; - $stmt = $pdo->prepare($sql); - $stmt->execute($values); - - $iddatadb = $pdo->lastInsertId(); - $insertedIds[] = $iddatadb; - - // Inserisci tutti i campi in import_data_details - foreach ($allMappings as $mapping) { - $fieldValue = null; - if (!$mapping['is_manual']) { - $excelColumn = trim($mapping['excel_column']); - $excelColumnIndex = array_search($excelColumn, array_map('trim', $columns)); - if ($excelColumnIndex !== false && isset($row[$excelColumnIndex]) && $row[$excelColumnIndex] !== '') { - $fieldValue = $row[$excelColumnIndex]; - error_log("Found Excel column '$excelColumn' at index $excelColumnIndex, value: " . var_export($fieldValue, true)); - } else { - $fieldValue = $mapping['manual_default'] ?? ''; - error_log("Excel column '$excelColumn' not found or empty, using default: " . var_export($fieldValue, true)); - } - switch ($mapping['data_type']) { - case 'INT': - $fieldValue = is_numeric($fieldValue) ? (int)$fieldValue : ($mapping['manual_default'] ?? 0); - break; - case 'DATE': - $fieldValue = !empty($fieldValue) ? date('Y-m-d', strtotime($fieldValue)) : ($mapping['manual_default'] === 'today' ? date('Y-m-d') : ($mapping['manual_default'] ?? '')); - break; - case 'CHAR': - $fieldValue = !empty($fieldValue) ? substr((string)$fieldValue, 0, 1) : ($mapping['manual_default'] ?? ''); - break; - case 'Testo': - case 'VARCHAR': - default: - $fieldValue = !empty($fieldValue) ? htmlspecialchars((string)$fieldValue) : ($mapping['manual_default'] ?? ''); - break; - } - } else { - $fieldValue = $mapping['manual_default'] ?? ''; - if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') { - $fieldValue = date('Y-m-d'); - } - } - if ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) { - error_log("Required field missing for mapping ID: " . $mapping['id'] . ", field: " . $mapping['field_label']); - } - error_log("Inserting into import_data_details - Mapping ID: " . $mapping['id'] . ", Field Value: " . var_export($fieldValue, true) . ", Is Manual: " . $mapping['is_manual'] . ", Excel Column: " . ($mapping['excel_column'] ?? 'N/A') . ", Manual Default: " . ($mapping['manual_default'] ?? 'N/A')); - $stmt = $pdo->prepare("INSERT INTO import_data_details (id, mapping_id, field_value) VALUES (?, ?, ?)"); - $stmt->execute([$iddatadb, $mapping['id'], $fieldValue]); - error_log("Inserted into import_data_details for ID $iddatadb, Mapping ID: " . $mapping['id'] . ", Field Value: " . var_export($fieldValue, true)); - } -} - -$_SESSION['inserted_ids'] = $insertedIds; - -$params = [ - 'template_id' => $template_id, - 'filename' => $newFilename, -]; - -?> -
    - - - - - - - - - - - -
    - - \ No newline at end of file diff --git a/public/userarea/import_list.php b/public/userarea/import_list.php new file mode 100644 index 0000000..8b3b4e6 --- /dev/null +++ b/public/userarea/import_list.php @@ -0,0 +1,412 @@ +getConnection(); +?> + + + + + + + Imported Data Management + + + + + + + + + +
    + + +
    +
    +
    +
    +

    Imported Data

    +
    + + +
    +
    +
    +
    + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + +
    IDCollectionCategoryModelModel DescriptionMod.CodeDescriptionFinish.CodeFinishing DescriptionAvailable QtyWHPriceActions
    +
    +
    +
    +
    + + +
    + + + + + + + + + \ No newline at end of file diff --git a/public/userarea/import_list_data.php b/public/userarea/import_list_data.php new file mode 100644 index 0000000..c423aac --- /dev/null +++ b/public/userarea/import_list_data.php @@ -0,0 +1,21 @@ +getConnection(); + +$idclient = isset($_GET['idclient']) && is_numeric($_GET['idclient']) ? intval($_GET['idclient']) : null; + +try { + if ($idclient) { + $stmt = $pdo->prepare("SELECT * FROM importdb WHERE idclient = :idclient ORDER BY id DESC"); + $stmt->execute([':idclient' => $idclient]); + } else { + $stmt = $pdo->query("SELECT * FROM importdb ORDER BY id DESC"); + } + echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)); +} catch (Exception $e) { + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} diff --git a/public/userarea/import_list_delete.php b/public/userarea/import_list_delete.php new file mode 100644 index 0000000..e250779 --- /dev/null +++ b/public/userarea/import_list_delete.php @@ -0,0 +1,20 @@ +getConnection(); + +$id = intval($_POST['id'] ?? 0); +if ($id <= 0) { + echo json_encode(['status' => 'error', 'message' => 'Invalid ID']); + exit; +} + +try { + $stmt = $pdo->prepare("DELETE FROM importdb WHERE id = :id"); + $stmt->execute([':id' => $id]); + echo json_encode(['status' => 'ok']); +} catch (Exception $e) { + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} diff --git a/public/userarea/import_list_save.php b/public/userarea/import_list_save.php new file mode 100644 index 0000000..a3c0529 --- /dev/null +++ b/public/userarea/import_list_save.php @@ -0,0 +1,47 @@ +getConnection(); + +$row = json_decode($_POST['row'] ?? '', true); +if (!$row || !isset($row['id'])) { + echo json_encode(['status' => 'error', 'message' => 'Invalid data']); + exit; +} + +try { + $sql = "UPDATE importdb SET + collection = :collection, + category = :category, + model = :model, + model_description = :model_description, + description = :description, + finish_code = :finish_code, + finishing_description = :finishing_description, + available_qty = :available_qty, + wh = :wh, + price = :price, + updated_on = CURRENT_TIMESTAMP + WHERE id = :id"; + + $stmt = $pdo->prepare($sql); + $stmt->execute([ + ':collection' => $row['collection'] ?? null, + ':category' => $row['category'] ?? null, + ':model' => $row['model'] ?? null, + ':model_description' => $row['model_description'] ?? null, + ':description' => $row['description'] ?? null, + ':finish_code' => $row['finish_code'] ?? null, + ':finishing_description' => $row['finishing_description'] ?? null, + ':available_qty' => $row['available_qty'] ?? null, + ':wh' => $row['wh'] ?? null, + ':price' => $row['price'] ?? null, + ':id' => $row['id'] + ]); + + echo json_encode(['status' => 'ok']); +} catch (Exception $e) { + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} diff --git a/public/userarea/import_prices_pdf.php b/public/userarea/import_prices_pdf.php new file mode 100644 index 0000000..6b5c204 --- /dev/null +++ b/public/userarea/import_prices_pdf.php @@ -0,0 +1,200 @@ +getConnection(); + +// --- Carica clienti --- +$clients = $pdo->query("SELECT idclient, client_name FROM clients ORDER BY client_name")->fetchAll(PDO::FETCH_ASSOC); + +// --- Messaggio di stato --- +$message = ''; + +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['price_pdf'])) { + $idclient = intval($_POST['idclient'] ?? 0); + + if ($idclient > 0 && $_FILES['price_pdf']['error'] === UPLOAD_ERR_OK) { + $uploadDir = __DIR__ . '/uploads/'; + if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true); + + $filename = basename($_FILES['price_pdf']['name']); + $targetPath = $uploadDir . $filename; + + if (move_uploaded_file($_FILES['price_pdf']['tmp_name'], $targetPath)) { + try { + require_once(dirname(__DIR__, 2) . '/vendor/autoload.php'); + $parser = new Parser(); + $pdf = $parser->parseFile($targetPath); + $text = $pdf->getText(); + + // Salva testo completo per analisi + file_put_contents(__DIR__ . '/debug_pdf_text.txt', $text); + + // Pattern iniziale: "499 1C 23 €123,45" o "499 1C 23 123,45" + $pattern = '/(\d{3})\s([A-Z0-9]{1,2})\s(\d{2})\s*[€]?\s?(\d{1,4},\d{2})/'; + + preg_match_all($pattern, $text, $matches, PREG_SET_ORDER); + + // Salva tutti i match trovati + $debugMatches = "Matches found: " . count($matches) . "\n\n"; + foreach ($matches as $m) { + $debugMatches .= implode(' | ', $m) . "\n"; + } + file_put_contents(__DIR__ . '/debug_matches.txt', $debugMatches); + + $inserted = 0; + + $stmt = $pdo->prepare(" + INSERT INTO price_mapping (idclient, price_ref, price, source_file) + VALUES (:idclient, :price_ref, :price, :source_file) + "); + + foreach ($matches as $m) { + $ref = trim($m[1] . $m[2] . $m[3]); + $price = str_replace(',', '.', $m[4]); + $stmt->execute([ + ':idclient' => $idclient, + ':price_ref' => $ref, + ':price' => $price, + ':source_file' => $filename + ]); + $inserted++; + } + + $message = "
    ✅ Imported $inserted prices successfully.
    "; + } catch (Exception $e) { + $message = "
    Error parsing PDF: " . htmlspecialchars($e->getMessage()) . "
    "; + } + } else { + $message = "
    Upload failed.
    "; + } + } else { + $message = "
    Select a client and upload a valid PDF file.
    "; + } +} +?> + + + + + + + Import PDF Prices + + + + + + + +
    + + +
    +
    +
    +

    📄 Import Price List from PDF

    + +
    +
    + + +
    + +
    + + +
    + +
    + +
    +
    + + + +
    + +
    📊 Imported Prices
    +
    + + + + + + + + + + + +
    IDClientCode RefPrice (€)Source FileCreated At
    +
    + +
    +
    +
    + + +
    + + + + + + + + + \ No newline at end of file diff --git a/public/userarea/import_save.php b/public/userarea/import_save.php new file mode 100644 index 0000000..d281a12 --- /dev/null +++ b/public/userarea/import_save.php @@ -0,0 +1,76 @@ +getConnection(); + +// Ottieni dati dal POST +$rows = isset($_POST['rows']) ? json_decode($_POST['rows'], true) : []; +$idclient = isset($_POST['idclient']) ? intval($_POST['idclient']) : null; + +// Recupera utente loggato +$iduser = $_SESSION['iduserlogin'] ?? null; + +if (!$rows || !is_array($rows) || count($rows) === 0) { + echo json_encode(['status' => 'error', 'message' => 'No rows to import.']); + exit; +} + +if (empty($idclient)) { + echo json_encode(['status' => 'error', 'message' => 'Client not specified.']); + exit; +} + +try { + $pdo->beginTransaction(); + + $sql = " + INSERT INTO importdb + (collection, category, model, model_description, mod_code, description, finish_code, finishing_description, available_qty, wh, price, source_file, iduser, idclient) + VALUES + (:collection, :category, :model, :model_description, :mod_code, :description, :finish_code, :finishing_description, :available_qty, :wh, :price, :source_file, :iduser, :idclient) + ON DUPLICATE KEY UPDATE + collection = VALUES(collection), + category = VALUES(category), + model = VALUES(model), + model_description = VALUES(model_description), + description = VALUES(description), + finish_code = VALUES(finish_code), + finishing_description = VALUES(finishing_description), + available_qty = VALUES(available_qty), + wh = VALUES(wh), + price = VALUES(price), + updated_on = CURRENT_TIMESTAMP() + "; + + $stmt = $pdo->prepare($sql); + + foreach ($rows as $r) { + if (isset($r['avalable_qty']) && !isset($r['available_qty'])) { + $r['available_qty'] = $r['avalable_qty']; + } + $stmt->execute([ + ':collection' => $r['collection'] ?? null, + ':category' => $r['category'] ?? null, + ':model' => $r['model'] ?? null, + ':model_description' => $r['model_description'] ?? null, + ':mod_code' => $r['mod_code'] ?? null, + ':description' => $r['description'] ?? null, + ':finish_code' => $r['finish_code'] ?? null, + ':finishing_description' => $r['finishing_description'] ?? null, + ':available_qty' => is_numeric($r['available_qty']) ? intval($r['available_qty']) : null, + ':wh' => $r['wh'] ?? null, + ':price' => isset($r['price']) && is_numeric($r['price']) ? floatval($r['price']) : null, + ':source_file' => basename($_POST['source_file'] ?? 'upload.xlsx'), + ':iduser' => $iduser, + ':idclient' => $idclient + ]); + } + + $pdo->commit(); + echo json_encode(['status' => 'ok', 'message' => count($rows) . ' rows imported/updated.']); +} catch (Exception $e) { + $pdo->rollBack(); + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} diff --git a/public/userarea/import_xls.php b/public/userarea/import_xls.php index 6011827..0eb08b8 100644 --- a/public/userarea/import_xls.php +++ b/public/userarea/import_xls.php @@ -1,303 +1,258 @@ getConnection(); -$stmt = $pdo->prepare("SELECT * FROM excel_templates WHERE id = ?"); -$stmt->execute([$id]); -$template = $stmt->fetch(PDO::FETCH_ASSOC); -if (!$template) { - header("Location: template_dashboard.php?status=error&message=" . urlencode("Template not found")); - exit; -} - -// Debug del template -error_log("Loaded template: " . print_r($template, true)); +// Recupera lista clienti +$clients = $pdo->query("SELECT idclient, client_name FROM clients ORDER BY client_name")->fetchAll(PDO::FETCH_ASSOC); ?> - - + - - - + + + Import XLS - Cassina Products + + + - <?= htmlspecialchars($template['name']) ?> - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> -
    - + +
    -
    -
    - -
    -
    -
    -
    -
    - Template ID: , Start Row: , Start Column: +
    +
    +
    +

    Import Excel File

    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    -
    -
    - - -
    - - -
    - -
    - + - - +
    - -
    + +
    +
    + + +
    + + + + +
    + +
    - -
    - +
    - - - - - - - - + + + + diff --git a/public/userarea/import_xls2.php b/public/userarea/import_xls2.php deleted file mode 100644 index e1e3b40..0000000 --- a/public/userarea/import_xls2.php +++ /dev/null @@ -1,413 +0,0 @@ -getConnection(); -$stmt = $pdo->prepare("SELECT * FROM excel_templates WHERE id = ?"); -$stmt->execute([$id]); -$template = $stmt->fetch(PDO::FETCH_ASSOC); - -if (!$template) { - header("Location: template_dashboard.php?status=error&message=" . urlencode("Template not found")); - exit; -} - -// Verifica i mapping -$stmt = $pdo->prepare("SELECT id FROM template_mapping WHERE template_id = ?"); -$stmt->execute([$id]); -$hasMappings = $stmt->fetch(PDO::FETCH_ASSOC); - -// Debug del template -error_log("Loaded template: " . print_r($template, true)); -?> - - - - - - - - - - - - <?= htmlspecialchars($template['name']) ?> - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - -
    - - -
    -
    - - -
    -
    -
    -
    -
    - Template ID: , Start Row: , Start Column: -
    -
    -
    -
    - - - -
    -
    - - -
    - -
    -
    - - - -
    - - -
    -
    -
    -
    -
    - - -
    - - - - - - - - \ No newline at end of file diff --git a/public/userarea/import_xls_process.php b/public/userarea/import_xls_process.php new file mode 100644 index 0000000..b5f7d04 --- /dev/null +++ b/public/userarea/import_xls_process.php @@ -0,0 +1,63 @@ + 'error', 'message' => 'No file uploaded.']); + exit; + } + + try { + $spreadsheet = IOFactory::load($fileTmp); + $sheet = $spreadsheet->getActiveSheet(); + $data = $sheet->toArray(null, true, true, true); + + // Normalize headers + $headers = $data[$headerRow + 1]; + $normalizedHeaders = []; + foreach ($headers as $k => $v) { + $key = strtolower(trim($v)); + $key = str_replace([' ', '.', '-', '/'], '_', $key); + $normalizedHeaders[$k] = $key; + } + + // Build data array + $rows = array_slice($data, $headerRow + 1); + $array = []; + foreach ($rows as $row) { + $item = []; + foreach ($normalizedHeaders as $k => $key) { + $item[$key] = trim($row[$k]); + } + $array[] = $item; + } + + // Extract categories + $categories = []; + foreach ($array as $row) { + if (!empty($row['category'])) { + $cat = trim($row['category']); + if ($cat !== '' && !in_array($cat, $categories)) { + $categories[] = $cat; + } + } + } + sort($categories); + + echo json_encode([ + 'status' => 'ok', + 'columns' => array_keys($array[0] ?? []), + 'categories' => $categories, + 'data' => $array + ]); + } catch (Exception $e) { + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); + } +} diff --git a/public/userarea/insert_template_xls.php b/public/userarea/insert_template_xls.php deleted file mode 100644 index 71b1a2e..0000000 --- a/public/userarea/insert_template_xls.php +++ /dev/null @@ -1,396 +0,0 @@ -getConnection(); -$stmt = $pdo->prepare("SELECT * FROM routine"); -$stmt->execute(); -$routines = $stmt->fetchAll(PDO::FETCH_ASSOC); -?> - - - - - - - - - - - - Insert XLS Template <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - -
    - - -
    -
    -
    -
    -
    Insert new XLS Template
    -
    -
    -

    Fill the following form in order to create a new import XLS template

    -

    Mandatory Fields

    -
      -
    • Template Name
    • -
    • Row Header and Column Header: where the title of the excel starts
    • -
    • Schema and client
    • -
    -
    -
    - -
    -
    -
    -
    -
    Fill the form and click "Create Template"
    -
    -
    -
    -
    -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - - - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - - -
    - -
    - - - -
    - -
    - - - -
    - -
    - - Cancel -
    -
    -
    -
    -
    -
    -
    - - -
    - - - - - \ No newline at end of file diff --git a/public/userarea/insert_template_xlsbck.php b/public/userarea/insert_template_xlsbck.php deleted file mode 100644 index d03cdb0..0000000 --- a/public/userarea/insert_template_xlsbck.php +++ /dev/null @@ -1,411 +0,0 @@ - - - - - - - - - - - - Insert XLS Template <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - - -
    - - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -

    Total Orders

    -

    4805

    -

    +2.5% from last week

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Total Revenue

    -

    $84,245

    -

    +5.4% from last week

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Bounce Rate

    -

    34.6%

    -

    -4.5% from last week

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Total Customers

    -

    8.4K

    -

    +8.4% from last week

    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    Insert New XLS Template
    -
    -
    -
    -
    -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - -
    - -
    -
    -
    - -
    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    - -
    - - Cancel -
    -
    -
    -
    - -
    -
    - - -
    - - - - - -
    - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/json_example_bv.txt b/public/userarea/json_example_bv.txt deleted file mode 100644 index f62fe44..0000000 --- a/public/userarea/json_example_bv.txt +++ /dev/null @@ -1,13340 +0,0 @@ -{ - "@odata.context": "https:\/\/93.43.5.102\/limsapi\/api\/odata\/$metadata#Rapporto(CampioniDatiRapporto(AnalisiDatiRapporto(),CustomFieldsDatiRapporto()))\/$entity", - "IdRapporto": 515081, - "DataUltimaModifica": "2025-05-14T18:11:21.02+02:00", - "DaLeggere": false, - "CodiceRapporto": "2523026", - "Data": "2025-05-14T14:05:30+02:00", - "Versione": 0, - "DataStampa": "2025-05-14T14:11:00+02:00", - "Firmato": true, - "CampioniDatiRapporto": [ - { - "IdCampioneDatiRapporto": 651935, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.04", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28370998, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28370999, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28370994, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28370996, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28371001, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28371000, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28370995, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28371025, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371007, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371010, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371015, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371019, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371018, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371023, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371020, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371004, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371013, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371016, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371027, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371017, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371024, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371005, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371008, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371009, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371022, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371021, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371026, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371014, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371012, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371011, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371006, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28370992, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO\/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:21+02:00", - "FineAnalisi": "2025-05-13T10:19:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28371002, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Dimethylfumarate (DMFu)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Test method to quantitatively determine Dimethylfumarate (DMFu) in footwear materials\r\n- Test Method:\r\nISO 16186: 2021", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,05", - "LimiteQuantificazione": "0,05", - "LimitiDiLegge": "<=0,1", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-12T10:07:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16186_DMFu_Da caricare su 2 MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=0,1" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925192, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925193, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925194, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925195, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925196, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925197, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925198, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925199, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925200, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925201, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925205, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925206, - "Titolo": "Tested Component:", - "Valore": "MIX LACES + TEXTILE TONGUE", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925207, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925208, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925209, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925210, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925211, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925224, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925225, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925235, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925236, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925237, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925238, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925239, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925240, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925244, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925245, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651912, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": 810, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-12T00:00:00+02:00", - "CodiceCampione": "2523026.01", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28332143, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332144, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332139, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332141, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332146, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332145, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332140, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332147, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO\/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:15+02:00", - "FineAnalisi": "2025-05-12T10:42:41+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27924018, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27924019, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27924020, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27924021, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27924022, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27924023, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27924024, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27924025, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27924026, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27924027, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27924031, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27924032, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN PART OF SOLE, WHITE PART OF SOLE AND WHITE OUTERSOLE", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27924033, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27924034, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27924035, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27924036, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27924037, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27924050, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27924051, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27924061, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27924062, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27924063, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27924064, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27924065, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27924066, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27924070, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27924071, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651931, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-12T00:00:00+02:00", - "CodiceCampione": "2523026.02", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28332665, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332666, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332661, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332663, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332668, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332667, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332662, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332669, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO\/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:17+02:00", - "FineAnalisi": "2025-05-12T10:44:02+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27924985, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27924986, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27924987, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27924988, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27924989, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27924990, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27924991, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27924992, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27924993, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27924994, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27924998, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27924999, - "Titolo": "Tested Component:", - "Valore": "MIX OF BLACK PART OF SOLE, CARBON FIBER AND WHITE BACK PART OF SOLE", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925000, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925001, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925002, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925003, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925004, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925017, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925018, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925028, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925029, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925030, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925031, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925032, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925033, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925037, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925038, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651933, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.03", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28332698, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332699, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332697, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332703, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332701, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332700, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332702, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332738, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO\/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-13T10:36:34+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925096, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925097, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925098, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925099, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925100, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925101, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925102, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925103, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925104, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925105, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925109, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925110, - "Titolo": "Tested Component:", - "Valore": "YELLOW VIBRAM LOGO ON SOLE", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925111, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925112, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925113, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925114, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925115, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925128, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925129, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925139, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925140, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925141, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925142, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925143, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925144, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925148, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925149, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651939, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.06", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333037, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333032, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333031, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333053, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333033, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333051, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333035, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333030, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333040, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333048, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333046, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333039, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333047, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333036, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333042, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333043, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333044, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333034, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333049, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333029, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333052, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333045, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333038, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333050, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333058, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333059, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333054, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333056, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333061, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333060, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333055, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333062, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO\/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:26+02:00", - "FineAnalisi": "2025-05-12T14:07:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333064, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Dimethylfumarate (DMFu)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Test method to quantitatively determine Dimethylfumarate (DMFu) in footwear materials\r\n- Test Method:\r\nISO 16186: 2021", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,05", - "LimiteQuantificazione": "0,05", - "LimitiDiLegge": "<=0,1", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:28+02:00", - "FineAnalisi": "2025-05-12T10:07:20+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16186_DMFu_Da caricare su 2 MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=0,1" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925414, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925415, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925416, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925417, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925418, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925419, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925420, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925421, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925422, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925423, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925427, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925428, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN SUEDE UPPER AND GREEN TOE CAP", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925429, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925430, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925431, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925432, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925433, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925446, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925447, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925457, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925458, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925459, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925460, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925461, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925462, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925466, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925467, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651942, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-14T00:00:00+02:00", - "CodiceCampione": "2523026.07", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333247, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Chromium [Cr VI]", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Chemical determination of chromium (VI) content in leather - Part 2: Chromatographic method\r\n-Test Method:\r\nISO 17075-2: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Inorg", - "Reparto": "Analytical_Inorganic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "3,0", - "LimiteQuantificazione": "3,0", - "LimitiDiLegge": "<=3", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "CrVI", - "CommentoFisso": "The official method establishes the quantification limit for Chromium VI at 3 mg \/ kg. At this concentration, the uncertainty of the method was estimated to be 50%.\r\nFor this reason, any number below 3 mg\/kg could be affected by an uncertainty equal to or greater than that estimated at the quantification limit declared by the method.\r\nThe laboratory has performed the calculation of the recovery, as required by the method, and makes available the result if required.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-14T12:29:33+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17075-2_Cr VI_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": "<=3" - }, - { - "IdAnalisiDatoRapporto": 28333248, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Volatile Matter", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "%", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of volatile matter\r\n- Test Method:\r\nISO 4684: 2005", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Inorg", - "Reparto": "Analytical_Inorganic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "9,5", - "RisultatoPositivo": true, - "MinimoRilevabile": "0,5", - "LimiteQuantificazione": "0,5", - "LimitiDiLegge": null, - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "\u00b10,3", - "IncertezzaStampaNumerica": 0.3, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "4684", - "CommentoFisso": "The execution of the test is needed to express some chemical tests. This parameter is not limited by legislations and Pass or Fail is indicated only when a requirement is showed in Customer's documents (ref to Requirements section Denomination).", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:30+02:00", - "FineAnalisi": "2025-05-13T09:58:58+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "9,5", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17075-2_Cr VI_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": null - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925569, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925570, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925571, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925572, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925573, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925574, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925575, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925576, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925577, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925578, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925582, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925583, - "Titolo": "Tested Component:", - "Valore": "GREEN SUEDE UPPER", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925584, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925585, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925586, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925587, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925588, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925601, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925602, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925612, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925613, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925614, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925615, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925616, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925617, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925621, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925622, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651938, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.05", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28332958, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332940, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332943, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332948, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332952, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332951, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332956, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332953, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332937, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332946, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332949, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332960, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332950, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332957, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332938, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332941, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332942, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332955, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332954, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332959, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332947, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332945, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332944, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332939, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332966, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332967, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332962, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332964, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332969, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332968, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332963, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332970, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO\/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:24+02:00", - "FineAnalisi": "2025-05-13T12:43:52+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332972, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Dimethylfumarate (DMFu)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Test method to quantitatively determine Dimethylfumarate (DMFu) in footwear materials\r\n- Test Method:\r\nISO 16186: 2021", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,05", - "LimiteQuantificazione": "0,05", - "LimitiDiLegge": "<=0,1", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:07:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16186_DMFu_Da caricare su 2 MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=0,1" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925360, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925361, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925362, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925363, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925364, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925365, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925366, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925367, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925368, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925369, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925373, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925374, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN LATERAL BAND AND GREEN UPPER BAND", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925375, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925376, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925377, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925378, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925379, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925392, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925393, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925403, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925404, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925405, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925406, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925407, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925408, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925412, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925413, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651943, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-14T00:00:00+02:00", - "CodiceCampione": "2523026.08", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333249, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Chromium [Cr VI]", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Chemical determination of chromium (VI) content in leather - Part 2: Chromatographic method\r\n-Test Method:\r\nISO 17075-2: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Inorg", - "Reparto": "Analytical_Inorganic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "3,0", - "LimiteQuantificazione": "3,0", - "LimitiDiLegge": "<=3", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "CrVI", - "CommentoFisso": "The official method establishes the quantification limit for Chromium VI at 3 mg \/ kg. At this concentration, the uncertainty of the method was estimated to be 50%.\r\nFor this reason, any number below 3 mg\/kg could be affected by an uncertainty equal to or greater than that estimated at the quantification limit declared by the method.\r\nThe laboratory has performed the calculation of the recovery, as required by the method, and makes available the result if required.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:31+02:00", - "FineAnalisi": "2025-05-14T12:29:29+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17075-2_Cr VI_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": "<=3" - }, - { - "IdAnalisiDatoRapporto": 28333250, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Volatile Matter", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "%", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of volatile matter\r\n- Test Method:\r\nISO 4684: 2005", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Inorg", - "Reparto": "Analytical_Inorganic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "9,7", - "RisultatoPositivo": true, - "MinimoRilevabile": "0,5", - "LimiteQuantificazione": "0,5", - "LimitiDiLegge": null, - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "\u00b10,3", - "IncertezzaStampaNumerica": 0.3, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "4684", - "CommentoFisso": "The execution of the test is needed to express some chemical tests. This parameter is not limited by legislations and Pass or Fail is indicated only when a requirement is showed in Customer's documents (ref to Requirements section Denomination).", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:32+02:00", - "FineAnalisi": "2025-05-13T09:58:58+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "9,7", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17075-2_Cr VI_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": null - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925623, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925624, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925625, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925626, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925627, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925628, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925629, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925630, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925631, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925632, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925636, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925637, - "Titolo": "Tested Component:", - "Valore": "GREEN TOE CAP", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925638, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925639, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925640, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925641, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925642, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925655, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925656, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925666, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925667, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925668, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925669, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925670, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925671, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925675, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925676, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651945, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.09", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333072, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333073, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333068, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333070, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333075, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333074, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333069, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333076, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO\/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:32+02:00", - "FineAnalisi": "2025-05-13T10:36:34+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925736, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925737, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925738, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925739, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925740, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925741, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925742, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925743, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925744, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925745, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925749, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925750, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN EYELET AND PLASTIC END OF LACES", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925751, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925752, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925753, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925754, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925755, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925768, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925769, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925779, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925780, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925781, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925782, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925783, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925784, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925788, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925789, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651946, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.10", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333099, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333081, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333084, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333089, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333093, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333092, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333097, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333094, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333078, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333087, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333090, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333101, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333091, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333098, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333079, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333082, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333083, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333096, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333095, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333100, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333088, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333086, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333085, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333080, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925790, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925791, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925792, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925793, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925794, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925795, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925796, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925797, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925798, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925799, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925803, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925804, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN LOOP OF LACES AND BACK LITLLE FLAG LABEL", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925805, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925806, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925807, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925808, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925809, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925822, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925823, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925833, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925834, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925835, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925836, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925837, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925838, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925842, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925843, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651947, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.11", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333118, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333113, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333112, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333134, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and\/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333114, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333132, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333116, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333111, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333121, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333129, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333127, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333120, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333128, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333117, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333123, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333124, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333125, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333115, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333130, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333110, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333133, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333126, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333119, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333131, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333171, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333172, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333167, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333169, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333174, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333173, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333168, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333175, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO\/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:35+02:00", - "FineAnalisi": "2025-05-13T10:36:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333177, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Dimethylfumarate (DMFu)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Test method to quantitatively determine Dimethylfumarate (DMFu) in footwear materials\r\n- Test Method:\r\nISO 16186: 2021", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,05", - "LimiteQuantificazione": "0,05", - "LimitiDiLegge": "<=0,1", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:35+02:00", - "FineAnalisi": "2025-05-12T10:07:20+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16186_DMFu_Da caricare su 2 MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=0,1" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925844, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925845, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925846, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925847, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925848, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925849, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925850, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925851, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925852, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925853, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925857, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925858, - "Titolo": "Tested Component:", - "Valore": "MIX OF INSOLE AND LINING", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925859, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925860, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925861, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925862, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925863, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925876, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925877, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925887, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925888, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925889, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925890, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925891, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925892, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925896, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925897, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 652180, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed \/\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes\/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-12T00:00:00+02:00", - "CodiceCampione": "2523026.12", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28343776, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343777, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343775, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343781, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343779, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343778, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343780, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg\/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27938052, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27938053, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27938054, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27938055, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27938056, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27938057, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27938058, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27938059, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27938060, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27938061, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27938065, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27938066, - "Titolo": "Tested Component:", - "Valore": "N\u00b0 38 INNER LABEL", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27938067, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27938068, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27938069, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27938070, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27938071, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27938084, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27938085, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27938095, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27938096, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27938097, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27938098, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27938099, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27938100, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27938104, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27938105, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - } - ] -} \ No newline at end of file diff --git a/public/userarea/load_active_templates.php b/public/userarea/load_active_templates.php deleted file mode 100644 index b0d9fb7..0000000 --- a/public/userarea/load_active_templates.php +++ /dev/null @@ -1,27 +0,0 @@ - false, "data" => [], "message" => ""]; - -try { - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - if (!$pdo) { - throw new Exception('Database connection failed.'); - } - - // Recupera solo i template attivi - $stmt = $pdo->query("SELECT id, button_label, button_bg_color, button_text_color, button_size FROM excel_templates WHERE status = 'active'"); - $templates = $stmt->fetchAll(PDO::FETCH_ASSOC); - - $response["success"] = true; - $response["data"] = $templates; -} catch (PDOException $e) { - $response["message"] = "Database error: " . $e->getMessage(); -} catch (Exception $e) { - $response["message"] = "Error: " . $e->getMessage(); -} - -echo json_encode($response); diff --git a/public/userarea/load_existing_mappings.php b/public/userarea/load_existing_mappings.php deleted file mode 100644 index 14d0bac..0000000 --- a/public/userarea/load_existing_mappings.php +++ /dev/null @@ -1,60 +0,0 @@ - false, "message" => "Invalid template ID"]); - exit; -} - -$template_id = intval($_GET['template_id']); - -try { - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - // 1️⃣ Recuperiamo il nome della tabella target da `excel_templates` - $stmt = $pdo->prepare("SELECT target_table FROM excel_templates WHERE id = ?"); - $stmt->execute([$template_id]); - $template = $stmt->fetch(PDO::FETCH_ASSOC); - - if (!$template || empty($template['target_table'])) { - echo json_encode(["success" => false, "message" => "Template not found or missing target table"]); - exit; - } - - $target_table = $template['target_table']; - - // 2️⃣ Recuperiamo le associazioni già esistenti per il template_id - $stmt = $pdo->prepare("SELECT excel_column, mysql_column, headerexcel FROM excel_column_mappings WHERE template_id = ?"); - $stmt->execute([$template_id]); - $existing_mappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - - // Creiamo gli array delle colonne già mappate - $mapped_xls_columns = array_column($existing_mappings, 'excel_column'); - $mapped_mysql_columns = array_column($existing_mappings, 'mysql_column'); // CORRETTO PER FILTRARE! - - // 3️⃣ Recuperiamo tutte le colonne disponibili nella tabella MySQL target - $stmt = $pdo->prepare("SHOW COLUMNS FROM `$target_table`"); - $stmt->execute(); - $table_columns = $stmt->fetchAll(PDO::FETCH_COLUMN); - - // 🔥 FIX: Rimuoviamo le colonne MySQL che sono già state mappate! - $remaining_mysql_columns = array_values(array_diff($table_columns, $mapped_mysql_columns)); - - // 4️⃣ Se abbiamo salvato gli header XLSX in `headerexcel`, li usiamo per calcolare le colonne XLSX non mappate - $headerexcel = !empty($existing_mappings) ? $existing_mappings[0]['headerexcel'] : ''; - $all_xls_columns = !empty($headerexcel) ? explode(',', $headerexcel) : []; - $remaining_xls_columns = array_values(array_diff($all_xls_columns, $mapped_xls_columns)); - - // 5️⃣ Invio dei dati al frontend - echo json_encode([ - "success" => true, - "mappings" => $existing_mappings, - "remaining_xls_columns" => $remaining_xls_columns, - "remaining_mysql_columns" => $remaining_mysql_columns // 🔥 ORA LE COLONNE MYSQL SONO FILTRATE! - ]); -} catch (PDOException $e) { - echo json_encode(["success" => false, "message" => "Database error: " . $e->getMessage()]); -} diff --git a/public/userarea/load_mappings.php b/public/userarea/load_mappings.php deleted file mode 100644 index 89fb892..0000000 --- a/public/userarea/load_mappings.php +++ /dev/null @@ -1,23 +0,0 @@ -getConnection(); - -$template_id = $_GET['template_id'] ?? 0; - -try { - $stmt = $pdo->prepare("SELECT id, field_id, excel_column, is_manual, manual_default, field_label FROM template_mapping WHERE template_id = ?"); - $stmt->execute([$template_id]); - $mappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - - echo json_encode(["success" => true, "mappings" => $mappings]); -} catch (Exception $e) { - echo json_encode(["success" => false, "message" => "Error: " . $e->getMessage()]); -} -exit; diff --git a/public/userarea/load_more_rows.php b/public/userarea/load_more_rows.php deleted file mode 100644 index f4125d6..0000000 --- a/public/userarea/load_more_rows.php +++ /dev/null @@ -1,69 +0,0 @@ - false, 'message' => 'Parametri non validi']); - exit; -} - -// Connessione al database -$db = DBHandlerSelect::getInstance(); -$pdo = $db->getConnection(); - -// Recupera i dati -try { - $stmt = $pdo->prepare(" - SELECT d.*, CONCAT(u.first_name, ' ', u.last_name) AS user_name - FROM datadb d - LEFT JOIN auth_users u ON d.user_id = u.id - WHERE d.templateid = ? AND d.status = ? - LIMIT ? OFFSET ? - "); - $stmt->execute([$template_id, $status, $limit, $offset]); - $importedData = $stmt->fetchAll(PDO::FETCH_ASSOC); - - // Recupera i dettagli manuali - $insertedIds = array_column($importedData, 'iddatadb'); - $manualDetails = []; - if (!empty($insertedIds)) { - $placeholders = implode(',', array_fill(0, count($insertedIds), '?')); - $stmt = $pdo->prepare(" - SELECT d.id AS detail_id, d.id AS datadb_id, d.mapping_id, d.field_value, m.field_label, m.data_type, m.is_required, m.manual_default - FROM import_data_details d - JOIN template_mapping m ON d.mapping_id = m.id - WHERE d.id IN ($placeholders) - "); - $stmt->execute($insertedIds); - $manualDetails = $stmt->fetchAll(PDO::FETCH_ASSOC); - } - - // Prepara i dati per il JSON - $rows = []; - foreach ($importedData as $row) { - $rowData = [ - 'iddatadb' => $row['iddatadb'] ?? '', - 'importreferencecode' => $row['importreferencecode'] ?? '', - 'filename_import' => $row['filename_import'] ?? '', - 'status' => $row['status'] ?? '', - 'importdate' => $row['importdate'] ?? '', - 'details' => array_filter($manualDetails, fn($d) => $d['datadb_id'] == $row['iddatadb']) - ]; - $rows[] = $rowData; - } - - error_log("load_more_rows.php: Caricate " . count($rows) . " righe per template_id=$template_id, status=$status, offset=$offset"); - echo json_encode(['success' => true, 'rows' => $rows]); -} catch (Exception $e) { - error_log("Errore in load_more_rows.php: " . $e->getMessage()); - echo json_encode(['success' => false, 'message' => 'Errore nel caricamento: ' . $e->getMessage()]); -} -exit; diff --git a/public/userarea/load_parts.php b/public/userarea/load_parts.php deleted file mode 100644 index e0fdea7..0000000 --- a/public/userarea/load_parts.php +++ /dev/null @@ -1,24 +0,0 @@ -getConnection(); - -$iddatadb = $_GET['iddatadb'] ?? null; - -if (!$iddatadb) { - echo json_encode(['success' => false, 'message' => 'ID TRF mancante']); - exit; -} - -try { - $stmt = $pdo->prepare("SELECT id, iddatadb, part_number, part_description, idmatrice, note, dateexpiry FROM identification_parts WHERE iddatadb = :iddatadb ORDER BY part_number ASC"); - $stmt->execute([':iddatadb' => $iddatadb]); - $parts = $stmt->fetchAll(PDO::FETCH_ASSOC); - - echo json_encode(['success' => true, 'parts' => $parts]); -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nel caricamento: ' . $e->getMessage()]); -} diff --git a/public/userarea/load_parts_quotation.php b/public/userarea/load_parts_quotation.php deleted file mode 100644 index a88782d..0000000 --- a/public/userarea/load_parts_quotation.php +++ /dev/null @@ -1,23 +0,0 @@ -getConnection(); - -$idquotations = $_GET['idquotations'] ?? null; - -if (!$idquotations) { - echo json_encode(['success' => false, 'message' => 'ID quotations mancante']); - exit; -} - -try { - $stmt = $pdo->prepare("SELECT id, idquotations, part_number, part_description FROM identification_parts WHERE idquotations = :idquotations ORDER BY part_number ASC"); - $stmt->execute([':idquotations' => $idquotations]); - $parts = $stmt->fetchAll(); - - echo json_encode(['success' => true, 'parts' => $parts]); -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nel caricamento: ' . $e->getMessage()]); -} diff --git a/public/userarea/load_photo.php b/public/userarea/load_photo.php deleted file mode 100644 index f3ac03b..0000000 --- a/public/userarea/load_photo.php +++ /dev/null @@ -1,34 +0,0 @@ -getConnection(); - -$iddatadb = $_GET['iddatadb'] ?? null; - -if (!$iddatadb) { - echo json_encode(['success' => false, 'message' => 'ID TRF mancante']); - exit; -} - -try { - // Adjust the query to select all photo paths for the given iddatadb - $stmt = $pdo->prepare("SELECT file_path FROM datadb_photos WHERE iddatadb = :iddatadb"); - $stmt->execute([':iddatadb' => $iddatadb]); - $photos = $stmt->fetchAll(PDO::FETCH_ASSOC); - - if ($photos && count($photos) > 0) { - // Prepare an array of full file paths - $photoPaths = array_map(function($photo) { - return '../photostrf/' . $photo['file_path']; // Assuming the photos are stored in the "photostrf" folder - }, $photos); - - echo json_encode(['success' => true, 'photos' => $photoPaths]); // Return an array of photo paths - } else { - echo json_encode(['success' => false, 'message' => 'Nessuna foto trovata']); - } -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nel caricamento: ' . $e->getMessage()]); -} diff --git a/public/userarea/load_photo_quotation.php b/public/userarea/load_photo_quotation.php deleted file mode 100644 index 2eab4cc..0000000 --- a/public/userarea/load_photo_quotation.php +++ /dev/null @@ -1,33 +0,0 @@ -getConnection(); - -$idquotations = isset($_GET['idquotations']) ? intval($_GET['idquotations']) : null; - -if (!$idquotations) { - echo json_encode(['success' => false, 'message' => 'ID quotation mancante']); - exit; -} - -try { - // Seleziona le foto per il dato idquotations dalla tabella datadb_photos - $stmt = $pdo->prepare("SELECT id, file_path FROM datadb_photos WHERE idquotations = ?"); - $stmt->execute([$idquotations]); - $photos = $stmt->fetchAll(PDO::FETCH_ASSOC); - - if ($photos && count($photos) > 0) { - $photoPaths = array_map(function ($photo) { - return '../photostrf/' . $photo['file_path']; - }, $photos); - echo json_encode(['success' => true, 'photos' => $photoPaths]); - } else { - echo json_encode(['success' => false, 'message' => 'Nessuna foto trovata']); - } -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nel caricamento: ' . $e->getMessage()]); -} diff --git a/public/userarea/load_quotations.php b/public/userarea/load_quotations.php deleted file mode 100644 index f850a75..0000000 --- a/public/userarea/load_quotations.php +++ /dev/null @@ -1,32 +0,0 @@ -getConnection(); - -// Recupera l'ID dell'utente loggato -$user_id = $iduserlogin ?? 1; - -if (!$user_id) { - echo json_encode(['success' => false, 'message' => "ID dell'utente autenticato mancante"]); - exit; -} - -try { - $stmt = $pdo->prepare( - "SELECT DISTINCT q.* - FROM quotations q - INNER JOIN identification_parts ip - ON ip.idquotations = q.id - AND ip.iddatadb IS NULL - WHERE q.iduser = :iduser" - ); - $stmt->execute([':iduser' => $user_id]); - $quotations = $stmt->fetchAll(PDO::FETCH_ASSOC); - - echo json_encode(['success' => true, 'quotations' => $quotations]); -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nel caricamento delle quotations: ' . $e->getMessage()]); -} \ No newline at end of file diff --git a/public/userarea/load_table_columns.php b/public/userarea/load_table_columns.php deleted file mode 100644 index 73ad483..0000000 --- a/public/userarea/load_table_columns.php +++ /dev/null @@ -1,35 +0,0 @@ - false, "columns" => []]; - -try { - if (!isset($_GET['table']) || empty($_GET['table'])) { - throw new Exception("Invalid table name."); - } - - $table = preg_replace('/[^a-zA-Z0-9_]/', '', $_GET['table']); // Sanitize table name - - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - // Retrieve table columns - $stmt = $pdo->query("SHOW COLUMNS FROM `$table`"); - $columns = $stmt->fetchAll(PDO::FETCH_COLUMN); - - if (!$columns) { - throw new Exception("No columns found in table."); - } - - $response["success"] = true; - $response["columns"] = $columns; -} catch (Exception $e) { - $response["message"] = $e->getMessage(); -} - -// Log per debugging -error_log(json_encode($response)); - -// Restituisce la risposta JSON -echo json_encode($response); diff --git a/public/userarea/load_templates.php b/public/userarea/load_templates.php deleted file mode 100644 index 0f281db..0000000 --- a/public/userarea/load_templates.php +++ /dev/null @@ -1,39 +0,0 @@ -getConnection(); - - if (!$pdo) { - throw new Exception('Connessione al database non valida'); - } - - // Query per selezionare i template dalla tabella excel_templates - $stmt = $pdo->query("SELECT * FROM excel_templates ORDER BY created_at DESC"); - $templates = $stmt->fetchAll(PDO::FETCH_ASSOC); - - echo json_encode(['success' => true, 'data' => $templates]); -} catch (PDOException $e) { - http_response_code(500); - echo json_encode(['success' => false, 'message' => 'Errore PDO: ' . $e->getMessage()]); -} catch (Exception $e) { - http_response_code(500); - echo json_encode(['success' => false, 'message' => 'Errore interno: ' . $e->getMessage()]); -} finally { - ob_end_flush(); -} - -error_log('Errore in load_templates.php: ' . (isset($e) ? $e->getMessage() : 'Nessun errore catturato')); diff --git a/public/userarea/mapping_template_xls.php b/public/userarea/mapping_template_xls.php deleted file mode 100644 index c78d415..0000000 --- a/public/userarea/mapping_template_xls.php +++ /dev/null @@ -1,448 +0,0 @@ -getConnection(); -$stmt = $pdo->prepare("SELECT name, header_row, start_column, target_table, sample_xlsx FROM excel_templates WHERE id = ?"); -$stmt->execute([$id]); -$template = $stmt->fetch(PDO::FETCH_ASSOC); - - -if (!$template) { - die("Template not found"); -} -?> - - - - - - - - - - - Mapping XLS Template <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - - - - -
    - - - - - - - -
    -
    - - - - -
    -
    -
    -
    -
    Associate Columns - Template:
    -

    Header Row: | Start Column:

    -
    - -
    -
    -
    - -
    - - - - - ✅ Current file: - - - - No file uploaded yet. - - -
    - - - - - -
    -
    -
    XLS Column
    -
      -
      -
      - -
      -
      -
      Table Column
      -
        -
        -
        - - -
        -
        Current Associations
        -
          -
          - - - - -
          -
          - -
          -
          - - -
          - - - - - -
          - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/mapping_template_xls_scheme.php b/public/userarea/mapping_template_xls_scheme.php deleted file mode 100644 index 4d9af1c..0000000 --- a/public/userarea/mapping_template_xls_scheme.php +++ /dev/null @@ -1,614 +0,0 @@ -getConnection(); -$stmt = $pdo->prepare("SELECT name, header_row, start_column, target_table, sample_xlsx, idclient, clientname, idschema, schemaname, schemajson FROM excel_templates WHERE id = ?"); -$stmt->execute([$id]); -$template = $stmt->fetch(PDO::FETCH_ASSOC); - -if (!$template) { - die("Template not found"); -} - -// Opzionale: se clientname o schemaname non sono disponibili, potresti volerli recuperare dinamicamente -$clientName = $template['clientname'] ?: ''; -$schemaName = $template['schemaname'] ?: ''; -$schemajson = $template['schemajson'] ?: ''; // Recupera il valore di schemajson -$isSchemajsonEmpty = empty(trim($template['schemajson'])); - -?> - - - - - - - - - - - Mapping XLS Template <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - - - - -
          - - - - - - - -
          -
          - - - - -
          -
          -
          -
          -
          Associate Columns - Template:
          -

          - Client: | - Schema: | - Header Row: | - Start Column: -

          -
          -
          -
          -
          - -
          - - - - - ✅ Current file: - - - - No file uploaded yet. - - -
          - - -
          -
          -
          XLS Column
          -
            -
            -
            - -
            -
            -
            -
            Schema Fields
            - -
            - - - - - - - - - - - -
            TitleIDType
            -
            -
            - - -
            -
            Current Associations
            -
              -
              - - - -
              -
              - -
              -
              - - -
              - - - - - -
              - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/mapping_template_xls_scheme2.php b/public/userarea/mapping_template_xls_scheme2.php deleted file mode 100644 index 37186bf..0000000 --- a/public/userarea/mapping_template_xls_scheme2.php +++ /dev/null @@ -1,721 +0,0 @@ -getConnection(); -$stmt = $pdo->prepare("SELECT name, header_row, start_column, target_table, sample_xlsx, idclient, clientname, idschema, schemaname, schemajson, xls_headers FROM excel_templates WHERE id = ?"); -$stmt->execute([$id]); -$template = $stmt->fetch(PDO::FETCH_ASSOC); - -if (!$template) { - die("Template not found"); -} - -$clientName = $template['clientname'] ?: ''; -$schemaName = $template['schemaname'] ?: ''; -$schemajson = $template['schemajson'] ? json_decode($template['schemajson'], true) : []; -$isSchemajsonEmpty = empty(trim($template['schemajson'])); - -// Recupera i campi dalla tabella template_mapping -$stmt = $pdo->prepare("SELECT id, field_id, excel_column, is_manual, manual_default, data_type, is_required, default_value, has_list, length, decimals, min_value, max_value, default_curr_date, tablename, field_label, main_field, is_visible_import FROM template_mapping WHERE template_id = ?"); -$stmt->execute([$id]); -$mappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - -// Recupera le colonne già associate nel database -$usedColumnsFromDB = array_filter(array_column($mappings, 'excel_column')); - -// Decodifica l'header XLS salvato, se presente -$xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], true) : []; -?> - - - - - - - - - - Configure Template <?= htmlspecialchars($template['name'], ENT_QUOTES, 'UTF-8'); ?> - - - - - -
              - - -
              -
              - - -
              -
              -
              -
              -
              Configure Template:
              -

              - Client: | - Schema: | - Header Row: | - Start Column: -

              -
              -
              -
              -
              -
              - - - - - ✅ Current file: - - No file uploaded yet. - - -
              - -
              -
              -
              -
              Schema Fields Configuration
              - -
              - - - - - - - - - - - - - - - - - - - - - - - -
              MainVisible on ImportTitleTypeMappingDefault Value
              - > - - > - - - - Required - - - - - - - - - - - - - - - -
              -
              -
              - - -
              -
              -
              -
              -
              - - -
              - - - - - - - \ No newline at end of file diff --git a/public/userarea/mapping_template_xls_scheme2bck31072025.php b/public/userarea/mapping_template_xls_scheme2bck31072025.php deleted file mode 100644 index eee1224..0000000 --- a/public/userarea/mapping_template_xls_scheme2bck31072025.php +++ /dev/null @@ -1,464 +0,0 @@ -getConnection(); -$stmt = $pdo->prepare("SELECT name, header_row, start_column, target_table, sample_xlsx, idclient, clientname, idschema, schemaname, schemajson, xls_headers FROM excel_templates WHERE id = ?"); -$stmt->execute([$id]); -$template = $stmt->fetch(PDO::FETCH_ASSOC); - -if (!$template) { - die("Template not found"); -} - -$clientName = $template['clientname'] ?: ''; -$schemaName = $template['schemaname'] ?: ''; -$schemajson = $template['schemajson'] ? json_decode($template['schemajson'], true) : []; -$isSchemajsonEmpty = empty(trim($template['schemajson'])); - -// Recupera i campi dalla tabella template_mapping -$stmt = $pdo->prepare("SELECT id, field_id, excel_column, is_manual, manual_default, data_type, is_required, default_value, has_list, length, decimals, min_value, max_value, default_curr_date, tablename, field_label FROM template_mapping WHERE template_id = ?"); -$stmt->execute([$id]); -$mappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - -// Recupera le colonne già associate nel database -$usedColumnsFromDB = array_filter(array_column($mappings, 'excel_column')); - -// Decodifica l'header XLS salvato, se presente -$xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], true) : []; -?> - - - - - - - - - - Configure Template <?= htmlspecialchars($template['name'], ENT_QUOTES, 'UTF-8'); ?> - - - - -
              - - -
              -
              - - -
              -
              -
              -
              -
              Configure Template:
              -

              - Client: | - Schema: | - Header Row: | - Start Column: -

              -
              -
              -
              -
              -
              - - - - - ✅ Current file: - - No file uploaded yet. - - -
              - -
              -
              -
              -
              Schema Fields Configuration
              - -
              - - - - - - - - - - - - - - - - - - - - - -
              TitleIDTypeMappingDefault Value
              - - - - - - - - -
              -
              -
              - - -
              -
              -
              -
              -
              - - -
              - - - - - - \ No newline at end of file diff --git a/public/userarea/metadata_response.xml b/public/userarea/metadata_response.xml deleted file mode 100644 index 453cac5..0000000 --- a/public/userarea/metadata_response.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/userarea/modal_annotations.php b/public/userarea/modal_annotations.php deleted file mode 100644 index 35f5135..0000000 --- a/public/userarea/modal_annotations.php +++ /dev/null @@ -1,274 +0,0 @@ - - - - - \ No newline at end of file diff --git a/public/userarea/modal_parts.php b/public/userarea/modal_parts.php deleted file mode 100644 index 8a88919..0000000 --- a/public/userarea/modal_parts.php +++ /dev/null @@ -1,310 +0,0 @@ - - - - \ No newline at end of file diff --git a/public/userarea/modal_partsTable.php b/public/userarea/modal_partsTable.php deleted file mode 100644 index 59d7f13..0000000 --- a/public/userarea/modal_partsTable.php +++ /dev/null @@ -1,496 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/parts - Copia.js b/public/userarea/parts - Copia.js deleted file mode 100644 index 9427811..0000000 --- a/public/userarea/parts - Copia.js +++ /dev/null @@ -1,572 +0,0 @@ -$(document).ready(function () { - console.log("parts.js caricato correttamente"); - - $(".parts-btn").on("click", function () { - console.log("Pulsante Parts cliccato"); - const iddatadb = $(this).data("iddatadb"); - const rowIndex = $(this).data("row"); - const importRef = $("table tbody tr") - .eq(rowIndex) - .find("td") - .eq(1) - .text(); - const description = - $("table tbody tr").eq(rowIndex).find("td").eq(2).text() || - "Sconosciuto"; - - $("#trfHeader").text(`${iddatadb} - ${importRef} - ${description}`); - $("#partsModal").data("iddatadb", iddatadb); - - loadPhoto(iddatadb); - loadExistingParts(iddatadb); - - $("#partsModal").modal("show"); - }); - - function loadPhoto(iddatadb) { - $.ajax({ - url: "load_photo.php", - method: "GET", - data: { iddatadb: iddatadb }, - success: function (response) { - if (response.success && response.file_path) { - const img = $("#samplePhoto"); - img.attr("src", response.file_path); - img.on("load", function () { - const container = img.parent(); - const canvas = document.getElementById("photoCanvas"); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img[0].naturalWidth; - const scaleY = containerHeight / img[0].naturalHeight; - const scale = Math.min(scaleX, scaleY); - canvas.width = img[0].naturalWidth * scale; - canvas.height = img[0].naturalHeight * scale; - canvas.style.width = `${containerWidth}px`; - canvas.style.height = `${containerHeight}px`; - const ctx = canvas.getContext("2d"); - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.drawImage( - img.get(0), - 0, - 0, - canvas.width, - canvas.height, - ); - updateMarkers(); - }); - } else { - $("#samplePhoto").attr("src", ""); - alert("Nessuna foto trovata per questo TRF."); - } - }, - error: function (xhr, status, error) { - alert("Errore nel caricamento della foto: " + error); - }, - }); - } - - function addNewRow(nextPartNumber) { - const newRow = ` - - - - - - - - - - - `; - $("#partsTableBody").append(newRow); - updateRowButtons(); - } - - function updateRowButtons() { - const rowCount = $("#partsTableBody tr").length; - $("#partsTableBody tr").each(function (index) { - const $removeBtn = $(this).find(".remove-row"); - if (rowCount > 1) { - $removeBtn.show(); - } else { - $removeBtn.hide(); - } - }); - } - - $(document).on("click", ".add-row", function (e) { - e.preventDefault(); - console.log("Pulsante Aggiungi riga cliccato"); - const maxPartNumber = Math.max( - ...$("#partsTableBody tr") - .map(function () { - return parseInt($(this).find(".part-number").val()) || 0; - }) - .get(), - ); - addNewRow(maxPartNumber + 1); - updatePartsList(); - }); - - $(document).on("click", ".remove-row", function (e) { - e.preventDefault(); - console.log("Pulsante Rimuovi riga cliccato"); - const $row = $(this).closest("tr"); - const partId = $row.data("part-id"); - console.log("ID parte da eliminare:", partId); - - if (partId !== "new" && partId !== undefined && partId !== null) { - console.log("Procedo con la cancellazione dal database"); - $.ajax({ - url: "delete_part.php", - method: "POST", - data: JSON.stringify({ part_id: partId }), - contentType: "application/json", - beforeSend: function () { - console.log( - "Invio richiesta AJAX a delete_part.php con part_id:", - partId, - ); - }, - success: function (response) { - console.log("Risposta da delete_part.php:", response); - if (response.success) { - $row.remove(); - updateRowButtons(); - updatePartsList(); - clearCanvasMarkers(); - } else { - alert("Errore nell'eliminazione: " + response.message); - } - }, - error: function (xhr, status, error) { - console.log("Errore AJAX:", status, error); - alert( - "Errore nell'eliminazione: " + - error + - ". Stato: " + - xhr.status + - " - " + - xhr.responseText, - ); - }, - }); - } else { - console.log( - 'Riga non salvata nel database (partId = "new" o non definito), rimuovo solo visivamente', - ); - $row.remove(); - updateRowButtons(); - updatePartsList(); - } - }); - - $(document).on("blur", ".part-description, .part-number", function () { - const $input = $(this); - const $row = $input.closest("tr"); - const partNumber = $row.find(".part-number").val(); - const partDescription = $row.find(".part-description").val().trim(); - const $saveStatus = $row.find(".save-status"); - const $saveLoading = $row.find(".save-loading"); - const iddatadb = $("#partsModal").data("iddatadb"); - - console.log("Evento blur su input:", { partNumber, partDescription }); - - if (partDescription && iddatadb) { - $saveLoading.show(); - $saveStatus.hide(); - - $.ajax({ - url: "save_parts.php", - method: "POST", - data: JSON.stringify({ - iddatadb: iddatadb, - parts: [ - { - part_number: partNumber, - part_description: partDescription, - }, - ], - }), - contentType: "application/json", - success: function (response) { - if (response.success) { - if (response.part_id) { - $row.data("part-id", response.part_id); - console.log( - "Aggiornato partId della riga:", - response.part_id, - ); - } - $saveLoading.hide(); - $saveStatus.show(); - updatePartsList(); - setTimeout(() => $saveStatus.hide(), 2000); - } else { - alert("Errore nel salvataggio: " + response.message); - $saveLoading.hide(); - } - }, - error: function (xhr, status, error) { - alert("Errore nel salvataggio delle parti: " + error); - $saveLoading.hide(); - }, - }); - } - }); - - function loadExistingParts(iddatadb) { - $.ajax({ - url: "load_parts.php", - method: "GET", - data: { iddatadb: iddatadb }, - success: function (response) { - if (response.success) { - $("#partsTableBody").empty(); - if (response.parts.length > 0) { - response.parts.forEach((part) => { - const newRow = ` - - - - - - - - - - - `; - $("#partsTableBody").append(newRow); - }); - } else { - addNewRow(1); - } - updateRowButtons(); - updatePartsList(); - } else { - alert( - "Errore nel caricamento delle parti: " + - response.message, - ); - addNewRow(1); - } - }, - error: function (xhr, status, error) { - alert("Errore nel caricamento delle parti: " + error); - addNewRow(1); - }, - }); - } - - function updatePartsList() { - $("#partsList").empty(); - $("#partsTableBody tr").each(function () { - const partNumber = $(this).find(".part-number").val(); - const partDescription = $(this).find(".part-description").val(); - if (partNumber && partDescription) { - const listItem = `
            • ${partNumber} - ${partDescription}
            • `; - $("#partsList").append(listItem); - } - }); - } - - let selectedPartNumber = null; - let markers = []; - let descriptionPosition = { x: 10, y: 10 }; - let hasDescriptions = false; - - $("#partsList").on("click", "li", function () { - selectedPartNumber = $(this).data("part-number"); - console.log("Part number selezionato:", selectedPartNumber); - $(this).addClass("active").siblings().removeClass("active"); - }); - - const canvas = document.getElementById("photoCanvas"); - const ctx = canvas.getContext("2d"); - - $("#markerContainer").on("click", function (e) { - console.log("Click sul markerContainer rilevato"); // Debug - if (selectedPartNumber !== null) { - const img = $("#samplePhoto"); - const canvas = document.getElementById("photoCanvas"); - const rect = canvas.getBoundingClientRect(); - const container = img.parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img.get(0).naturalWidth; - const scaleY = containerHeight / img.get(0).naturalHeight; - const scale = Math.min(scaleX, scaleY); - const x = (e.clientX - rect.left) / scale; - const y = (e.clientY - rect.top) / scale; - - console.log("Coordinate cliccate (x, y):", x, y); // Debug - - const existingMarker = markers.find( - (m) => m.partNumber == selectedPartNumber, - ); - if (existingMarker) { - existingMarker.x = x; - existingMarker.y = y; - } else { - markers.push({ partNumber: selectedPartNumber, x, y }); - } - console.log("Markers aggiornati:", markers); // Debug - updateMarkers(); - if (hasDescriptions) { - drawDescriptions(descriptionPosition.x, descriptionPosition.y); - } - selectedPartNumber = null; - $("#partsList li").removeClass("active"); - } else { - console.log("Nessun part number selezionato"); // Debug - } - }); - function updateMarkers() { - const img = $("#samplePhoto"); - const container = img.parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img.get(0).naturalWidth; - const scaleY = containerHeight / img.get(0).naturalHeight; - const scale = Math.min(scaleX, scaleY); - - const markerContainer = $("#markerContainer"); - markerContainer.empty(); - - markers.forEach((marker) => { - const scaledX = marker.x * scale; - const scaledY = marker.y * scale; - console.log( - "Aggiungo marker:", - marker.partNumber, - "a posizione (scaledX, scaledY):", - scaledX, - scaledY, - ); // Debug - const $marker = $( - `
              ${marker.partNumber}
              `, - ).css({ - left: scaledX - 8 + "px", - top: scaledY - 8 + "px", - }); - markerContainer.append($marker); - makeDraggable($marker, marker, scale); - }); - } - - function makeDraggable($element, item, scale) { - let isDragging = false; - let currentX = parseFloat($element.css("left")) || 0; - let currentY = parseFloat($element.css("top")) || 0; - let initialX, initialY; - - $element.on("mousedown", function (e) { - e.preventDefault(); - isDragging = true; - initialX = e.clientX - currentX; - initialY = e.clientY - currentY; - $element.css("z-index", 1001); - }); - - $(document).on("mousemove", function (e) { - if (isDragging) { - e.preventDefault(); - currentX = e.clientX - initialX; - currentY = e.clientY - initialY; - const container = $("#photoCanvas").parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const maxX = containerWidth - $element.width(); - const maxY = containerHeight - $element.height(); - - currentX = Math.max(0, Math.min(currentX, maxX)); - currentY = Math.max(0, Math.min(currentY, maxY)); - - $element.css({ - left: currentX + "px", - top: currentY + "px", - }); - - if (item.partNumber) { - // È un marker - item.x = (currentX + 8) / scale; - item.y = (currentY + 8) / scale; - } else { - // È la lista - descriptionPosition.x = (currentX + 5) / scale; - descriptionPosition.y = (currentY + 5) / scale; - } - } - }); - - $(document).on("mouseup", function () { - isDragging = false; - $element.css("z-index", 1000); - }); - } - - function drawDescriptions(x, y) { - const img = $("#samplePhoto"); - const container = img.parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img.get(0).naturalWidth; - const scaleY = containerHeight / img.get(0).naturalHeight; - const scale = Math.min(scaleX, scaleY); - - const partsList = []; - $("#partsTableBody tr").each(function () { - const partNumber = $(this).find(".part-number").val(); - const partDescription = $(this).find(".part-description").val(); - if (partNumber && partDescription) { - partsList.push(`${partNumber} ${partDescription}`); - } - }); - - const descriptionList = $("#descriptionList"); - descriptionList.empty(); - descriptionList.css({ - display: "block", - top: y * scale + "px", - left: x * scale + "px", - width: "200px", - }); - partsList.forEach((part) => { - descriptionList.append(`
              ${part}
              `); - }); - - updateMarkers(); - } - - function clearCanvasMarkers() { - markers = []; - hasDescriptions = false; - $("#descriptionList").css("display", "none"); - $("#markerContainer").empty(); - const canvas = document.getElementById("photoCanvas"); - const img = $("#samplePhoto"); - const ctx = canvas.getContext("2d"); - const container = img.parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img.get(0).naturalWidth; - const scaleY = containerHeight / img.get(0).naturalHeight; - const scale = Math.min(scaleX, scaleY); - - canvas.width = img.get(0).naturalWidth * scale; - canvas.height = img.get(0).naturalHeight * scale; - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.drawImage(img.get(0), 0, 0, canvas.width, canvas.height); - } - - $("#addDescriptionsBtn").on("click", function () { - hasDescriptions = true; - descriptionPosition = { x: 10, y: 10 }; - drawDescriptions(descriptionPosition.x, descriptionPosition.y); - makeDraggable( - $("#descriptionList"), - descriptionPosition, - Math.min( - $("#photoCanvas").parent().width() / - $("#samplePhoto").get(0).naturalWidth, - $("#photoCanvas").parent().height() / - $("#samplePhoto").get(0).naturalHeight, - ), - ); - }); - - $("#removeAnnotationsBtn").on("click", function () { - clearCanvasMarkers(); - }); - - $("#savePhotoBtn").on("click", function () { - const canvas = document.getElementById("photoCanvas"); - const img = $("#samplePhoto"); - const ctx = canvas.getContext("2d"); - - canvas.width = img.get(0).naturalWidth; - canvas.height = img.get(0).naturalHeight; - ctx.drawImage(img.get(0), 0, 0); - - const partsList = []; - $("#partsTableBody tr").each(function () { - const partNumber = $(this).find(".part-number").val(); - const partDescription = $(this).find(".part-description").val(); - if (partNumber && partDescription) { - partsList.push(`${partNumber} ${partDescription}`); - } - }); - - if (hasDescriptions) { - ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; - ctx.fillRect( - descriptionPosition.x, - descriptionPosition.y, - 200, - partsList.length * 12 + 10, - ); - ctx.fillStyle = "#000000"; - ctx.font = "10px Arial"; - partsList.forEach((part, index) => { - ctx.fillText( - part, - descriptionPosition.x + 5, - descriptionPosition.y + 12 + index * 12, - ); - }); - } - - markers.forEach((marker) => { - ctx.beginPath(); - ctx.arc(marker.x, marker.y, 8, 0, 2 * Math.PI); - ctx.fillStyle = "rgba(255, 0, 0, 0.5)"; - ctx.fill(); - ctx.strokeStyle = "#ff0000"; - ctx.lineWidth = 1; - ctx.stroke(); - ctx.fillStyle = "#ffffff"; - ctx.font = "bold 8px Arial"; - ctx.textAlign = "center"; - ctx.textBaseline = "middle"; - ctx.fillText(marker.partNumber, marker.x, marker.y); - }); - - const dataURL = canvas.toDataURL("image/png"); - const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); - const defaultName = `photo_${$("#partsModal").data("iddatadb")}_${timestamp}.png`; - const newName = prompt( - "Inserisci il nome del file (senza estensione):", - defaultName.split(".png")[0], - ); - if (newName) { - const finalName = newName + "_" + timestamp + ".png"; - $.ajax({ - url: "save_annotated_photo.php", - method: "POST", - data: { dataURL: dataURL, filename: finalName }, - success: function (response) { - if (response.success) { - alert( - "Foto salvata con successo: " + response.file_path, - ); - } else { - alert("Errore nel salvataggio: " + response.message); - } - }, - error: function (xhr, status, error) { - alert("Errore nel salvataggio della foto: " + error); - }, - }); - } - }); - - $(document).on("mouseenter", "tr", function () { - console.log("Mouse entrato su riga"); - }); - - $(document).on("mouseleave", "tr", function () { - console.log("Mouse uscito da riga"); - }); -}); diff --git a/public/userarea/parts.js b/public/userarea/parts.js deleted file mode 100644 index ee615f6..0000000 --- a/public/userarea/parts.js +++ /dev/null @@ -1,1917 +0,0 @@ -$(document).ready(function () { - // =================== - // GLOBAL STATE - // =================== - let photoData = { - naturalWidth: 0, - naturalHeight: 0, - displayWidth: 0, - displayHeight: 0, - scale: 1, - }; - - let photoAnnotations = {}; - let partColors = {}; - let partMatrice = {}; - let selectedPartNumber = null; - let unsavedChanges = false; - let fabricCanvas = null; - let descriptionTextbox = null; - let markerObjects = {}; - let matrici = []; - - // =================== - // VOICE RECOGNITION SETUP - // =================== - const SpeechRecognition = - window.SpeechRecognition || window.webkitSpeechRecognition; - let recognition = null; - let isVoiceActive = false; - const magicWord = "salva"; - - if (SpeechRecognition) { - recognition = new SpeechRecognition(); - recognition.lang = "it-IT"; - recognition.continuous = true; - recognition.interimResults = false; - - recognition.onresult = function (event) { - const transcript = event.results[ - event.results.length - 1 - ][0].transcript - .trim() - .toLowerCase(); - - const $currentRow = $("#partsTableBody tr:last"); - const $descriptionInput = $currentRow.find(".part-description"); - - if (transcript.includes(magicWord)) { - const cleanedTranscript = transcript - .replace(magicWord, "") - .trim(); - if (cleanedTranscript) { - $descriptionInput.val( - ( - $descriptionInput.val() + - " " + - cleanedTranscript - ).trim(), - ); - $descriptionInput.trigger("blur"); - } - const maxPartNumber = Math.max( - ...$("#partsTableBody tr") - .map(function () { - return ( - parseInt($(this).find(".part-number").val()) || - 0 - ); - }) - .get(), - ); - addNewRow(maxPartNumber + 1); - const $newRow = $("#partsTableBody tr:last"); - $newRow.find(".part-description").focus(); - } else { - $descriptionInput.val( - ($descriptionInput.val() + " " + transcript).trim(), - ); - $descriptionInput.trigger("blur"); - } - }; - - recognition.onerror = function (event) { - if (event.error === "no-speech" || event.error === "aborted") { - if (isVoiceActive) recognition.start(); - } else { - alert("Errore nel riconoscimento vocale: " + event.error); - toggleVoiceRecognition(); - } - }; - - recognition.onend = function () { - if (isVoiceActive) recognition.start(); - }; - } else { - $("#toggleVoiceBtn").hide(); - } - - function toggleVoiceRecognition() { - if (!recognition) return; - isVoiceActive = !isVoiceActive; - const $btn = $("#toggleVoiceBtn"); - if (isVoiceActive) { - $btn.addClass("btn-danger").html( - ' Stop Voce', - ); - recognition.start(); - $("#partsTableBody tr:last").find(".part-description").focus(); - } else { - $btn.removeClass("btn-danger") - .addClass("btn-secondary") - .html(' Voce'); - recognition.stop(); - } - } - - $("#toggleVoiceBtn").on("click", toggleVoiceRecognition); - - // =================== - // MODAL HANDLING - // =================== - $(".parts-btn").on("click", function () { - const iddatadb = $(this).data("iddatadb"); - const idquotations = $(this).data("idquotations"); - const rowIndex = $(this).data("row"); - const importRef = $("table tbody tr") - .eq(rowIndex) - .find("td") - .eq(1) - .text(); - const description = - $("table tbody tr").eq(rowIndex).find("td").eq(2).text() || - "Sconosciuto"; - - $("#trfHeader").text( - `${iddatadb || idquotations} - ${importRef} - ${description}`, - ); - $("#partsModal") - .data("iddatadb", iddatadb) - .data("idquotations", idquotations); - - // Precarica le matrici se iddatadb (assumendo matrici solo per iddatadb) - if (iddatadb) { - if (matrici.length === 0) { - $.ajax({ - url: "get_matrici_db.php", - method: "GET", - dataType: "json", - success: function (data) { - matrici = data.value || []; - initializeGlobalSelect2(); - loadPhoto(iddatadb, idquotations); - loadExistingParts(iddatadb, idquotations); - }, - error: function (xhr, status, error) { - matrici = []; - initializeGlobalSelect2(); - loadPhoto(iddatadb, idquotations); - loadExistingParts(iddatadb, idquotations); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } else { - initializeGlobalSelect2(); - loadPhoto(iddatadb, idquotations); - loadExistingParts(iddatadb, idquotations); - } - } else { - loadPhoto(iddatadb, idquotations); - loadExistingParts(iddatadb, idquotations); - } - - const modalElement = document.getElementById("partsModal"); - if (modalElement) { - // Verifica se il modale è già stato inizializzato - let modal = bootstrap.Modal.getInstance(modalElement); - if (!modal) { - modal = new bootstrap.Modal(modalElement, { - backdrop: true, - keyboard: true, - focus: true, - }); - } - modal.show(); - } else { - console.error("Elemento modale non trovato: #partsModal"); - const errorMsg = $( - '', - ); - $("body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }); - - $("#partsModal .close-btn, #partsModal").on("click", function (event) { - if (event.target === this || $(event.target).hasClass("close-btn")) { - const modalElement = document.getElementById("partsModal"); - const modal = bootstrap.Modal.getInstance(modalElement); - if (modal) { - modal.hide(); - } - } - }); - - $("#partsModal").on("hide.bs.modal", function (e) { - if ( - unsavedChanges && - !confirm("Hai modifiche non salvate. Vuoi davvero uscire?") - ) { - e.preventDefault(); - } - }); - - $("#partsModal").on("hidden.bs.modal", function () { - // Resetta lo stato - photoData = { - naturalWidth: 0, - naturalHeight: 0, - displayWidth: 0, - displayHeight: 0, - scale: 1, - }; - photoAnnotations = {}; - partColors = {}; - partMatrice = {}; - selectedPartNumber = null; - unsavedChanges = false; - if (fabricCanvas) { - fabricCanvas.off(); - fabricCanvas.dispose(); - fabricCanvas = null; - } - descriptionTextbox = null; - markerObjects = {}; - matrici = []; - $("#photoSelectorContainer").empty().hide(); - $("#samplePhoto").attr("src", ""); - $("#partsTableBody").empty(); - $("#global-matrice").empty(); - $(".temp-alert").remove(); - - // Rimuovi manualmente il backdrop e ripristina il body - const modalElement = document.getElementById("partsModal"); - const modal = bootstrap.Modal.getInstance(modalElement); - if (modal) { - modal.dispose(); // Distrugge l'istanza del modale - } - $(".modal-backdrop").remove(); - $("body").removeClass("modal-open"); - $("body").css("padding-right", ""); - $(":focus").blur(); - }); - - // =================== - // PHOTO LOADERS - // =================== - function loadPhoto(iddatadb, idquotations) { - const currentPhoto = $("#samplePhoto").attr("src"); - const endpoint = idquotations - ? "load_photo_quotation.php" - : "load_photo.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - $.ajax({ - url: endpoint, - method: "GET", - data: data, - success: function (response) { - if (response.success) { - if (response.photos && response.photos.length > 1) { - showPhotoSelector(response.photos, currentPhoto); - } else if ( - response.photos && - response.photos.length === 1 - ) { - loadSinglePhoto(response.photos[0]); - } else { - $("#samplePhoto").attr("src", ""); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } - - function showPhotoSelector(photos, selected = null) { - const selectorContainer = $("#photoSelectorContainer"); - selectorContainer.empty().show(); - const selector = $( - '', - ); - photos.forEach((photo, index) => { - const photoName = photo.split("/").pop(); - const option = $("") - .val(photo) - .text(`Photo ${index + 1} - ${photoName}`); - selector.append(option); - }); - selector.on("change", function () { - loadSinglePhoto($(this).val()); - }); - selectorContainer.append(selector); - const photoToSelect = - selected && photos.includes(selected) ? selected : photos[0]; - if (photoToSelect) { - selector.val(photoToSelect); - loadSinglePhoto(photoToSelect); - } - } - - function loadSinglePhoto(photoPath) { - const img = $("#samplePhoto"); - img.off("load").attr("src", photoPath); - img.on("load", function () { - const canvas = document.getElementById("photoCanvas"); - const ctx = canvas.getContext("2d"); - const naturalWidth = img[0].naturalWidth; - const naturalHeight = img[0].naturalHeight; - const parent = $(canvas).parent(); - const maxW = parent.width(); - const maxH = parent.height(); - const scale = Math.min(maxW / naturalWidth, maxH / naturalHeight); - - photoData = { - naturalWidth, - naturalHeight, - displayWidth: Math.max(1, Math.round(naturalWidth * scale)), - displayHeight: Math.max(1, Math.round(naturalHeight * scale)), - scale, - }; - - canvas.width = naturalWidth; - canvas.height = naturalHeight; - canvas.style.width = `${photoData.displayWidth}px`; - canvas.style.height = `${photoData.displayHeight}px`; - - ctx.clearRect(0, 0, naturalWidth, naturalHeight); - ctx.drawImage(img[0], 0, 0, naturalWidth, naturalHeight); - - // === FIX PER FABRIC.JS === - - // 1. Disponi completamente il canvas esistente - if (fabricCanvas) { - fabricCanvas.off(); // Rimuove tutti gli eventi esistenti - fabricCanvas.dispose(); - fabricCanvas = null; - } - - // 2. Resetta completamente l'elemento canvas overlay - const overlayCanvas = document.getElementById("overlayCanvas"); - - // Rimuovi l'elemento esistente e creane uno nuovo - const canvasContainer = overlayCanvas.parentElement; - const newOverlayCanvas = document.createElement("canvas"); - newOverlayCanvas.id = "overlayCanvas"; - newOverlayCanvas.width = photoData.displayWidth; - newOverlayCanvas.height = photoData.displayHeight; - newOverlayCanvas.style.width = `${photoData.displayWidth}px`; - newOverlayCanvas.style.height = `${photoData.displayHeight}px`; - - // Mantieni gli stili CSS esistenti - newOverlayCanvas.style.position = "absolute"; - newOverlayCanvas.style.top = "0"; - newOverlayCanvas.style.left = "0"; - newOverlayCanvas.style.zIndex = "10"; - - // Sostituisci l'elemento - canvasContainer.removeChild(overlayCanvas); - canvasContainer.appendChild(newOverlayCanvas); - - // 3. Aspetta un tick per assicurarsi che il DOM sia aggiornato - setTimeout(() => { - // 4. Inizializza nuovo canvas Fabric.js - fabricCanvas = new fabric.Canvas("overlayCanvas", { - selection: true, - preserveObjectStacking: true, - width: photoData.displayWidth, - height: photoData.displayHeight, - }); - - // 5. Forza il ridimensionamento del canvas - fabricCanvas.setDimensions({ - width: photoData.displayWidth, - height: photoData.displayHeight, - }); - - // 6. Registra gli eventi - fabricCanvas.on("mouse:down", function (options) { - if (selectedPartNumber === null) { - return; - } - if (options.target) { - return; - } - const pointer = fabricCanvas.getPointer(options.e); - const x = pointer.x / photoData.scale; - const y = pointer.y / photoData.scale; - const currentPhoto = $("#samplePhoto").attr("src"); - - if (!photoAnnotations[currentPhoto]) { - photoAnnotations[currentPhoto] = { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - } - - const partColor = - partColors[selectedPartNumber] || "#ff0000"; - const existingMarker = photoAnnotations[ - currentPhoto - ].markers.find((m) => m.partNumber == selectedPartNumber); - - if (existingMarker) { - existingMarker.x = x; - existingMarker.y = y; - existingMarker.color = partColor; - } else { - photoAnnotations[currentPhoto].markers.push({ - partNumber: selectedPartNumber, - x, - y, - color: partColor, - }); - } - - updateMarkers(); - markUnsaved(); - selectedPartNumber = null; - $("#partsList li").removeClass("active"); - }); - - // 7. Forza focus e render - fabricCanvas.upperCanvasEl.focus(); - fabricCanvas.renderAll(); - - // 8. Aggiorna marker e descrizioni esistenti per questa foto - updateMarkers(); - updateDescriptions(); - }, 10); // Piccolo delay per assicurare che il DOM sia pronto - }); - } - - // =================== - // DOWNLOAD PHOTO - // =================== - $("#downloadPhotoBtn").on("click", function () { - const photoSrc = $("#samplePhoto").attr("src"); - if (!photoSrc) { - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - const photoName = photoSrc.split("/").pop(); - const link = document.createElement("a"); - link.href = photoSrc; - link.download = photoName; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - }); - - // =================== - // PARTS TABLE - // =================== - function addNewRow(nextPartNumber, isMix = false) { - const description = isMix ? "Mix" : ""; - const defaultColor = isMix ? "#0000ff" : "#ff0000"; - const newRow = ` - - - - - - - - - - - `; - $("#partsTableBody").append(newRow); - updateRowButtons(); - partColors[nextPartNumber || 1] = defaultColor; - markUnsaved(); - } - - function updateRowButtons() { - const rowCount = $("#partsTableBody tr").length; - $("#partsTableBody tr").each(function () { - $(this) - .find(".remove-row") - .toggle(rowCount > 1); - }); - } - - $(document).on("click", ".add-row", function (e) { - e.preventDefault(); - const maxPartNumber = Math.max( - ...$("#partsTableBody tr") - .map(function () { - return parseInt($(this).find(".part-number").val()) || 0; - }) - .get(), - ); - addNewRow(maxPartNumber + 1); - updatePartsList(); - if (photoAnnotations[$("#samplePhoto").attr("src")]?.hasDescriptions) { - updateDescriptions(); - } - }); - - $(document).on("click", ".add-mix-row", function (e) { - e.preventDefault(); - const maxPartNumber = Math.max( - ...$("#partsTableBody tr") - .map(function () { - return parseInt($(this).find(".part-number").val()) || 0; - }) - .get(), - ); - addNewRow(maxPartNumber + 1, true); - updatePartsList(); - if (photoAnnotations[$("#samplePhoto").attr("src")]?.hasDescriptions) { - updateDescriptions(); - } - }); - - $(document).on("click", ".remove-row", function (e) { - e.preventDefault(); - const $row = $(this).closest("tr"); - const partId = $row.data("part-id"); - const partNumber = $row.find(".part-number").val(); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "delete_part_quotation.php" - : "delete_part.php"; - - if (partId && partId !== "new") { - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ part_id: partId }), - contentType: "application/json", - success: function (response) { - if (response.success) { - $row.remove(); - delete partColors[partNumber]; - delete partMatrice[partNumber]; - if (markerObjects[partNumber]) { - fabricCanvas.remove(markerObjects[partNumber]); - delete markerObjects[partNumber]; - fabricCanvas.renderAll(); - } - updateRowButtons(); - updatePartsList(); - markUnsaved(); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } else { - $row.remove(); - delete partColors[partNumber]; - delete partMatrice[partNumber]; - if (markerObjects[partNumber]) { - fabricCanvas.remove(markerObjects[partNumber]); - delete markerObjects[partNumber]; - fabricCanvas.renderAll(); - } - updateRowButtons(); - updatePartsList(); - if ( - photoAnnotations[$("#samplePhoto").attr("src")]?.hasDescriptions - ) { - updateDescriptions(); - } - markUnsaved(); - } - }); - - $(document).on("blur", ".part-description, .part-number", function () { - const $input = $(this); - const $row = $input.closest("tr"); - const partNumber = $row.find(".part-number").val(); - const partDescription = $row.find(".part-description").val().trim(); - const $saveStatus = $row.find(".save-status"); - const $saveLoading = $row.find(".save-loading"); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const isMix = partDescription.startsWith("Mix") ? "Y" : "N"; - const partId = $row.data("part-id") || null; - const endpoint = idquotations - ? "save_parts_quotation.php" - : "save_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - - if (partDescription && (iddatadb || idquotations)) { - $saveLoading.show(); - $saveStatus.hide(); - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ - ...data, - parts: [ - { - id: partId, - part_number: partNumber, - part_description: partDescription, - mix: isMix, - }, - ], - }), - contentType: "application/json", - success: function (response) { - $saveLoading.hide(); - if (response.success) { - $saveStatus.show(); - if (response.part_id) { - $row.attr("data-part-id", response.part_id).data( - "part-id", - response.part_id, - ); - } - setTimeout(() => $saveStatus.hide(), 2000); - updatePartsList(); - if ( - photoAnnotations[$("#samplePhoto").attr("src")] - ?.hasDescriptions - ) { - updateDescriptions(); - } - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - $saveLoading.hide(); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } - }); - - // =================== - // LOAD EXISTING PARTS - // =================== - function loadExistingParts(iddatadb, idquotations) { - const endpoint = idquotations - ? "load_parts_quotation.php" - : "load_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - $.ajax({ - url: endpoint, - method: "GET", - data: data, - success: function (response) { - $("#partsTableBody").empty(); - if (response.success && response.parts.length > 0) { - response.parts.forEach((part) => { - const defaultColor = part.part_description.startsWith( - "Mix", - ) - ? "#0000ff" - : "#ff0000"; - const newRow = ` - - - - - - - - - - - `; - $("#partsTableBody").append(newRow); - partColors[part.part_number] = defaultColor; - if (part.idmatrice) { - partMatrice[part.part_number] = part.idmatrice; - } - }); - } else { - addNewRow(1); - } - updateRowButtons(); - updatePartsList(); - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - addNewRow(1); - }, - }); - } - - // Funzione per inizializzare Select2 sulle tendine delle matrici - function initializeSelect2($select, partNumber, partId, idmatrice) { - if (typeof $.fn.select2 === "undefined") { - $select.replaceWith( - '', - ); - return; - } - - const options = matrici.map(function (matrice) { - return { - id: matrice.IdMatrice, - text: matrice.NomeMatrice, // Updated to use NomeMatrice - }; - }); - - $select.select2({ - placeholder: "Seleziona matrice", - allowClear: true, - data: options, - dropdownParent: $("#partsModal"), - matcher: function (params, data) { - if (!params.term || params.term.length < 3) { - return data; - } - const term = params.term.toUpperCase(); - if (data.text.toUpperCase().indexOf(term) >= 0) { - return data; - } - return null; - }, - }); - - if (partId && partId !== "new" && idmatrice) { - const matrice = matrici.find((m) => m.IdMatrice == idmatrice); - if (matrice) { - const option = new Option( - matrice.NomeMatrice, // Updated to use NomeMatrice - matrice.IdMatrice, - true, - true, - ); - $select.append(option).trigger("change"); - partMatrice[partNumber] = matrice.IdMatrice; - } - } - - $select.on("change", function () { - const idmatrice = $(this).val(); - const $listItem = $(this).closest("li"); - const $saveStatus = $listItem.find(".save-status"); - const $saveLoading = $listItem.find(".save-loading"); - - partMatrice[partNumber] = idmatrice || null; - - if (partId && partId !== "new") { - $saveLoading.show(); - $saveStatus.hide(); - - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "save_matrice_quotation.php" - : "save_matrice.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ - ...data, - parts: [ - { - id: partId, - idmatrice: idmatrice || null, - }, - ], - }), - contentType: "application/json", - success: function (response) { - if (response.success) { - $saveLoading.hide(); - $saveStatus.show(); - setTimeout(() => $saveStatus.hide(), 2000); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - $saveLoading.hide(); - } - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - $saveLoading.hide(); - }, - }); - } - }); - } - - // Funzione per inizializzare Select2 sul dropdown globale - function initializeGlobalSelect2() { - const $select = $("#global-matrice"); - if (typeof $.fn.select2 === "undefined") { - $select.replaceWith( - '', - ); - return; - } - - const options = matrici.map(function (matrice) { - return { - id: matrice.IdMatrice, - text: matrice.NomeMatrice, // Updated to use NomeMatrice - }; - }); - - $select.select2({ - placeholder: "Seleziona matrice globale", - allowClear: true, - data: options, - dropdownParent: $("#partsModal"), - matcher: function (params, data) { - if (!params.term || params.term.length < 3) { - return data; - } - const term = params.term.toUpperCase(); - if (data.text.toUpperCase().indexOf(term) >= 0) { - return data; - } - return null; - }, - }); - } - - // =================== - // PARTS LIST - // =================== - function updatePartsList() { - const showMixParts = $("#showMixParts").is(":checked"); - $("#partsList").empty(); - const predefinedColors = [ - "#ff0000", // Rosso - "#0000ff", // Blu - "#00ff00", // Verde - "#01832cff", // Giallo - "#ff00ff", // Magenta - "#00ffff", // Ciano - "#800080", // Viola - "#ffa500", // Arancione - ]; - - $("#partsTableBody tr").each(function () { - const partNumber = $(this).find(".part-number").val(); - const partDescription = $(this).find(".part-description").val(); - const partId = $(this).data("part-id"); - const partColor = - partColors[partNumber] || - (partDescription.startsWith("Mix") ? "#0000ff" : "#ff0000"); - if ( - partNumber && - partDescription && - (showMixParts || !partDescription.startsWith("Mix")) - ) { - const colorOptions = predefinedColors - .map( - (color) => - `
              `, - ) - .join(""); - const listItem = ` -
            • - ${partNumber} - ${partDescription} -
              - - - -
              -
              -
              ${colorOptions}
              -
              - - -
              -
            • `; - $("#partsList").append(listItem); - const $select = $("#partsList").find( - `li[data-part-number="${partNumber}"] .part-matrice`, - ); - initializeSelect2( - $select, - partNumber, - partId, - partMatrice[partNumber], - ); - } - }); - - $(".selected-color").on("click", function (e) { - e.stopPropagation(); - const $picker = $(this).siblings(".color-picker"); - $(".color-picker").not($picker).hide(); - $picker.toggle(); - }); - - $(".color-option").on("click", function (e) { - e.stopPropagation(); - const $this = $(this); - const color = $this.data("color"); - const $listItem = $this.closest("li"); - const partNumber = $listItem.data("part-number"); - partColors[partNumber] = color; - $listItem.find(".selected-color").css("background-color", color); - $this.closest(".color-picker").hide(); - updateMarkers(); - markUnsaved(); - }); - - $(document).on("click", function (e) { - if (!$(e.target).closest(".color-picker-container").length) { - $(".color-picker").hide(); - } - }); - } - - $(document).on("click", ".add-to-mix-btn", function () { - const $listItem = $(this).closest("li"); - const partDescription = $listItem.text().split(" - ")[1].trim(); - const $mixRow = $("#partsTableBody tr") - .filter(function () { - return $(this) - .find(".part-description") - .val() - .startsWith("Mix"); - }) - .last(); - - if ($mixRow.length === 0) { - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - const $descriptionInput = $mixRow.find(".part-description"); - let currentDescription = $descriptionInput.val().trim(); - if (currentDescription === "Mix") { - currentDescription = `Mix ${partDescription}`; - } else if (!currentDescription.includes(partDescription)) { - currentDescription += ` + ${partDescription}`; - } else { - return; - } - - $descriptionInput.val(currentDescription); - $descriptionInput.trigger("blur"); - updatePartsList(); - if (photoAnnotations[$("#samplePhoto").attr("src")]?.hasDescriptions) { - updateDescriptions(); - } - }); - - $(document).on("click", ".propagate-matrice-btn", function () { - const $listItem = $(this).closest("li"); - const globalVal = $("#global-matrice").val(); - if (globalVal) { - $listItem.find(".part-matrice").val(globalVal).trigger("change"); - } else { - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }); - - $("#partsList").on("click", "li", function (e) { - if ( - $(e.target).hasClass("add-to-mix-btn") || - $(e.target).hasClass("color-option") || - $(e.target).closest(".color-picker-container").length || - $(e.target).hasClass("part-matrice") || - $(e.target).closest(".select2-container").length || - $(e.target).hasClass("propagate-matrice-btn") - ) - return; - selectedPartNumber = $(this).data("part-number"); - $(this).addClass("active").siblings().removeClass("active"); - }); - - $("#showMixParts").on("change", function () { - updatePartsList(); - updateMarkers(); - if (photoAnnotations[$("#samplePhoto").attr("src")]?.hasDescriptions) { - updateDescriptions(); - } - }); - - function renumberParts() { - const $rows = $("#partsTableBody tr"); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "renumber_parts_quotation.php" - : "renumber_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - let newPartColors = {}; - let newPartMatrice = {}; - let newMarkerObjects = {}; - - let partsData = $rows - .map(function (index) { - const $row = $(this); - return { - partNumber: $row.find(".part-number").val(), - partDescription: $row.find(".part-description").val(), - partId: $row.data("part-id"), - }; - }) - .get(); - - partsData.forEach((part, index) => { - const newNumber = index + 1; - newPartColors[newNumber] = partColors[part.partNumber] || "#ff0000"; - newPartMatrice[newNumber] = partMatrice[part.partNumber] || null; - if (markerObjects[part.partNumber]) { - newMarkerObjects[newNumber] = markerObjects[part.partNumber]; - } - part.partNumber = newNumber; - }); - - $rows.each(function (index) { - $(this) - .find(".part-number") - .val(index + 1); - }); - - const currentPhoto = $("#samplePhoto").attr("src"); - if (photoAnnotations[currentPhoto]) { - photoAnnotations[currentPhoto].markers.forEach((marker) => { - const newPartNumber = partsData.find( - (p) => p.partNumber == marker.partNumber, - )?.partNumber; - if (newPartNumber) { - marker.partNumber = newPartNumber; - marker.color = newPartColors[newPartNumber]; - } - }); - } - - partColors = newPartColors; - partMatrice = newPartMatrice; - markerObjects = newMarkerObjects; - - const partsToSave = partsData.map((part) => ({ - id: part.partId || null, - part_number: part.partNumber, - part_description: part.partDescription, - mix: part.partDescription.startsWith("Mix") ? "Y" : "N", - idmatrice: partMatrice[part.partNumber] || null, - })); - - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ ...data, parts: partsToSave }), - contentType: "application/json", - success: function (response) { - if (response.success) { - $rows.each(function (index) { - const $row = $(this); - const newPartId = - response.part_ids && response.part_ids[index] - ? response.part_ids[index] - : $row.data("part-id"); - if (newPartId) { - $row.attr("data-part-id", newPartId).data( - "part-id", - newPartId, - ); - } - const $saveStatus = $row.find(".save-status"); - const $saveLoading = $row.find(".save-loading"); - $saveLoading.hide(); - $saveStatus.show(); - setTimeout(() => $saveStatus.hide(), 2000); - }); - updatePartsList(); - updateMarkers(); - if (photoAnnotations[currentPhoto]?.hasDescriptions) { - updateDescriptions(); - } - markUnsaved(); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } - - $("#renumberPartsBtn").on("click", renumberParts); - - // =================== - // MARKERS & DESCRIPTIONS - // =================== - function updateMarkers() { - // Rimuovi marker esistenti - for (let partNumber in markerObjects) { - fabricCanvas.remove(markerObjects[partNumber]); - delete markerObjects[partNumber]; - } - markerObjects = {}; - - const currentPhoto = $("#samplePhoto").attr("src"); - const annotations = photoAnnotations[currentPhoto] || { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - const showMixParts = $("#showMixParts").is(":checked"); - - annotations.markers.forEach((marker) => { - const partRow = $("#partsTableBody tr").filter(function () { - return $(this).find(".part-number").val() == marker.partNumber; - }); - const partDescription = partRow.find(".part-description").val(); - if ( - !showMixParts && - partDescription && - partDescription.startsWith("Mix") - ) - return; - - const radius = 12; - const fontSize = 16; - const markerColor = - marker.color || partColors[marker.partNumber] || "#ff0000"; - - // Crea cerchio - const circle = new fabric.Circle({ - radius: radius, - fill: markerColor, - stroke: markerColor, - strokeWidth: 1, - left: marker.x * photoData.scale, - top: marker.y * photoData.scale, - originX: "center", - originY: "center", - selectable: true, - hasControls: false, - lockScalingX: true, - lockScalingY: true, - lockRotation: true, - }); - - // Crea testo - const text = new fabric.Text(marker.partNumber.toString(), { - fontFamily: "Arial", - fontSize: fontSize, - fontWeight: "bold", - fill: "#ffffff", - left: marker.x * photoData.scale, - top: marker.y * photoData.scale, - originX: "center", - originY: "middle", - selectable: true, - hasControls: false, - lockScalingX: true, - lockScalingY: true, - lockRotation: true, - }); - - // Raggruppa cerchio e testo - const group = new fabric.Group([circle, text], { - left: marker.x * photoData.scale, - top: marker.y * photoData.scale, - originX: "center", - originY: "center", - selectable: true, - hasControls: false, - lockScalingX: true, - lockScalingY: true, - lockRotation: true, - }); - - group.on("moving", function () { - marker.x = this.left / photoData.scale; - marker.y = this.top / photoData.scale; - markUnsaved(); - }); - - fabricCanvas.add(group); - markerObjects[marker.partNumber] = group; - }); - - fabricCanvas.renderAll(); - } - - function updateDescriptions() { - const currentPhoto = $("#samplePhoto").attr("src"); - const annotations = photoAnnotations[currentPhoto] || { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - const showMixParts = $("#showMixParts").is(":checked"); - - if (!annotations.hasDescriptions) { - if (descriptionTextbox) { - fabricCanvas.remove(descriptionTextbox); - descriptionTextbox = null; - fabricCanvas.renderAll(); - } - return; - } - - const partsList = []; - $("#partsTableBody tr").each(function () { - const partNumber = $(this).find(".part-number").val(); - const partDescription = $(this).find(".part-description").val(); - if ( - partNumber && - partDescription && - (showMixParts || !partDescription.startsWith("Mix")) - ) { - partsList.push(`${partNumber} ${partDescription}`); - } - }); - - const text = partsList.join("\n"); - - // Rimuovi il textbox esistente - if (descriptionTextbox) { - fabricCanvas.remove(descriptionTextbox); - descriptionTextbox = null; - } - - descriptionTextbox = new fabric.Textbox(text, { - left: annotations.descriptionPosition.x * photoData.scale, - top: annotations.descriptionPosition.y * photoData.scale, - width: annotations.descriptionSize.width, - scaleX: 1, - scaleY: 1, - backgroundColor: "rgba(255, 255, 255, 0)", // Changed to fully transparent - fontFamily: "Arial", - fontSize: 24, - fill: "#000000", - padding: 10, - editable: false, - selectable: true, - hasControls: true, - borderColor: "#ccc", - cornerColor: "#888", - cornerSize: 10, - transparentCorners: false, - lockRotation: true, - lockScalingFlip: true, - minScaleLimit: 0.1, - }); - - descriptionTextbox.on("scaling", function () { - fitFontToBox(this); - annotations.descriptionSize.width = this.width * this.scaleX; - annotations.descriptionSize.height = this.height * this.scaleY; - markUnsaved(); - }); - - descriptionTextbox.on("moving", function () { - annotations.descriptionPosition.x = this.left / photoData.scale; - annotations.descriptionPosition.y = this.top / photoData.scale; - markUnsaved(); - }); - - fabricCanvas.add(descriptionTextbox); - fitFontToBox(descriptionTextbox); - fabricCanvas.renderAll(); - } - - function fitFontToBox(textbox) { - let fontSize = 24; - textbox.set("fontSize", fontSize); - textbox.setCoords(); - - while ( - (textbox.textLines.length * textbox.fontSize * 1.2 > - textbox.height * textbox.scaleY || - textbox._getTransformedDimensions().x > - textbox.width * textbox.scaleX) && - fontSize > 8 - ) { - fontSize -= 1; - textbox.set("fontSize", fontSize); - textbox.setCoords(); - } - - while ( - textbox.textLines.length * textbox.fontSize * 1.2 < - textbox.height * textbox.scaleY && - textbox._getTransformedDimensions().x < - textbox.width * textbox.scaleX && - fontSize < 32 - ) { - fontSize += 1; - textbox.set("fontSize", fontSize); - textbox.setCoords(); - } - } - - function clearCanvasMarkers(clearDescriptions = true) { - const currentPhoto = $("#samplePhoto").attr("src"); - if (clearDescriptions && photoAnnotations[currentPhoto]) { - photoAnnotations[currentPhoto].hasDescriptions = false; - photoAnnotations[currentPhoto].descriptionPosition = { - x: 10, - y: 10, - }; - photoAnnotations[currentPhoto].descriptionSize = { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }; - if (descriptionTextbox) { - fabricCanvas.remove(descriptionTextbox); - descriptionTextbox = null; - } - } - - for (let partNumber in markerObjects) { - fabricCanvas.remove(markerObjects[partNumber]); - delete markerObjects[partNumber]; - } - markerObjects = {}; - - const canvas = document.getElementById("photoCanvas"); - const ctx = canvas.getContext("2d"); - canvas.width = photoData.naturalWidth; - canvas.height = photoData.naturalHeight; - canvas.style.width = `${photoData.displayWidth}px`; - canvas.style.height = `${photoData.displayHeight}px`; - ctx.clearRect(0, 0, canvas.width, canvas.height); - if ($("#samplePhoto")[0].naturalWidth) { - ctx.drawImage( - $("#samplePhoto")[0], - 0, - 0, - canvas.width, - canvas.height, - ); - } - updateMarkers(); - if (photoAnnotations[currentPhoto]?.hasDescriptions) { - updateDescriptions(); - } - } - - function undoLastMarker() { - const currentPhoto = $("#samplePhoto").attr("src"); - if ( - photoAnnotations[currentPhoto] && - photoAnnotations[currentPhoto].markers.length > 0 - ) { - const lastMarker = photoAnnotations[currentPhoto].markers.pop(); - if (markerObjects[lastMarker.partNumber]) { - fabricCanvas.remove(markerObjects[lastMarker.partNumber]); - delete markerObjects[lastMarker.partNumber]; - fabricCanvas.renderAll(); - } - markUnsaved(); - } - } - - $("#addDescriptionsBtn").on("click", function () { - const currentPhoto = $("#samplePhoto").attr("src"); - if (!photoAnnotations[currentPhoto]) { - photoAnnotations[currentPhoto] = { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - } - photoAnnotations[currentPhoto].hasDescriptions = true; - updateDescriptions(); - markUnsaved(); - }); - - $("#removeAnnotationsBtn").on("click", function () { - clearCanvasMarkers(true); - }); - - $("#undoMarkerBtn").on("click", undoLastMarker); - - // =================== - // SAVE PHOTO - // =================== - $("#savePhotoBtn").on("click", function () { - console.log("savePhotoBtn clicked"); - - if (!$("#samplePhoto").attr("src")) { - console.log("No image source found"); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - if (!fabricCanvas) { - console.log("fabricCanvas is undefined"); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - const canvas = document.getElementById("photoCanvas"); - const ctx = canvas.getContext("2d"); - const img = $("#samplePhoto")[0]; - - console.log( - "Image loaded:", - img.complete, - "Natural width:", - img.naturalWidth, - ); - - if (!img.complete || img.naturalWidth === 0) { - console.log("Image not loaded correctly"); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - console.log( - "Setting canvas dimensions:", - photoData.naturalWidth, - photoData.naturalHeight, - ); - canvas.width = photoData.naturalWidth; - canvas.height = photoData.naturalHeight; - ctx.drawImage(img, 0, 0, canvas.width, canvas.height); - - console.log("Rendering Fabric canvas"); - try { - const fabricDataURL = fabricCanvas.toDataURL({ - format: "png", - multiplier: 1 / photoData.scale, - }); - console.log( - "Fabric DataURL generated, length:", - fabricDataURL.length, - ); - - const tempImg = new Image(); - tempImg.src = fabricDataURL; - tempImg.onload = function () { - console.log("Drawing Fabric overlay on canvas"); - ctx.drawImage(tempImg, 0, 0, canvas.width, canvas.height); - - fetch(fabricDataURL) - .then((res) => res.blob()) - .then((blob) => { - console.log("Fabric blob generated, size:", blob.size); - finalizeSave(blob); - }) - .catch((err) => { - console.log("Error converting DataURL to Blob:", err); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }); - }; - tempImg.onerror = function () { - console.log("Error loading Fabric overlay image"); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }; - } catch (e) { - console.log("Error generating Fabric DataURL:", e); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - function finalizeSave(fabricBlob) { - console.log("Finalizing save"); - canvas.toBlob( - function (blob) { - if (!blob) { - console.log("Failed to generate final blob"); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - - console.log("Final blob generated, size:", blob.size); - const timestamp = new Date() - .toISOString() - .replace(/[:.]/g, "-"); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const id = iddatadb || idquotations; - const endpoint = idquotations - ? "save_annotated_photo_quotation.php" - : "save_annotated_photo.php"; - const finalName = `photo_${id}_${timestamp}.png`; - - console.log( - "Sending AJAX request to:", - endpoint, - "with filename:", - finalName, - "and ID:", - id, - ); - - const formData = new FormData(); - formData.append("file", blob, finalName); - formData.append("filename", finalName); - formData.append( - idquotations ? "idquotations" : "iddatadb", - id, - ); - - $.ajax({ - url: endpoint, - method: "POST", - data: formData, - processData: false, - contentType: false, - success: function (response) { - console.log("AJAX success:", response); - if (response.success) { - const successMsg = $( - '", - ); - $("#partsModal .modal-body").prepend( - successMsg, - ); - setTimeout(function () { - successMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - - const photoSelector = $("#photoSelector"); - if (photoSelector.length > 0) { - const newPhotoPath = response.file_path; - const newPhotoName = newPhotoPath - .split("/") - .pop(); - const optionCount = - photoSelector.find("option").length; - - const newOption = $("") - .val(newPhotoPath) - .text( - `Photo ${optionCount + 1} - ${newPhotoName}`, - ); - photoSelector.append(newOption); - - const firstPhotoPath = photoSelector - .find("option:first") - .val(); - photoSelector.val(firstPhotoPath); - - console.log( - "Loading first photo:", - firstPhotoPath, - ); - loadSinglePhoto(firstPhotoPath); - } else { - const currentPhoto = - $("#samplePhoto").attr("src"); - if (currentPhoto) { - console.log( - "Reloading current photo:", - currentPhoto, - ); - loadSinglePhoto(currentPhoto); - } - } - - const currentPhoto = - $("#samplePhoto").attr("src"); - - const newPhoto = response.file_path; - photoAnnotations[newPhoto] = { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - - photoAnnotations[currentPhoto] = { - markers: [], - hasDescriptions: false, - descriptionPosition: { x: 10, y: 10 }, - descriptionSize: { - width: photoData.displayWidth * 0.3, - height: photoData.displayHeight * 0.3, - }, - }; - - console.log("Clearing canvas and annotations"); - clearCanvasMarkers(true); - clearUnsaved(); - } else { - console.log( - "AJAX response error:", - response.message, - ); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - console.log( - "AJAX error:", - status, - error, - xhr.status, - ); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - }, - "image/png", - 0.9, - ); - } - }); - - // =================== - // HELPER FUNCTIONS - // =================== - function markUnsaved() { - if (!unsavedChanges) { - unsavedChanges = true; - $("#savePhotoBtn").addClass("unsaved").text("⚠️ Salva Modifiche"); - } - } - - function clearUnsaved() { - unsavedChanges = false; - $("#savePhotoBtn").removeClass("unsaved").text("Salva Foto"); - } - - $(document).on("input change", "#partsTableBody input", markUnsaved); - $(document).on("click", ".add-row, .add-mix-row, .remove-row", markUnsaved); -}); diff --git a/public/userarea/partsTable.js b/public/userarea/partsTable.js deleted file mode 100644 index b403360..0000000 --- a/public/userarea/partsTable.js +++ /dev/null @@ -1,2150 +0,0 @@ -$(document).ready(function () { - // =================== - // GLOBAL STATE - // =================== - let partMatrice = {}; - let unsavedChanges = false; - let matrici = []; - let macroMatrici = []; - let quotations = []; - - // --- ROW ID helpers: niente più cache impazzita di jQuery .data() --- - function getPartId($row) { - // Legge in ordine: cache jQuery, nostra cache, attributo - const d = $row.data("part-id"); - const ours = $row.data("__pid"); - const attr = $row.attr("data-part-id"); - - // Scegli il primo definito - const id = - d !== undefined - ? d - : ours !== undefined - ? ours - : attr !== undefined - ? attr - : null; - - // Normalizza: "new" o "" NON sono ID validi - return id === "new" || id === "" || id === null ? null : id; - } - - function setPartId($row, id) { - if (!id) return; - // Sincronizza TUTTO: attributo + cache jQuery + nostra cache - $row.attr("data-part-id", id); - $row.data("part-id", id); // <<< fondamentale per invalidare la cache di jQuery - $row.data("__pid", id); - } - - // =================== - // VOICE RECOGNITION SETUP - // =================== - const SpeechRecognition = - window.SpeechRecognition || window.webkitSpeechRecognition; - let recognition = null; - let isVoiceActive = false; - const magicWord = "salva"; - - if (SpeechRecognition) { - recognition = new SpeechRecognition(); - recognition.lang = "it-IT"; - recognition.continuous = true; - recognition.interimResults = false; - - recognition.onresult = function (event) { - const transcript = event.results[ - event.results.length - 1 - ][0].transcript - .trim() - .toLowerCase(); - const $currentRow = $("#partsTableBody tr:last"); - const $descriptionInput = $currentRow.find(".part-description"); - - if (transcript.includes(magicWord)) { - const cleanedTranscript = transcript - .replace(magicWord, "") - .trim(); - if (cleanedTranscript) { - $descriptionInput.val( - ( - $descriptionInput.val() + - " " + - cleanedTranscript - ).trim(), - ); - $descriptionInput.trigger("blur"); - } - const maxPartNumber = Math.max( - ...$("#partsTableBody tr") - .map(function () { - return ( - parseInt($(this).find(".part-number").val()) || - 0 - ); - }) - .get(), - ); - addNewRow(maxPartNumber + 1, false); // Aggiunge riga normale per riconoscimento vocale - const $newRow = $("#partsTableBody tr:last"); - $newRow.find(".part-description").focus(); - } else { - $descriptionInput.val( - ($descriptionInput.val() + " " + transcript).trim(), - ); - $descriptionInput.trigger("blur"); - } - }; - - recognition.onerror = function (event) { - if (event.error === "no-speech" || event.error === "aborted") { - if (isVoiceActive) recognition.start(); - } else { - alert("Errore nel riconoscimento vocale: " + event.error); - toggleVoiceRecognition(); - } - }; - - recognition.onend = function () { - if (isVoiceActive) recognition.start(); - }; - } else { - $("#toggleVoiceBtn").hide(); - } - - function toggleVoiceRecognition() { - if (!recognition) { - console.log("Voce non supportata dal browser"); - return; - } - isVoiceActive = !isVoiceActive; - const $btn = $("#toggleVoiceBtn"); - if (isVoiceActive) { - $btn.addClass("btn-danger").html( - ' Stop Voce', - ); - recognition.start(); - $("#partsTableBody tr:last").find(".part-description").focus(); - } else { - $btn.removeClass("btn-danger") - .addClass("btn-secondary") - .html(' Voce'); - recognition.stop(); - } - } - - $(document).on("click", "#toggleVoiceBtn", function (e) { - console.log("Clicked Voce - Evento triggerato"); - e.preventDefault(); - toggleVoiceRecognition(); - }); - - // =================== - // MODAL HANDLING - // =================== - function loadParts(iddatadb, idquotations, callback = null) { - if (iddatadb) { - if (matrici.length === 0) { - $.ajax({ - url: "get_matrici_db.php", - method: "GET", - dataType: "json", - success: function (data) { - matrici = data.value || []; - loadMacroMatrici(); - initializeGlobalSelect2(); - loadPhoto(iddatadb, idquotations); - loadExistingParts(iddatadb, idquotations, callback); - }, - error: function (xhr, status, error) { - matrici = []; - loadMacroMatrici(); - initializeGlobalSelect2(); - loadPhoto(iddatadb, idquotations); - loadExistingParts(iddatadb, idquotations, callback); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } else { - loadMacroMatrici(); - initializeGlobalSelect2(); - loadPhoto(iddatadb, idquotations); - loadExistingParts(iddatadb, idquotations, callback); - } - } else { - loadPhoto(iddatadb, idquotations); - loadExistingParts(iddatadb, idquotations, callback); - } - } - - // EVENTO PER APRIRE IL SECONDO MODALE - $(document).on("click", "#openAnnotationsBtn", function () { - console.log("Clic su Apri Annotazioni..."); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const trfHeader = $("#trfHeader").text(); - - console.log("Dati recuperati da partsModal:", { - iddatadb, - idquotations, - trfHeader, - }); - - const partsModal = bootstrap.Modal.getInstance( - document.getElementById("partsModal"), - ); - if (partsModal) { - partsModal.hide(); - } - - const annotationsModalElement = - document.getElementById("annotationsModal"); - if (annotationsModalElement) { - console.log("Elemento #annotationsModal trovato nel DOM."); - openAnnotationsModal(iddatadb, idquotations, trfHeader); - return; - } - - console.log("Caricamento dinamico di modal_annotations.php..."); - $.ajax({ - url: "modal_annotations.php", - method: "GET", - cache: false, - beforeSend: function () { - console.log("Inizio richiesta AJAX per modal_annotations.php"); - }, - success: function (response) { - console.log( - "modal_annotations.php caricato con successo:", - response.substring(0, 100) + "...", - ); - $("#annotationsModalContainer").html(response); - - const annotationsModalElementAfterLoad = - document.getElementById("annotationsModal"); - if (!annotationsModalElementAfterLoad) { - console.error( - "Errore: #annotationsModal non trovato nel DOM dopo il caricamento.", - ); - alert( - "Errore: Il modale delle annotazioni non è stato caricato correttamente. Controlla il contenuto di modal_annotations.php.", - ); - return; - } - - openAnnotationsModal(iddatadb, idquotations, trfHeader); - }, - error: function (xhr, status, error) { - console.error( - "Errore nel caricamento di modal_annotations.php:", - { - status: status, - statusCode: xhr.status, - error: error, - responseText: xhr.responseText, - }, - ); - alert( - "Errore nel caricamento del modale delle annotazioni: " + - error + - " (Codice: " + - xhr.status + - ")", - ); - }, - }); - }); - - function openAnnotationsModal(iddatadb, idquotations, trfHeader) { - console.log("Tentativo di aprire annotationsModal con:", { - iddatadb, - idquotations, - trfHeader, - }); - const annotationsModalElement = - document.getElementById("annotationsModal"); - if (!annotationsModalElement) { - console.error( - "Elemento #annotationsModal non trovato nel DOM durante openAnnotationsModal.", - ); - alert( - "Errore: Modale annotazioni non trovato dopo il caricamento.", - ); - return; - } - - if (typeof window.initAnnotationsModal === "function") { - console.log("Chiamata a window.initAnnotationsModal..."); - window.initAnnotationsModal(iddatadb, idquotations, trfHeader); - } else { - console.error( - "initAnnotationsModal non definito. Verifica che annotationsModal.js sia caricato correttamente.", - ); - alert( - "Errore: Funzione initAnnotationsModal non trovata. Controlla che annotationsModal.js sia incluso correttamente.", - ); - } - } - - $("#partsModal").on("hide.bs.modal", function (e) { - if ( - unsavedChanges && - !confirm("Hai modifiche non salvate. Vuoi davvero uscire?") - ) { - e.preventDefault(); - } - }); - - $("#partsModal").on("hidden.bs.modal", function () { - partMatrice = {}; - unsavedChanges = false; - matrici = []; - macroMatrici = []; - $("#photoSelectorContainer").empty().hide(); - $("#samplePhoto").attr("src", ""); - $("#partsTableBody").empty(); - $("#global-matrice").empty(); - $("#macro-matrice-filter").empty(); - $(".temp-alert").remove(); - $(".modal-backdrop").remove(); - $("body").removeClass("modal-open").css("padding-right", ""); - $(":focus").blur(); - }); - - // =================== - // PHOTO LOADERS - // =================== - function loadPhoto(iddatadb, idquotations) { - const currentPhoto = $("#samplePhoto").attr("src"); - const endpoint = idquotations - ? "load_photo_quotation.php" - : "load_photo.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - $.ajax({ - url: endpoint, - method: "GET", - data: data, - success: function (response) { - if (response.success) { - if (response.photos && response.photos.length > 1) { - showPhotoSelector(response.photos, currentPhoto); - } else if ( - response.photos && - response.photos.length === 1 - ) { - loadSinglePhoto(response.photos[0]); - } else { - $("#samplePhoto").attr("src", ""); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } - - function showPhotoSelector(photos, selected = null) { - const selectorContainer = $("#photoSelectorContainer"); - selectorContainer.empty().show(); - const selector = $( - '', - ); - photos.forEach((photo, index) => { - const photoName = photo.split("/").pop(); - const option = $("") - .val(photo) - .text(`Photo ${index + 1} - ${photoName}`); - selector.append(option); - }); - selector.on("change", function () { - loadSinglePhoto($(this).val()); - }); - selectorContainer.append(selector); - const photoToSelect = - selected && photos.includes(selected) ? selected : photos[0]; - if (photoToSelect) { - selector.val(photoToSelect); - loadSinglePhoto(photoToSelect); - } - } - - function loadSinglePhoto(photoPath) { - const img = $("#samplePhoto"); - img.off("load").attr("src", photoPath); - } - - // =================== - // DOWNLOAD PHOTO - // =================== - $(document).on("click", "#downloadPhotoBtn", function (e) { - console.log("Clicked Download Photo - Evento triggerato"); - e.preventDefault(); - const photoSrc = $("#samplePhoto").attr("src"); - if (!photoSrc) { - console.log("Nessuna foto caricata"); - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - return; - } - const photoName = photoSrc.split("/").pop(); - const link = document.createElement("a"); - link.href = photoSrc; - link.download = photoName; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - console.log("Download avviato per:", photoSrc); - }); - - // =================== - // PARTS TABLE - // =================== - $(document).on("click", ".add-row-global", function (e) { - e.preventDefault(); - const maxPartNumber = Math.max( - ...$("#partsTableBody tr") - .map(function () { - return parseInt($(this).find(".part-number").val()) || 0; - }) - .get(), - ); - addNewRow(maxPartNumber + 1, false); // Riga normale - }); - - $(document).on("click", ".add-mix-global", function (e) { - e.preventDefault(); - - const maxPartNumber = Math.max( - ...$("#partsTableBody tr") - .map(function () { - return parseInt($(this).find(".part-number").val()) || 0; - }) - .get(), - ); - - // Crea la riga Mix - addNewRow(maxPartNumber + 1, true); - const $mixRow = $("#partsTableBody tr:last"); - - // Consenti SOLO ora la creazione (INSERT) della riga Mix - $mixRow.data("allowCreateMix", true); - - // esegue SUBITO l'INSERT così ottieni part-id - saveRow($mixRow); - }); - - function extractPartId(response) { - // prova i campi più comuni - if (response == null) return null; - - if (response.part_id) return response.part_id; - if (response.id) return response.id; - if (response.insert_id) return response.insert_id; - if (response.lastId) return response.lastId; - - // array di id - if (Array.isArray(response.part_ids) && response.part_ids[0]) { - return response.part_ids[0]; - } - - // oggetti annidati - if (response.parts && response.parts[0]) { - if (response.parts[0].id) return response.parts[0].id; - if (response.parts[0].part_id) return response.parts[0].part_id; - if (response.parts[0].insert_id) return response.parts[0].insert_id; - } - - // altri possibili nomi dal backend - if (response.new_id) return response.new_id; - if (response.partId) return response.partId; - - return null; - } - - function saveRow($row) { - const partNumber = $row.find(".part-number").val(); - const partDescription = $row.find(".part-description").val().trim(); - const dateexpiry = $row.find(".part-dateexpiry").val(); - const note = $row.data("note") || null; - const $saveStatus = $row.find(".save-status"); - const $saveLoading = $row.find(".save-loading"); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const isMix = partDescription.startsWith("Mix") ? "Y" : "N"; - let partId = getPartId($row); - if (partId === "new") partId = null; // difesa extra (non dovrebbe più servire, ma sicura) - const endpoint = idquotations - ? "save_parts_quotation.php" - : "save_parts.php"; - const data = idquotations ? { idquotations } : { iddatadb }; - - // Evita salvataggi concorrenti - if ($row.data("saving") === true) return; - - // Blocca INSERT del Mix se non esplicitamente richiesta - if (isMix === "Y" && !partId && $row.data("allowCreateMix") !== true) { - return; - } - - $row.data("saving", true); - - if (partDescription && (iddatadb || idquotations)) { - $saveLoading.show(); - $saveStatus.hide(); - - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ - ...data, - parts: [ - { - id: partId, - part_number: partNumber, - part_description: partDescription, - mix: isMix, - dateexpiry: dateexpiry || null, - note: note, - }, - ], - }), - contentType: "application/json", - - success: function (response) { - // assegna ID appena arriva (robusto) - if (response.success) { - const newId = extractPartId(response); - if (newId) { - setPartId($row, newId); - } else { - console.warn( - "Parte salvata ma ID non presente nella risposta. Ricarico parti per sincronizzare gli ID.", - ); - loadExistingParts(iddatadb, idquotations); // <<< ORA ANCHE PER RIGHE NORMALI - } - } - - $row.data("saving", false); - $row.removeData("allowCreateMix"); - - // ora che l'ID c'è di sicuro, sblocco gli update pendenti (es. M+) - $row.trigger("row:saved"); - - $saveLoading.hide(); - if (response.success) { - $saveStatus.show(); - setTimeout(() => $saveStatus.hide(), 2000); - - if (!$("#quotationeBtn").hasClass('d-none')) $("#quotationeBtn").addClass("d-none"); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(() => { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - - error: function (xhr, status, error) { - $row.data("saving", false); - $row.removeData("allowCreateMix"); - $saveLoading.hide(); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(() => { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } - } - - $(document).on("click", ".add-mix-row", function (e) { - e.preventDefault(); - - const $srcRow = $(this).closest("tr"); - const partDescription = $srcRow.find(".part-description").val().trim(); - if (!partDescription) { - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout( - () => - errorMsg.fadeOut(500, function () { - $(this).remove(); - }), - 5000, - ); - return; - } - - let $mixRow = $("#partsTableBody tr") - .filter(function () { - return $(this) - .find(".part-description") - .val() - .trim() - .startsWith("Mix"); - }) - .last(); - - // Se non esiste una riga Mix, ne creo una e la INSERISCO SUBITO (come fa il bottone in header) - if ($mixRow.length === 0) { - const maxPartNumber = Math.max( - ...$("#partsTableBody tr") - .map(function () { - return ( - parseInt($(this).find(".part-number").val()) || 0 - ); - }) - .get(), - ); - - addNewRow(maxPartNumber + 1, true); - $mixRow = $("#partsTableBody tr:last"); - $mixRow.find(".part-description").val(`Mix ${partDescription}`); - - // Consenti la creazione (INSERT) della riga Mix e salvala subito - $mixRow.data("allowCreateMix", true); - - saveRow($mixRow); // -> INSERT - return; // la descrizione include già l'elemento appena aggiunto - } - - // Aggiorna la descrizione del Mix esistente - const currentMix = $mixRow.find(".part-description").val().trim(); - let newDesc = currentMix; - if (currentMix === "Mix") newDesc = currentMix + " " + partDescription; - else if (!currentMix.includes(partDescription)) - newDesc = currentMix + " + " + partDescription; - - $mixRow.find(".part-description").val(newDesc); - - // Se il Mix è già in salvataggio (INSERT o UPDATE in corso), accodiamo un solo UPDATE - if ($mixRow.data("saving") === true) { - // evita più code accumulate - if (!$mixRow.data("pendingUpdate")) { - $mixRow.data("pendingUpdate", true); - $mixRow.one("row:saved", function () { - $mixRow.removeData("pendingUpdate"); - // ora che saving è false, salviamo l'ultima descrizione impostata - saveRow($mixRow); - }); - } - } else { - // libero: salva subito - saveRow($mixRow); - } - }); - - function addNewRow(nextPartNumber, isMix = false) { - const description = isMix ? "Mix" : ""; - const newRow = ` - - - - -
              - - -
              - - - - - - - - - - `; - $("#partsTableBody").append(newRow); - const $select = $("#partsTableBody tr:last .part-matrice"); - const selectedMacro = $("#macro-matrice-filter").val() || ""; - initializeSelect2($select, nextPartNumber, "", null, selectedMacro); - updateRowButtons(); - markUnsaved(); - } - - // =================== - // NOTE HANDLING - // =================== - $(document).on("click", ".note-btn", function () { - const $row = $(this).closest("tr"); - const partId = getPartId($row); - const note = $row.data("note") || ""; - const $noteModal = $("#noteModal"); - $noteModal.find(".part-note").val(note); - $noteModal.data("part-id", partId); - $noteModal.data("row", $row); - const modalInstance = new bootstrap.Modal($noteModal[0], { - backdrop: "static", - keyboard: false, - }); - modalInstance.show(); - }); - - $(document).on("click", ".save-note-btn", function () { - const $noteModal = $("#noteModal"); - const $row = $noteModal.data("row"); - const partId = $noteModal.data("part-id"); - const note = $noteModal.find(".part-note").val().trim(); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "save_parts_quotation.php" - : "save_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - - // Raccogli tutti i dati della riga per evitare sovrascritture - const partNumber = $row.find(".part-number").val(); - const partDescription = $row.find(".part-description").val().trim(); - const mix = partDescription.startsWith("Mix") ? "Y" : "N"; - const idmatrice = $row.find(".part-matrice").val() || null; - const dateexpiry = $row.find(".part-dateexpiry").val() || null; - - if (partId && partId !== "new") { - const $saveStatus = $row.find(".save-status"); - const $saveLoading = $row.find(".save-loading"); - $saveLoading.show(); - $saveStatus.hide(); - - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ - ...data, - parts: [ - { - id: partId, - part_number: partNumber, - part_description: partDescription, - mix: mix, - idmatrice: idmatrice, - note: note || null, - dateexpiry: dateexpiry, - }, - ], - }), - contentType: "application/json", - success: function (response) { - $saveLoading.hide(); - if (response.success) { - $row.data("note", note); - $row.find(".note-btn").toggleClass("has-note", !!note); - $saveStatus.show(); - setTimeout(() => $saveStatus.hide(), 2000); - bootstrap.Modal.getInstance( - document.getElementById("noteModal"), - ).hide(); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - $saveLoading.hide(); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } else { - $row.data("note", note); - $row.find(".note-btn").toggleClass("has-note", !!note); - bootstrap.Modal.getInstance( - document.getElementById("noteModal"), - ).hide(); - markUnsaved(); - } - }); - - // =================== - // DATEEXPIRY HANDLING - // =================== - $(document).on("change", ".part-dateexpiry", function () { - const $input = $(this); - const $row = $input.closest("tr"); - const partId = getPartId($row); - const dateexpiry = $input.val(); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "save_parts_quotation.php" - : "save_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - - // Raccogli tutti i dati della riga per evitare sovrascritture - const partNumber = $row.find(".part-number").val(); - const partDescription = $row.find(".part-description").val().trim(); - const mix = partDescription.startsWith("Mix") ? "Y" : "N"; - const idmatrice = $row.find(".part-matrice").val() || null; - const note = $row.data("note") || null; - - if (partId && partId !== "new") { - const $saveStatus = $row.find(".save-status"); - const $saveLoading = $row.find(".save-loading"); - $saveLoading.show(); - $saveStatus.hide(); - - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ - ...data, - parts: [ - { - id: partId, - part_number: partNumber, - part_description: partDescription, - mix: mix, - idmatrice: idmatrice, - note: note, - dateexpiry: dateexpiry || null, - }, - ], - }), - contentType: "application/json", - success: function (response) { - $saveLoading.hide(); - if (response.success) { - $saveStatus.show(); - setTimeout(() => $saveStatus.hide(), 2000); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - $saveLoading.hide(); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } else { - markUnsaved(); - } - }); - - // =================== - // OTHER TABLE HANDLERS - // =================== - function updateRowButtons() { - const rowCount = $("#partsTableBody tr").length; - $("#partsTableBody tr").each(function () { - const $row = $(this); - $row.find(".remove-row").css( - "display", - rowCount > 1 ? "inline-block" : "none", - ); - }); - } - - $(document).on("click", ".remove-row", function (e) { - e.preventDefault(); - console.log("Clic su .remove-row rilevato"); // Debug: verifica clic - const $row = $(this).closest("tr"); - const partId = $row.data("part-id"); - const partNumber = $row.find(".part-number").val(); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "delete_part_quotation.php" - : "delete_part.php"; - - // Verifica se il modale esiste - const $modal = $("#confirmDeleteModal"); - if ($modal.length) { - try { - // Inizializza il modale Bootstrap in modo esplicito - const modalInstance = new bootstrap.Modal($modal[0], { - backdrop: "static", - keyboard: false, - }); - // Associa l'handler al pulsante Elimina - $("#confirmDeleteBtn") - .off("click") - .on("click", function () { - if (partId && partId !== "new") { - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ part_id: partId }), - contentType: "application/json", - success: function (response) { - if (response.success) { - $row.remove(); - delete partMatrice[partNumber]; - updateRowButtons(); - markUnsaved(); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend( - errorMsg, - ); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - modalInstance.hide(); - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend( - errorMsg, - ); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - modalInstance.hide(); - }, - }); - } else { - $row.remove(); - delete partMatrice[partNumber]; - updateRowButtons(); - markUnsaved(); - modalInstance.hide(); - } - }); - // Mostra il modale - modalInstance.show(); - } catch (error) { - console.error("Errore nell'apertura del modale:", error); - alert( - "Errore: Impossibile aprire il modale di conferma. Dettagli: " + - error.message, - ); - // Fallback con confirm nativo - if (confirm("Sei sicuro di voler eliminare questa parte?")) { - if (partId && partId !== "new") { - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ part_id: partId }), - contentType: "application/json", - success: function (response) { - if (response.success) { - $row.remove(); - delete partMatrice[partNumber]; - updateRowButtons(); - markUnsaved(); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend( - errorMsg, - ); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } else { - $row.remove(); - delete partMatrice[partNumber]; - updateRowButtons(); - markUnsaved(); - } - } - } - } else { - console.error("Modale #confirmDeleteModal non trovato nel DOM"); - alert("Errore: Modale di conferma non trovato. Verifica l'HTML."); - // Fallback con confirm nativo - if (confirm("Sei sicuro di voler eliminare questa parte?")) { - if (partId && partId !== "new") { - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ part_id: partId }), - contentType: "application/json", - success: function (response) { - if (response.success) { - $row.remove(); - delete partMatrice[partNumber]; - updateRowButtons(); - markUnsaved(); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } else { - $row.remove(); - delete partMatrice[partNumber]; - updateRowButtons(); - markUnsaved(); - } - } - } - }); - - $(document).on("blur", ".part-description, .part-number", function () { - saveRow($(this).closest("tr")); - }); - - function loadExistingParts(iddatadb, idquotations, callback = null) { - const endpoint = idquotations - ? "load_parts_quotation.php" - : "load_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - $.ajax({ - url: endpoint, - method: "GET", - data: data, - success: function (response) { - $("#partsTableBody").empty(); - if ( - response.success && - response.parts && - response.parts.length > 0 - ) { - response.parts.forEach((part) => { - console.log( - "Caricamento parte:", - part.id, - "Numero:", - part.part_number, - "Descrizione:", - part.part_description, - "idmatrice:", - part.idmatrice || "non definito", - "note:", - part.note || "non definito", - "dateexpiry:", - part.dateexpiry || "non definito", - ); - // Escape HTML per evitare problemi con caratteri speciali - const escapedDescription = $("
              ") - .text(part.part_description || "") - .html(); - const escapedNote = part.note - ? $("
              ").text(part.note).html() - : ""; - const newRow = ` - - - - -
              - - -
              - - - - - - - - - - `; - $("#partsTableBody").append(newRow); - const $select = $("#partsTableBody").find( - `tr[data-part-id="${part.id}"] .part-matrice`, - ); - const selectedMacro = - $("#macro-matrice-filter").val() || ""; - initializeSelect2( - $select, - part.part_number, - part.id, - part.idmatrice || null, - selectedMacro, - ); - if (part.idmatrice) { - partMatrice[part.part_number] = part.idmatrice; - } - }); - } else { - addNewRow(1, false); // Riga iniziale normale - $("#quotationeBtn").removeClass("d-none"); - } - updateRowButtons(); - - if (callback) callback(); - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - addNewRow(1, false); // Riga iniziale normale - }, - }); - } - - function loadMacroMatrici() { - $.ajax({ - url: "get_macro_matrici.php", - method: "GET", - dataType: "json", - success: function (data) { - macroMatrici = data.value || []; - initializeMacroMatriceFilter(); - }, - error: function (xhr, status, error) { - console.error( - "Errore nel caricamento delle MacroMatrici:", - error, - ); - macroMatrici = []; - initializeMacroMatriceFilter(); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } - - function initializeMacroMatriceFilter() { - const $select = $("#macro-matrice-filter"); - if ($select.length === 0) return; // Ignora se il filtro non è presente nell'HTML - if (typeof $.fn.select2 === "undefined") { - $select.replaceWith( - '', - ); - return; - } - - // Popola il dropdown MacroMatrice - const options = [ - { id: "", text: "Tutte le MacroMatrici" }, - ...macroMatrici.map(function (macro) { - return { id: macro, text: macro }; - }), - ]; - - // Distrugge Select2 esistente, se presente - if ($select.hasClass("select2-hidden-accessible")) { - $select.select2("destroy"); - } - - $select.empty().select2({ - placeholder: "Seleziona MacroMatrice", - allowClear: true, - data: options, - dropdownParent: $("#partsModal"), - }); - - $select.on("change", function () { - const selectedMacro = $(this).val() || ""; - console.log("Filtro MacroMatrice cambiato:", selectedMacro); - // Aggiorna global-matrice - initializeGlobalSelect2(selectedMacro); - // Aggiorna tutti i part-matrice - $("#partsTableBody .part-matrice").each(function () { - const $partSelect = $(this); - const partNumber = $partSelect - .closest("tr") - .find(".part-number") - .val(); - const partId = $partSelect.closest("tr").data("part-id"); - const currentValue = - $partSelect.val() || partMatrice[partNumber] || null; - initializeSelect2( - $partSelect, - partNumber, - partId, - currentValue, - selectedMacro, - true - ); - }); - }); - } - - function initializeGlobalSelect2(selectedMacro = null) { - const $select = $("#global-matrice"); - if (typeof $.fn.select2 === "undefined") { - $select.replaceWith( - '', - ); - return; - } - - // Filtra le matrici in base alla MacroMatrice selezionata - const filteredMatrici = selectedMacro - ? matrici.filter( - (matrice) => matrice.MacroMatrice === selectedMacro, - ) - : matrici; - - // Crea opzioni per Select2 - const options = filteredMatrici.map(function (matrice) { - return { id: matrice.IdMatrice, text: matrice.NomeMatrice }; - }); - - // Memorizza il valore corrente - const currentValue = $select.val(); - - // Distrugge Select2 esistente, se presente - if ($select.hasClass("select2-hidden-accessible")) { - $select.select2("destroy"); - } - - // Inizializza Select2 - $select.empty().select2({ - placeholder: filteredMatrici.length - ? "Seleziona matrice globale" - : "Nessuna matrice disponibile", - allowClear: true, - data: options, - dropdownParent: $("#partsModal"), - minimumResultsForSearch: 0, // Abilita ricerca senza limite minimo di caratteri - matcher: function (params, data) { - if (!params.term) return data; // Mostra tutte le opzioni se non c'è termine di ricerca - const term = params.term.toUpperCase(); - if (data.text.toUpperCase().indexOf(term) >= 0) return data; - return null; - }, - }); - - // Ripristina il valore corrente se valido - if ( - currentValue && - filteredMatrici.some((m) => m.IdMatrice == currentValue) - ) { - $select.val(currentValue).trigger("change"); - } else if (filteredMatrici.length === 0) { - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - } - - function initializeSelect2( - $select, - partNumber, - partId, - idmatrice, - selectedMacro = null, - fromFilter = false - ) { - if (typeof $.fn.select2 === "undefined") { - $select.replaceWith( - '', - ); - return; - } - - // Filtra le matrici in base alla MacroMatrice selezionata - const filteredMatrici = selectedMacro - ? matrici.filter((m) => m.MacroMatrice === selectedMacro) - : matrici; - - // Crea opzioni per Select2, includendo il valore pre-selezionato se non è nel filtro - let options = filteredMatrici.map(function (matrice) { - return { id: matrice.IdMatrice, text: matrice.NomeMatrice }; - }); - - // Se idmatrice esiste ed è fuori dal filtro, aggiungilo come opzione - if ( - idmatrice && - !filteredMatrici.some((m) => m.IdMatrice == idmatrice) - ) { - const selectedMatrice = matrici.find( - (m) => m.IdMatrice == idmatrice, - ); - if (selectedMatrice) { - options.push({ - id: selectedMatrice.IdMatrice, - text: selectedMatrice.NomeMatrice, - }); - } - } - - // Memorizza il valore corrente - const currentValue = idmatrice || $select.val(); - - // Distrugge Select2 esistente, se presente - if ($select.hasClass("select2-hidden-accessible")) { - $select.select2("destroy"); - } - - // Inizializza Select2 - $select.empty().select2({ - placeholder: filteredMatrici.length - ? "Seleziona matrice" - : "Nessuna matrice disponibile", - allowClear: true, - data: options, - dropdownParent: $("#partsModal"), - minimumResultsForSearch: 0, // Abilita ricerca senza limite minimo di caratteri - matcher: function (params, data) { - if (!params.term) return data; // Mostra tutte le opzioni se non c'è termine di ricerca - const term = params.term.toUpperCase(); - if (data.text.toUpperCase().indexOf(term) >= 0) return data; - return null; - }, - }); - - // Ripristina il valore se valido - if (partId && partId !== "new" && currentValue) { - const matrice = matrici.find((m) => m.IdMatrice == currentValue); - if (matrice) { - const option = new Option( - matrice.NomeMatrice, - matrice.IdMatrice, - true, - true, - ); - - if (!fromFilter) $select.append(option).trigger("change"); - else $select.append(option); - - partMatrice[partNumber] = matrice.IdMatrice; - } else { - // Aggiusta valore non valido - if (!fromFilter) $select.val(null).trigger("change"); - - partMatrice[partNumber] = null; - } - } else { - $select.val(null).trigger("change", [{ skipHandler: true }]); - } - - $select.on("change", function (event, data) { - if (data && data?.skipHandler) return; - - const idmatrice = $(this).val(); - const $row = $(this).closest("tr"); - const partId = $row.data("part-id"); - const partNumber = $row.find(".part-number").val(); - const $saveStatus = $row.find(".save-status"); - const $saveLoading = $row.find(".save-loading"); - - partMatrice[partNumber] = idmatrice || null; - - if (partId && partId !== "new") { - $saveLoading.show(); - $saveStatus.hide(); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "save_matrice_quotation.php" - : "save_matrice.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ - ...data, - parts: [{ id: partId, idmatrice: idmatrice || null }], - }), - contentType: "application/json", - success: function (response) { - if (response.success) { - $saveLoading.hide(); - $saveStatus.show(); - setTimeout(() => $saveStatus.hide(), 2000); - } else { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - $saveLoading.hide(); - } - }, - error: function (xhr, status, error) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - $saveLoading.hide(); - }, - }); - } - }); - - // Mostra messaggio se non ci sono matrici - if (filteredMatrici.length === 0 && selectedMacro) { - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - - // Debug per verificare inizializzazione - console.log( - "Inizializzo Select2 per partId:", - partId, - "con idmatrice:", - idmatrice, - "Macro:", - selectedMacro, - ); - } - - $(document).on("click", ".propagate-matrice-btn", function () { - const $row = $(this).closest("tr"); - const globalVal = $("#global-matrice").val(); - if (globalVal) { - $row.find(".part-matrice").val(globalVal).trigger("change"); - } else { - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }); - - $(document).on("click", ".propagate-all-btn", function () { - const globalVal = $("#global-matrice").val(); - if (globalVal) { - $("#partsTableBody .part-matrice").val(globalVal).trigger("change"); - } else { - const errorMsg = $( - '', - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }); - - function renumberParts() { - console.log( - "Inizio rinumera parts, numero righe:", - $("#partsTableBody tr").length, - ); - const $rows = $("#partsTableBody tr"); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "renumber_parts_quotation.php" - : "renumber_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - let newPartMatrice = {}; - - let partsData = $rows - .map(function (index) { - const $row = $(this); - return { - partNumber: $row.find(".part-number").val(), - partDescription: $row - .find(".part-description") - .val() - .trim(), - partId: - $row.data("part-id") === "new" || - $row.data("part-id") === "" - ? null - : $row.data("part-id"), - note: $row.data("note") || null, - dateexpiry: $row.find(".part-dateexpiry").val() || null, - }; - }) - .get(); - - console.log("Parts to save prima di rinumerazione:", partsData); - - partsData.forEach((part, index) => { - const newNumber = index + 1; - newPartMatrice[newNumber] = partMatrice[part.partNumber] || null; - part.partNumber = newNumber; - }); - - $rows.each(function (index) { - $(this) - .find(".part-number") - .val(index + 1); - }); - - partMatrice = newPartMatrice; - - const partsToSave = partsData.map((part, index) => ({ - id: part.partId, - part_number: index + 1, - part_description: part.partDescription, - mix: part.partDescription.startsWith("Mix") ? "Y" : "N", - idmatrice: partMatrice[index + 1] || null, - note: part.note, - dateexpiry: part.dateexpiry, - })); - - console.log("Parts to save inviati al server:", partsToSave); - - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ ...data, parts: partsToSave }), - contentType: "application/json", - success: function (response) { - console.log("Risposta server:", response); - if (response.success && response.part_ids) { - $rows.each(function (index) { - const $row = $(this); - const newPartId = - response.part_ids[index] || $row.data("part-id"); - if (newPartId) { - $row.attr("data-part-id", newPartId).data( - "part-id", - newPartId, - ); - } - const $saveStatus = $row.find(".save-status"); - const $saveLoading = $row.find(".save-loading"); - $saveLoading.hide(); - $saveStatus.show(); - setTimeout(() => $saveStatus.hide(), 2000); - }); - $rows - .find(".part-number, .part-description") - .trigger("blur"); - unsavedChanges = false; - } else { - console.error("Errore risposta server:", response.message); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - console.error( - "Errore AJAX rinumerazione:", - error, - xhr.responseText, - ); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } - - $(document).on("click", "#renumberPartsBtn", function (e) { - console.log("Clicked Rinumera Parti - Evento triggerato"); - e.preventDefault(); - renumberParts(); - }); - - function markUnsaved() { - if (!unsavedChanges) { - unsavedChanges = true; - } - } - - $(document).on( - "input change", - "#partsTableBody input, #partsTableBody select", - markUnsaved, - ); - $(document).on( - "click", - ".add-row-global, .add-mix-global, .add-mix-row, .remove-row, .propagate-matrice-btn, .propagate-all-btn, .note-btn", - markUnsaved, - ); - - // Esporta la funzione loadParts per essere usata da import_Edit2.php - window.loadParts = loadParts; - - $(document).on("click", "#quotationeBtn", function () { - $("#addQuotationModal").modal("show"); - - if (quotations.length > 0) { - reloadQuotations(); - } else { - $.ajax({ - url: "load_quotations.php", - method: "GET", - success: function (response) { - quotations = response?.quotations || []; - - reloadQuotations(); - }, - error: function (xhr, status, error) { - console.error("Errore AJAX caricamento quotations:", error, xhr.responseText); - let message = ` - - `; - - $("#partsModal .modal-body").prepend(errorMsg); - - setTimeout(function () { - message.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }); - } - }); - - $(document).on("click", "#addQuotationBtn", function () { - const quotationId = $("#addQuotationSelect").val(); - - if (quotationId && confirm("Confermo di collegare la quotazione al campione?")) { - $("#addQuotationModal").modal("hide"); - - loadParts(null, quotationId, () => { - $("#quotationeBtn").addClass("d-none"); - - setTimeout(() => { - $("#partsTableBody tr").each(function () { - $(this).find(".save-loading").show(); - }); - - let photoList = $('#photoSelector option').map(function () { - return this.value?.split('/')?.pop(); - }).get(); - - if (!photoList.length) { - let path = $('#samplePhoto').attr("src")?.split('/')?.pop(); - - if (path) photoList = [path]; - } - - $.ajax({ - url: "save_parts_photo_iddatadb.php", - method: "POST", - data: JSON.stringify({ - iddatadb: $("#partsModal").data("iddatadb"), - photoList, - partIds: $('#partsTableBody tr').map(function () { - return $(this).data("part-id"); - }).get(), - }), - success: function () { - $("#partsTableBody tr").each(function () { - let $row = $(this); - let $saveStatus = $row.find(".save-status"); - let $saveLoading = $row.find(".save-loading"); - - $saveLoading.hide(); - $saveStatus.show(); - - setTimeout(() => $saveStatus.hide(), 2000); - }); - }, error: function (xhr, status, error) { - let message = ` - - `; - - $("#partsModal .modal-body").prepend(message); - - setTimeout(function () { - message.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }); - }, 100); - }); - } - }); - - function reloadQuotations() { - if (quotations.length > 0) { - $("#addQuotationSelect").empty(); - - $("#addQuotationSelect").append(""); - - quotations.forEach(quotation => { - if (quotation?.description) { - $("#addQuotationSelect").append(``); - } - }); - - $("#addQuotationSelect").select2(); - } - } -}); - -$(document).on("change", ".propagate-date-input", function () { - const dateexpiry = $(this).val(); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "save_parts_quotation.php" - : "save_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - - const partsToSave = []; - $("#partsTableBody tr").each(function () { - const $row = $(this); - const partId = $row.data("part-id"); - const partNumber = $row.find(".part-number").val(); - const partDescription = $row.find(".part-description").val().trim(); - const mix = partDescription.startsWith("Mix") ? "Y" : "N"; - const idmatrice = $row.find(".part-matrice").val() || null; - const note = $row.data("note") || null; - - partsToSave.push({ - id: partId && partId !== "new" ? partId : null, - part_number: partNumber, - part_description: partDescription, - mix: mix, - idmatrice: idmatrice, - note: note, - dateexpiry: dateexpiry || null, - }); - - if (partId && partId !== "new") { - $row.find(".save-loading").show(); - $row.find(".save-status").hide(); - } - }); - - if (partsToSave.length > 0) { - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ - ...data, - parts: partsToSave, - }), - contentType: "application/json", - success: function (response) { - $("#partsTableBody tr").each(function () { - const $row = $(this); - const partId = $row.data("part-id"); - if (partId && partId !== "new") { - $row.find(".save-loading").hide(); - $row.find(".save-status").show(); - setTimeout( - () => $row.find(".save-status").hide(), - 2000, - ); - } - $row.find(".part-dateexpiry").val(dateexpiry); - }); - if (!response.success) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - $("#partsTableBody tr").each(function () { - const $row = $(this); - $row.find(".save-loading").hide(); - }); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } else { - $("#partsTableBody tr").find(".part-dateexpiry").val(dateexpiry); - markUnsaved(); - } -}); - -$(document).on("click", ".propagate-note-btn", function () { - const $commonNoteModal = $("#commonNoteModal"); - $commonNoteModal.find(".part-note").val(""); - const modalInstance = new bootstrap.Modal($commonNoteModal[0], { - backdrop: "static", - keyboard: false, - }); - modalInstance.show(); -}); - -$(document).on("click", ".save-common-note-btn", function () { - const $commonNoteModal = $("#commonNoteModal"); - const note = $commonNoteModal.find(".part-note").val().trim(); - const iddatadb = $("#partsModal").data("iddatadb"); - const idquotations = $("#partsModal").data("idquotations"); - const endpoint = idquotations - ? "save_parts_quotation.php" - : "save_parts.php"; - const data = idquotations - ? { idquotations: idquotations } - : { iddatadb: iddatadb }; - - const partsToSave = []; - $("#partsTableBody tr").each(function () { - const $row = $(this); - const partId = $row.data("part-id"); - const partNumber = $row.find(".part-number").val(); - const partDescription = $row.find(".part-description").val().trim(); - const mix = partDescription.startsWith("Mix") ? "Y" : "N"; - const idmatrice = $row.find(".part-matrice").val() || null; - const dateexpiry = $row.find(".part-dateexpiry").val() || null; - - partsToSave.push({ - id: partId && partId !== "new" ? partId : null, - part_number: partNumber, - part_description: partDescription, - mix: mix, - idmatrice: idmatrice, - note: note || null, - dateexpiry: dateexpiry, - }); - - if (partId && partId !== "new") { - $row.find(".save-loading").show(); - $row.find(".save-status").hide(); - } - }); - - if (partsToSave.length > 0) { - $.ajax({ - url: endpoint, - method: "POST", - data: JSON.stringify({ - ...data, - parts: partsToSave, - }), - contentType: "application/json", - success: function (response) { - $("#partsTableBody tr").each(function () { - const $row = $(this); - const partId = $row.data("part-id"); - if (partId && partId !== "new") { - $row.find(".save-loading").hide(); - $row.find(".save-status").show(); - setTimeout( - () => $row.find(".save-status").hide(), - 2000, - ); - } - $row.data("note", note); - $row.find(".note-btn").toggleClass("has-note", !!note); - }); - bootstrap.Modal.getInstance( - document.getElementById("commonNoteModal"), - ).hide(); - if (!response.success) { - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - } - }, - error: function (xhr, status, error) { - $("#partsTableBody tr").each(function () { - const $row = $(this); - $row.find(".save-loading").hide(); - }); - const errorMsg = $( - '", - ); - $("#partsModal .modal-body").prepend(errorMsg); - setTimeout(function () { - errorMsg.fadeOut(500, function () { - $(this).remove(); - }); - }, 5000); - }, - }); - } else { - $("#partsTableBody tr").each(function () { - const $row = $(this); - $row.data("note", note); - $row.find(".note-btn").toggleClass("has-note", !!note); - }); - bootstrap.Modal.getInstance( - document.getElementById("commonNoteModal"), - ).hide(); - markUnsaved(); - } -}); - -$(document).on("click", "#showHideImageBtn", function () { - let mainRow = $(this).closest(".parts-row"); - let photoContainer = mainRow.find(".col-md-3"); - let tableContainer = mainRow.find("#partsTable").closest("div[class*='col-md']"); - - if (photoContainer.hasClass("d-none")) { - photoContainer.removeClass("d-none"); - tableContainer.removeClass("col-md-12").addClass("col-md-9"); - $(this).html(""); - } else { - photoContainer.addClass("d-none"); - tableContainer.removeClass("col-md-9").addClass("col-md-12"); - $(this).html(""); - } -}); \ No newline at end of file diff --git a/public/userarea/parts_functions.php b/public/userarea/parts_functions.php deleted file mode 100644 index a9105d1..0000000 --- a/public/userarea/parts_functions.php +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/public/userarea/partsold.js b/public/userarea/partsold.js deleted file mode 100644 index 3cb0bfb..0000000 --- a/public/userarea/partsold.js +++ /dev/null @@ -1,668 +0,0 @@ -$(document).ready(function () { - console.log("parts.js caricato correttamente"); - - const partsButtons = document.querySelectorAll(".parts-btn"); - const partsModal = document.getElementById("partsModal"); - const overlay = document.querySelector(".overlay"); - - partsButtons.forEach((button) => { - button.addEventListener("click", function () { - console.log( - "Pulsante Parts cliccato, iddatadb:", - $(this).data("iddatadb"), - ); - const iddatadb = $(this).data("iddatadb"); - const rowIndex = $(this).data("row"); - console.log("Row index:", rowIndex); - const importRef = $("table tbody tr") - .eq(rowIndex) - .find("td") - .eq(1) - .text(); - console.log("ImportRef:", importRef); - const description = - $("table tbody tr").eq(rowIndex).find("td").eq(2).text() || - "Sconosciuto"; - console.log("Description:", description); - - $("#trfHeader").text(`${iddatadb} - ${importRef} - ${description}`); - $("#partsModal").data("iddatadb", iddatadb); - - if (partsModal) { - console.log( - "Tento di aprire il modal, bootstrap:", - typeof bootstrap !== "undefined" - ? "definito" - : "non definito", - ); - try { - console.log("Inizio try per creare modal instance"); - const modalInstance = new bootstrap.Modal(partsModal, { - focus: true, - }); // Forza la gestione del focus - console.log("Modal instance creata"); - console.log("Inizio show del modal"); - modalInstance.show(); - console.log("Modal mostrato"); - if (overlay) overlay.style.display = "none"; // Nascondi overlay solo se esiste - } catch (error) { - console.error("Errore nell'apertura del modal:", error); - } - } else { - console.error("Modal Parts non trovato"); - } - - console.log("Prima di chiamare loadPhoto e loadExistingParts"); - loadPhoto(iddatadb) - .then(() => { - console.log("loadPhoto completata"); - loadExistingParts(iddatadb) - .then(() => { - console.log("loadExistingParts completata"); - }) - .catch((error) => { - console.error( - "Errore in loadExistingParts:", - error, - ); - }); - }) - .catch((error) => { - console.error("Errore in loadPhoto:", error); - }); - console.log("Dopo l'avvio delle chiamate AJAX"); - }); - }); - - // Gestione della chiusura del modal Parts - if (closeBtn) { - closeBtn.addEventListener("click", function () { - partsModal.style.display = "none"; - overlay.style.display = "none"; // Nascondi overlay - document.body.style.pointerEvents = "auto"; // Riattiva la pagina - }); - } - - if (partsModal) { - window.addEventListener("click", function (event) { - if (event.target === partsModal) { - partsModal.style.display = "none"; - overlay.style.display = "none"; // Nascondi overlay - document.body.style.pointerEvents = "auto"; // Riattiva la pagina - } - }); - } - - function loadPhoto(iddatadb) { - console.log("Inizio loadPhoto per iddatadb:", iddatadb); - return $.ajax({ - url: "load_photo.php", - method: "GET", - data: { iddatadb: iddatadb }, - }) - .then(function (response) { - console.log("Risposta loadPhoto:", response); - if (response.success && response.file_path) { - const img = $("#samplePhoto"); - img.attr("src", response.file_path); - return new Promise((resolve) => { - img.on("load", function () { - const container = img.parent(); - const canvas = - document.getElementById("photoCanvas"); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img[0].naturalWidth; - const scaleY = - containerHeight / img[0].naturalHeight; - const scale = Math.min(scaleX, scaleY); - canvas.width = img[0].naturalWidth * scale; - canvas.height = img[0].naturalHeight * scale; - canvas.style.width = `${containerWidth}px`; - canvas.style.height = `${containerHeight}px`; - const ctx = canvas.getContext("2d"); - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.drawImage( - img.get(0), - 0, - 0, - canvas.width, - canvas.height, - ); - updateMarkers(); - resolve(); - }); - }); - } else { - $("#samplePhoto").attr("src", ""); - console.log( - "Nessuna foto trovata:", - response.message || "Nessun messaggio", - ); - return Promise.resolve(); // Risolvi comunque la promessa - } - }) - .catch(function (xhr, status, error) { - console.error("Errore in loadPhoto:", { - status, - error, - response: xhr.responseText, - }); - $("#samplePhoto").attr("src", ""); - alert("Errore nel caricamento della foto: " + error); - return Promise.reject(error); // Rifiuta la promessa in caso di errore - }); - } - - function addNewRow(nextPartNumber) { - const newRow = ` - - - - - - - - - - - `; - $("#partsTableBody").append(newRow); - updateRowButtons(); - } - - function updateRowButtons() { - const rowCount = $("#partsTableBody tr").length; - $("#partsTableBody tr").each(function (index) { - const $removeBtn = $(this).find(".remove-row"); - if (rowCount > 1) { - $removeBtn.show(); - } else { - $removeBtn.hide(); - } - }); - } - - $(document).on("click", ".add-row", function (e) { - e.preventDefault(); - console.log("Pulsante Aggiungi riga cliccato"); - const maxPartNumber = Math.max( - ...$("#partsTableBody tr") - .map(function () { - return parseInt($(this).find(".part-number").val()) || 0; - }) - .get(), - ); - addNewRow(maxPartNumber + 1); - updatePartsList(); - }); - - $(document).on("click", ".remove-row", function (e) { - e.preventDefault(); - console.log("Pulsante Rimuovi riga cliccato"); - const $row = $(this).closest("tr"); - const partId = $row.data("part-id"); - console.log("ID parte da eliminare:", partId); - - if (partId !== "new" && partId !== undefined && partId !== null) { - console.log("Procedo con la cancellazione dal database"); - $.ajax({ - url: "delete_part.php", - method: "POST", - data: JSON.stringify({ part_id: partId }), - contentType: "application/json", - beforeSend: function () { - console.log( - "Invio richiesta AJAX a delete_part.php con part_id:", - partId, - ); - }, - success: function (response) { - console.log("Risposta da delete_part.php:", response); - if (response.success) { - $row.remove(); - updateRowButtons(); - updatePartsList(); - clearCanvasMarkers(); - } else { - alert("Errore nell'eliminazione: " + response.message); - } - }, - error: function (xhr, status, error) { - console.log("Errore AJAX:", status, error); - alert( - "Errore nell'eliminazione: " + - error + - ". Stato: " + - xhr.status + - " - " + - xhr.responseText, - ); - }, - }); - } else { - console.log( - 'Riga non salvata nel database (partId = "new" o non definito), rimuovo solo visivamente', - ); - $row.remove(); - updateRowButtons(); - updatePartsList(); - } - }); - - $(document).on("blur", ".part-description, .part-number", function () { - const $input = $(this); - const $row = $input.closest("tr"); - const partNumber = $row.find(".part-number").val(); - const partDescription = $row.find(".part-description").val().trim(); - const $saveStatus = $row.find(".save-status"); - const $saveLoading = $row.find(".save-loading"); - const iddatadb = $("#partsModal").data("iddatadb"); - - console.log("Evento blur su input:", { partNumber, partDescription }); - - if (partDescription && iddatadb) { - $saveLoading.show(); - $saveStatus.hide(); - - $.ajax({ - url: "save_parts.php", - method: "POST", - data: JSON.stringify({ - iddatadb: iddatadb, - parts: [ - { - part_number: partNumber, - part_description: partDescription, - }, - ], - }), - contentType: "application/json", - success: function (response) { - if (response.success) { - if (response.part_id) { - $row.data("part-id", response.part_id); - console.log( - "Aggiornato partId della riga:", - response.part_id, - ); - } - $saveLoading.hide(); - $saveStatus.show(); - updatePartsList(); - setTimeout(() => $saveStatus.hide(), 2000); - } else { - alert("Errore nel salvataggio: " + response.message); - $saveLoading.hide(); - } - }, - error: function (xhr, status, error) { - alert("Errore nel salvataggio delle parti: " + error); - $saveLoading.hide(); - }, - }); - } - }); - - function loadExistingParts(iddatadb) { - console.log("Inizio loadExistingParts per iddatadb:", iddatadb); - return $.ajax({ - url: "load_parts.php", - method: "GET", - data: { iddatadb: iddatadb }, - }) - .then(function (response) { - console.log("Risposta loadExistingParts:", response); - if (response.success) { - $("#partsTableBody").empty(); - if (response.parts.length > 0) { - response.parts.forEach((part) => { - const newRow = ` - - - - - - - - - - - `; - $("#partsTableBody").append(newRow); - }); - } else { - addNewRow(1); - } - updateRowButtons(); - updatePartsList(); - } else { - console.log( - "Errore nel caricamento delle parti:", - response.message, - ); - addNewRow(1); - } - return Promise.resolve(); // Risolvi la promessa - }) - .catch(function (xhr, status, error) { - console.error("Errore in loadExistingParts:", { - status, - error, - response: xhr.responseText, - }); - alert("Errore nel caricamento delle parti: " + error); - addNewRow(1); - return Promise.reject(error); // Rifiuta la promessa in caso di errore - }); - } - - function updatePartsList() { - $("#partsList").empty(); - $("#partsTableBody tr").each(function () { - const partNumber = $(this).find(".part-number").val(); - const partDescription = $(this).find(".part-description").val(); - if (partNumber && partDescription) { - const listItem = `
            • ${partNumber} - ${partDescription}
            • `; - $("#partsList").append(listItem); - } - }); - } - - let selectedPartNumber = null; - let markers = []; - let descriptionPosition = { x: 10, y: 10 }; - let hasDescriptions = false; - - $("#partsList").on("click", "li", function () { - selectedPartNumber = $(this).data("part-number"); - console.log("Part number selezionato:", selectedPartNumber); - $(this).addClass("active").siblings().removeClass("active"); - }); - - const canvas = document.getElementById("photoCanvas"); - const ctx = canvas.getContext("2d"); - - $("#markerContainer").on("click", function (e) { - console.log("Click sul markerContainer rilevato"); - if (selectedPartNumber !== null) { - const img = $("#samplePhoto"); - const canvas = document.getElementById("photoCanvas"); - const rect = canvas.getBoundingRect(); - const container = img.parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img.get(0).naturalWidth; - const scaleY = containerHeight / img.get(0).naturalHeight; - const scale = Math.min(scaleX, scaleY); - const x = (e.clientX - rect.left) / scale; - const y = (e.clientY - rect.top) / scale; - - console.log("Coordinate cliccate (x, y):", x, y); - - const existingMarker = markers.find( - (m) => m.partNumber == selectedPartNumber, - ); - if (existingMarker) { - existingMarker.x = x; - existingMarker.y = y; - } else { - markers.push({ partNumber: selectedPartNumber, x, y }); - } - console.log("Markers aggiornati:", markers); - updateMarkers(); - if (hasDescriptions) { - drawDescriptions(descriptionPosition.x, descriptionPosition.y); - } - selectedPartNumber = null; - $("#partsList li").removeClass("active"); - } else { - console.log("Nessun part number selezionato"); - } - }); - - function updateMarkers() { - const img = $("#samplePhoto"); - const container = img.parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img.get(0).naturalWidth; - const scaleY = containerHeight / img.get(0).naturalHeight; - const scale = Math.min(scaleX, scaleY); - - const markerContainer = $("#markerContainer"); - markerContainer.empty(); - - markers.forEach((marker) => { - const scaledX = marker.x * scale; - const scaledY = marker.y * scale; - console.log( - "Aggiungo marker:", - marker.partNumber, - "a posizione (scaledX, scaledY):", - scaledX, - scaledY, - ); - const $marker = $( - `
              ${marker.partNumber}
              `, - ).css({ - left: scaledX - 8 + "px", - top: scaledY - 8 + "px", - }); - markerContainer.append($marker); - makeDraggable($marker, marker, scale); - }); - } - - function makeDraggable($element, item, scale) { - let isDragging = false; - let currentX = parseFloat($element.css("left")) || 0; - let currentY = parseFloat($element.css("top")) || 0; - let initialX, initialY; - - $element.on("mousedown", function (e) { - e.preventDefault(); - isDragging = true; - initialX = e.clientX - currentX; - initialY = e.clientY - currentY; - $element.css("z-index", 1001); - }); - - $(document).on("mousemove", function (e) { - if (isDragging) { - e.preventDefault(); - currentX = e.clientX - initialX; - currentY = e.clientY - initialY; - const container = $("#photoCanvas").parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const maxX = containerWidth - $element.width(); - const maxY = containerHeight - $element.height(); - - currentX = Math.max(0, Math.min(currentX, maxX)); - currentY = Math.max(0, Math.min(currentY, maxY)); - - $element.css({ - left: currentX + "px", - top: currentY + "px", - }); - - if (item.partNumber) { - item.x = (currentX + 8) / scale; - item.y = (currentY + 8) / scale; - } else { - descriptionPosition.x = (currentX + 5) / scale; - descriptionPosition.y = (currentY + 5) / scale; - } - } - }); - - $(document).on("mouseup", function () { - isDragging = false; - $element.css("z-index", 1000); - }); - } - - function drawDescriptions(x, y) { - const img = $("#samplePhoto"); - const container = img.parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img.get(0).naturalWidth; - const scaleY = containerHeight / img.get(0).naturalHeight; - const scale = Math.min(scaleX, scaleY); - - const partsList = []; - $("#partsTableBody tr").each(function () { - const partNumber = $(this).find(".part-number").val(); - const partDescription = $(this).find(".part-description").val(); - if (partNumber && partDescription) { - partsList.push(`${partNumber} ${partDescription}`); - } - }); - - const descriptionList = $("#descriptionList"); - descriptionList.empty(); - descriptionList.css({ - display: "block", - top: y * scale + "px", - left: x * scale + "px", - width: "200px", - }); - partsList.forEach((part) => { - descriptionList.append(`
              ${part}
              `); - }); - - updateMarkers(); - } - - function clearCanvasMarkers() { - markers = []; - hasDescriptions = false; - $("#descriptionList").css("display", "none"); - $("#markerContainer").empty(); - const canvas = document.getElementById("photoCanvas"); - const img = $("#samplePhoto"); - const ctx = canvas.getContext("2d"); - const container = img.parent(); - const containerWidth = container.width(); - const containerHeight = container.height(); - const scaleX = containerWidth / img.get(0).naturalWidth; - const scaleY = containerHeight / img.get(0).naturalHeight; - const scale = Math.min(scaleX, scaleY); - - canvas.width = img.get(0).naturalWidth * scale; - canvas.height = img.get(0).naturalHeight * scale; - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.drawImage(img.get(0), 0, 0, canvas.width, canvas.height); - } - - $("#addDescriptionsBtn").on("click", function () { - hasDescriptions = true; - descriptionPosition = { x: 10, y: 10 }; - drawDescriptions(descriptionPosition.x, descriptionPosition.y); - makeDraggable( - $("#descriptionList"), - descriptionPosition, - Math.min( - $("#photoCanvas").parent().width() / - $("#samplePhoto").get(0).naturalWidth, - $("#photoCanvas").parent().height() / - $("#samplePhoto").get(0).naturalHeight, - ), - ); - }); - - $("#removeAnnotationsBtn").on("click", function () { - clearCanvasMarkers(); - }); - - $("#savePhotoBtn").on("click", function () { - const canvas = document.getElementById("photoCanvas"); - const img = $("#samplePhoto"); - const ctx = canvas.getContext("2d"); - - canvas.width = img.get(0).naturalWidth; - canvas.height = img.get(0).naturalHeight; - ctx.drawImage(img.get(0), 0, 0); - - const partsList = []; - $("#partsTableBody tr").each(function () { - const partNumber = $(this).find(".part-number").val(); - const partDescription = $(this).find(".part-description").val(); - if (partNumber && partDescription) { - partsList.push(`${partNumber} ${partDescription}`); - } - }); - - if (hasDescriptions) { - ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; - ctx.fillRect( - descriptionPosition.x, - descriptionPosition.y, - 200, - partsList.length * 12 + 10, - ); - ctx.fillStyle = "#000000"; - ctx.font = "10px Arial"; - partsList.forEach((part, index) => { - ctx.fillText( - part, - descriptionPosition.x + 5, - descriptionPosition.y + 12 + index * 12, - ); - }); - } - - markers.forEach((marker) => { - ctx.beginPath(); - ctx.arc(marker.x, marker.y, 8, 0, 2 * Math.PI); - ctx.fillStyle = "rgba(255, 0, 0, 0.5)"; - ctx.fill(); - ctx.strokeStyle = "#ff0000"; - ctx.lineWidth = 1; - ctx.stroke(); - ctx.fillStyle = "#ffffff"; - ctx.font = "bold 8px Arial"; - ctx.textAlign = "center"; - ctx.textBaseline = "middle"; - ctx.fillText(marker.partNumber, marker.x, marker.y); - }); - - const dataURL = canvas.toDataURL("image/png"); - const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); - const defaultName = `photo_${$("#partsModal").data("iddatadb")}_${timestamp}.png`; - const newName = prompt( - "Inserisci il nome del file (senza estensione):", - defaultName.split(".png")[0], - ); - if (newName) { - const finalName = newName + "_" + timestamp + ".png"; - $.ajax({ - url: "save_annotated_photo.php", - method: "POST", - data: { dataURL: dataURL, filename: finalName }, - success: function (response) { - if (response.success) { - alert( - "Foto salvata con successo: " + response.file_path, - ); - } else { - alert("Errore nel salvataggio: " + response.message); - } - }, - error: function (xhr, status, error) { - alert("Errore nel salvataggio della foto: " + error); - }, - }); - } - }); - - $(document).on("mouseenter", "tr", function () { - console.log("Mouse entrato su riga"); - }); - - $(document).on("mouseleave", "tr", function () { - console.log("Mouse uscito da riga"); - }); -}); diff --git a/public/userarea/photos.js b/public/userarea/photos.js deleted file mode 100644 index dfd8e8c..0000000 --- a/public/userarea/photos.js +++ /dev/null @@ -1,1063 +0,0 @@ -document.addEventListener("DOMContentLoaded", function () { - // Funzione per caricare il contenuto del popup - async function loadPopupContent(iddatadb, idquotations) { - const popupContent = document.getElementById("popupContent"); - if (!popupContent) { - console.error("Elemento popupContent non trovato"); - return; - } - try { - const endpoint = idquotations - ? `photos_popup.php?idquotations=${idquotations}` - : `photos_popup.php?iddatadb=${iddatadb}`; - console.log("Caricamento popup da:", endpoint); - const response = await fetch(endpoint); - if (!response.ok) - throw new Error("Errore nella risposta del server"); - popupContent.innerHTML = await response.text(); - attachPhotoEventListeners(iddatadb, idquotations); - } catch (error) { - popupContent.innerHTML = `

              Errore durante il caricamento: ${error.message}

              `; - console.error("Errore in loadPopupContent:", error); - } - } - - // Funzione per gestire la webcam - function setupWebcam(iddatadb, idquotations) { - const openWebcamBtn = document.getElementById("openWebcamBtn"); - const webcamArea = document.getElementById("webcamArea"); - const webcamVideo = document.getElementById("webcamVideo"); - const captureBtn = document.getElementById("captureBtn"); - const closeWebcamBtn = document.getElementById("closeWebcamBtn"); - const webcamSelect = document.getElementById("webcamSelect"); - let stream = null; - - if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { - console.warn("La webcam non è supportata dal browser."); - if (openWebcamBtn) openWebcamBtn.style.display = "none"; - return; - } - - if ( - !openWebcamBtn || - !webcamArea || - !webcamVideo || - !captureBtn || - !closeWebcamBtn || - !webcamSelect - ) { - console.error("Elementi webcam mancanti", { - openWebcamBtn, - webcamArea, - webcamVideo, - captureBtn, - closeWebcamBtn, - webcamSelect, - }); - return; - } - - async function startWebcam(deviceId = null) { - try { - if (stream) { - stream.getTracks().forEach((track) => track.stop()); - stream = null; - webcamVideo.srcObject = null; - } - - const constraints = { - video: deviceId ? { deviceId: { exact: deviceId } } : true, - }; - - stream = await navigator.mediaDevices.getUserMedia(constraints); - webcamVideo.srcObject = stream; - webcamArea.style.display = "block"; - openWebcamBtn.style.display = "none"; - dropArea.style.display = "none"; - } catch (error) { - console.error("Errore nell'accesso alla webcam:", error); - alert("Errore nell'accesso alla webcam: " + error.message); - webcamArea.style.display = "none"; - openWebcamBtn.style.display = "block"; - dropArea.style.display = "block"; - } - } - - async function populateWebcamSelect() { - try { - await navigator.mediaDevices.getUserMedia({ video: true }); - const devices = await navigator.mediaDevices.enumerateDevices(); - const videoDevices = devices.filter( - (device) => device.kind === "videoinput", - ); - - webcamSelect.innerHTML = - ''; - - videoDevices.forEach((device) => { - const option = document.createElement("option"); - option.value = device.deviceId; - option.text = - device.label || `Webcam ${webcamSelect.options.length}`; - webcamSelect.appendChild(option); - }); - - webcamSelect.style.display = - videoDevices.length > 1 ? "block" : "none"; - - if (videoDevices.length > 0) { - await startWebcam(videoDevices[0].deviceId); - } else { - alert("Nessuna webcam rilevata."); - webcamArea.style.display = "none"; - openWebcamBtn.style.display = "block"; - dropArea.style.display = "block"; - } - } catch (error) { - console.error("Errore nel recupero dei dispositivi:", error); - alert("Errore nel recupero dei dispositivi: " + error.message); - webcamSelect.style.display = "none"; - } - } - - openWebcamBtn.addEventListener("click", async () => { - await populateWebcamSelect(); - }); - - webcamSelect.addEventListener("change", async (e) => { - const deviceId = e.target.value; - if (deviceId) { - await startWebcam(deviceId); - } - }); - - closeWebcamBtn.addEventListener("click", () => { - if (stream) { - stream.getTracks().forEach((track) => track.stop()); - stream = null; - webcamVideo.srcObject = null; - } - webcamArea.style.display = "none"; - openWebcamBtn.style.display = "block"; - dropArea.style.display = "block"; - }); - - captureBtn.addEventListener("click", () => { - const canvas = document.createElement("canvas"); - canvas.width = webcamVideo.videoWidth; - canvas.height = webcamVideo.videoHeight; - canvas - .getContext("2d") - .drawImage(webcamVideo, 0, 0, canvas.width, canvas.height); - - canvas.toBlob(async (blob) => { - const file = new File( - [blob], - `webcam_photo_${Date.now()}.jpg`, - { type: "image/jpeg" }, - ); - const loader = document.getElementById("loader"); - if (loader) { - loader.style.display = "flex"; - } - await handleFiles([file], iddatadb, idquotations); - if (stream) { - stream.getTracks().forEach((track) => track.stop()); - stream = null; - webcamVideo.srcObject = null; - } - webcamArea.style.display = "none"; - openWebcamBtn.style.display = "block"; - dropArea.style.display = "block"; - }, "image/jpeg"); - }); - } - - async function handleFiles(files, iddatadb, idquotations) { - const loader = document.getElementById("loader"); - if (!loader) { - console.error("Elemento loader non trovato"); - return; - } - - if (!files || files.length === 0) { - console.warn("Nessun file da caricare"); - return; - } - - loader.style.display = "flex"; - console.log(`Inizio upload di ${files.length} file`); - - let successCount = 0; - let errorMessages = []; - let uploadPromises = []; - - for (let i = 0; i < files.length; i++) { - const file = files[i]; - if (!file.type.startsWith("image/")) { - alert(`File ${file.name} non è un'immagine, saltato!`); - continue; - } - - console.log(`Preparazione upload file ${i + 1}: ${file.name}`); - - const formData = new FormData(); - formData.append("photo", file); - if (idquotations) { - formData.append("idquotations", idquotations); - } else { - formData.append("iddatadb", iddatadb); - } - - const uploadPromise = fetch("upload_photo.php", { - method: "POST", - body: formData, - }) - .then((response) => response.json()) - .then((result) => { - if (result.success) { - successCount++; - console.log(`Successo per ${file.name}`); - } else { - errorMessages.push( - `Errore per ${file.name}: ${result.message}`, - ); - } - }) - .catch((error) => { - errorMessages.push( - `Errore per ${file.name}: ${error.message}`, - ); - }); - - uploadPromises.push(uploadPromise); - } - - await Promise.all(uploadPromises); - - loader.style.display = "none"; - console.log( - `Fine upload: ${successCount} riusciti, ${errorMessages.length} errori`, - ); - - if (errorMessages.length > 0) { - alert("Errori durante l'upload:\n" + errorMessages.join("\n")); - } - - // Ricarica sempre alla fine per aggiornare la lista, anche se parziale successo - loadPopupContent(iddatadb, idquotations); - } - - function attachPhotoEventListeners(iddatadb, idquotations) { - const dropArea = document.getElementById("dropArea"); - const photoInput = document.getElementById("photoInput"); - const photosModal = document.getElementById("photosModal"); - - if (!dropArea || !photoInput || !photosModal) { - console.error("Elementi mancanti:", { - dropArea, - photoInput, - photosModal, - }); - return; - } - - const preventDefaults = (e) => { - e.preventDefault(); - e.stopPropagation(); - }; - - ["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => { - dropArea.addEventListener(eventName, preventDefaults, false); - }); - - ["dragenter", "dragover"].forEach((eventName) => { - dropArea.addEventListener( - eventName, - () => dropArea.classList.add("highlight"), - false, - ); - }); - - ["dragleave", "drop"].forEach((eventName) => { - dropArea.addEventListener( - eventName, - () => dropArea.classList.remove("highlight"), - false, - ); - }); - - dropArea.addEventListener( - "drop", - (e) => { - const files = e.dataTransfer.files; - if (files.length > 0) { - handleFiles(files, iddatadb, idquotations); - } - }, - false, - ); - - dropArea.addEventListener( - "click", - () => { - photoInput.click(); - }, - false, - ); - - photoInput.addEventListener( - "change", - (e) => { - const files = e.target.files; - if (files.length > 0) { - handleFiles(files, iddatadb, idquotations); - } - e.target.value = ""; - }, - false, - ); - - document.querySelectorAll(".delete-photo-btn").forEach((button) => { - button.addEventListener("click", async function () { - const photoId = this.getAttribute("data-photo-id"); - if (confirm("Sei sicuro di voler eliminare questa foto?")) { - try { - const response = await fetch("delete_photo.php", { - method: "POST", - headers: { - "Content-Type": - "application/x-www-form-urlencoded", - }, - body: `photo_id=${photoId}`, - }); - const result = await response.json(); - if (result.success) { - loadPopupContent(iddatadb, idquotations); - } else { - alert( - "Errore durante l'eliminazione: " + - result.message, - ); - } - } catch (error) { - alert( - "Errore durante l'eliminazione: " + error.message, - ); - } - } - }); - }); - - document.querySelectorAll(".thumbnail").forEach((img) => { - img.addEventListener("click", function () { - const enlargedImage = document.getElementById("enlargedImage"); - enlargedImage.src = this.src; - document.getElementById("imageModal").style.display = "block"; - }); - }); - - const imageCloseBtn = document.querySelector(".image-modal-close"); - if (imageCloseBtn) { - imageCloseBtn.addEventListener("click", () => { - document.getElementById("imageModal").style.display = "none"; - }); - } - document - .getElementById("imageModal") - .addEventListener("click", function (event) { - if (event.target === this) { - this.style.display = "none"; - } - }); - - setupWebcam(iddatadb, idquotations); - - const createCollageBtn = document.getElementById("createCollageBtn"); - if (createCollageBtn) { - createCollageBtn.addEventListener("click", () => { - document.getElementById("collageModal").style.display = "block"; - initCollageCanvas(); - }); - } - - const closeCollageBtn = document.querySelector(".close-collage"); - if (closeCollageBtn) { - closeCollageBtn.addEventListener("click", () => { - document.getElementById("collageModal").style.display = "none"; - if (isCropping) { - exitCropMode(); - } - if (isRemovingBackground) { - exitBackgroundRemovalMode(); - } - }); - } - - let canvas; - let cropRect = null; - let isCropping = false; - let croppedImage = null; - let isApplyingCrop = false; - let isRemovingBackground = false; - let backgroundRemovalImage = null; - let history = []; - const maxHistory = 20; - - function initCollageCanvas() { - if (typeof fabric === "undefined") { - console.error("Fabric.js non è caricato!"); - alert( - "Errore: Fabric.js non è disponibile. Controlla la connessione al CDN.", - ); - return; - } - canvas = new fabric.Canvas("collageCanvas", { - backgroundColor: "#fff", - selection: true, - }); - fabric.Object.prototype.set({ - cornerColor: "black", - cornerStrokeColor: "black", - cornerSize: 12, - borderColor: "black", - transparentCorners: false, - }); - canvas.on("object:modified", () => { - saveCanvasState(); - updateLayersPanel(); - canvas.renderAll(); - }); - canvas.on("object:added", () => { - updateLayersPanel(); - }); - canvas.on("object:removed", () => { - updateLayersPanel(); - }); - canvas.on("selection:created", () => { - updateButtons(); - }); - canvas.on("selection:updated", () => { - updateButtons(); - }); - canvas.on("selection:cleared", () => { - if (!isCropping && !isRemovingBackground) { - updateButtons(); - } else if (isCropping && cropRect) { - canvas.setActiveObject(cropRect); - canvas.renderAll(); - } else if (isRemovingBackground) { - canvas.setActiveObject(backgroundRemovalImage); - canvas.renderAll(); - } - }); - canvas.on("mouse:down", (event) => { - if (isRemovingBackground && backgroundRemovalImage) { - handleBackgroundColorSelection(event); - } - }); - saveCanvasState(); - updateLayersPanel(); - updateButtons(); - } - - function updateLayersPanel() { - const layersList = document.getElementById("layersList"); - if (!layersList) { - console.error("Elemento layersList non trovato"); - return; - } - layersList.innerHTML = ""; - - const images = canvas.getObjects("image"); - images.forEach((img, index) => { - let thumbSrc; - try { - const thumbCanvas = document.createElement("canvas"); - thumbCanvas.width = 50; - thumbCanvas.height = 50; - const thumbFabric = new fabric.Canvas(thumbCanvas); - - const clonedImg = fabric.util.object.clone(img); - const scaleFactor = Math.min( - 50 / img.width, - 50 / img.height, - ); - clonedImg.scaleX = scaleFactor; - clonedImg.scaleY = scaleFactor; - clonedImg.left = (50 - img.width * scaleFactor) / 2; - clonedImg.top = (50 - img.height * scaleFactor) / 2; - clonedImg.setCoords(); - thumbFabric.add(clonedImg); - thumbFabric.renderAll(); - - thumbSrc = thumbCanvas.toDataURL("image/png"); - thumbFabric.dispose(); - } catch (error) { - console.warn( - "Errore nella generazione della thumbnail per immagine", - index + 1, - error, - ); - thumbSrc = img.getSrc(); // Fallback all'URL originale - } - - const layerItem = document.createElement("li"); - const thumbImg = document.createElement("img"); - thumbImg.src = thumbSrc; - thumbImg.title = `Layer ${index + 1}`; - thumbImg.addEventListener("click", () => { - canvas.setActiveObject(img); - canvas.renderAll(); - }); - - layerItem.appendChild(thumbImg); - layersList.appendChild(layerItem); - }); - } - - function saveCanvasState() { - if (isCropping || isRemovingBackground) { - return; - } - const state = JSON.stringify( - canvas.toJSON([ - "cornerColor", - "cornerStrokeColor", - "cornerSize", - "borderColor", - "transparentCorners", - ]), - ); - history.push(state); - if (history.length > maxHistory) { - history.shift(); - } - updateButtons(); - } - - function undo() { - if (history.length <= 1) { - return; - } - history.pop(); - const previousState = history[history.length - 1]; - if (previousState) { - canvas.clear(); - canvas.loadFromJSON(previousState, () => { - canvas.renderAll(); - updateLayersPanel(); - updateButtons(); - }); - } else { - console.warn("Nessuno stato precedente disponibile"); - canvas.clear(); - canvas.setBackgroundColor("#fff"); - canvas.renderAll(); - updateLayersPanel(); - updateButtons(); - } - } - - function updateButtons() { - const cropBtn = document.getElementById("cropImageBtn"); - const applyCropBtn = document.getElementById("applyCropBtn"); - const cancelCropBtn = document.getElementById("cancelCropBtn"); - const removeBackgroundBtn = document.getElementById( - "removeBackgroundBtn", - ); - const removeImageBtn = document.getElementById("removeImageBtn"); - const undoBtn = document.getElementById("undoBtn"); - const instruction = document.getElementById( - "backgroundRemovalInstruction", - ); - const activeObject = canvas.getActiveObject(); - if (isCropping && cropRect) { - cropBtn.disabled = true; - applyCropBtn.disabled = false; - cancelCropBtn.disabled = false; - removeBackgroundBtn.disabled = true; - removeImageBtn.disabled = true; - undoBtn.disabled = true; - instruction.style.display = "none"; - } else if (isRemovingBackground && backgroundRemovalImage) { - cropBtn.disabled = true; - applyCropBtn.disabled = true; - cancelCropBtn.disabled = true; - removeBackgroundBtn.disabled = true; - removeImageBtn.disabled = true; - undoBtn.disabled = true; - instruction.style.display = "block"; - } else if ( - activeObject && - activeObject.type === "image" && - !isCropping && - !isRemovingBackground - ) { - cropBtn.disabled = false; - applyCropBtn.disabled = true; - cancelCropBtn.disabled = true; - removeBackgroundBtn.disabled = false; - removeImageBtn.disabled = false; - undoBtn.disabled = history.length <= 1; - instruction.style.display = "none"; - } else { - cropBtn.disabled = true; - applyCropBtn.disabled = true; - cancelCropBtn.disabled = true; - removeBackgroundBtn.disabled = true; - removeImageBtn.disabled = true; - undoBtn.disabled = history.length <= 1; - instruction.style.display = "none"; - } - } - - function enterCropMode() { - const activeObject = canvas.getActiveObject(); - if (!activeObject || activeObject.type !== "image") { - console.warn("Nessuna immagine selezionata per il ritaglio"); - alert("Seleziona un'immagine prima di attivare il ritaglio!"); - return; - } - isCropping = true; - croppedImage = activeObject; - canvas.discardActiveObject(); - cropRect = new fabric.Rect({ - left: activeObject.left, - top: activeObject.top, - width: activeObject.width * activeObject.scaleX * 0.5, - height: activeObject.height * activeObject.scaleY * 0.5, - fill: "rgba(0, 0, 0, 0.3)", - stroke: "red", - strokeWidth: 2, - hasBorders: true, - hasControls: true, - lockRotation: true, - selectable: true, - cornerColor: "black", - cornerStrokeColor: "black", - cornerSize: 12, - borderColor: "black", - transparentCorners: false, - }); - canvas.add(cropRect); - canvas.setActiveObject(cropRect); - canvas.renderAll(); - updateButtons(); - } - - function exitCropMode() { - if (cropRect) { - canvas.remove(cropRect); - cropRect = null; - } - isCropping = false; - croppedImage = null; - isApplyingCrop = false; - canvas.discardActiveObject(); - canvas.renderAll(); - updateButtons(); - } - - function applyCrop() { - if (isApplyingCrop) { - return; - } - if (!isCropping || !cropRect || !croppedImage) { - console.warn("Condizioni per il ritaglio non soddisfatte", { - isCropping, - cropRect: !!cropRect, - croppedImage: !!croppedImage, - }); - alert( - "Nessun rettangolo di ritaglio attivo o immagine selezionata!", - ); - exitCropMode(); - return; - } - isApplyingCrop = true; - const img = croppedImage; - const cropX = (cropRect.left - img.left) / img.scaleX; - const cropY = (cropRect.top - img.top) / img.scaleY; - const cropWidth = (cropRect.width * cropRect.scaleX) / img.scaleX; - const cropHeight = (cropRect.height * cropRect.scaleY) / img.scaleY; - - fabric.Image.fromURL( - img.getSrc(), - (newImg) => { - newImg.set({ - left: cropRect.left, - top: cropRect.top, - scaleX: img.scaleX, - scaleY: img.scaleY, - cropX: cropX, - cropY: cropY, - width: cropWidth, - height: cropHeight, - hasControls: true, - hasBorders: true, - cornerColor: "black", - cornerStrokeColor: "black", - cornerSize: 12, - borderColor: "black", - transparentCorners: false, - }); - canvas.remove(img); - canvas.remove(cropRect); - canvas.add(newImg); - canvas.setActiveObject(newImg); - exitCropMode(); - saveCanvasState(); - updateLayersPanel(); - canvas.renderAll(); - }, - { crossOrigin: "anonymous" }, - ); - } - - function enterBackgroundRemovalMode() { - const activeObject = canvas.getActiveObject(); - if (!activeObject || activeObject.type !== "image") { - console.warn( - "Nessuna immagine selezionata per la rimozione dello sfondo", - ); - alert( - "Seleziona un'immagine prima di attivare la rimozione dello sfondo!", - ); - return; - } - isRemovingBackground = true; - backgroundRemovalImage = activeObject; - updateButtons(); - } - - function exitBackgroundRemovalMode() { - isRemovingBackground = false; - backgroundRemovalImage = null; - canvas.discardActiveObject(); - canvas.renderAll(); - updateButtons(); - } - - function handleBackgroundColorSelection(event) { - if (!isRemovingBackground || !backgroundRemovalImage) { - console.warn( - "Condizioni per la rimozione dello sfondo non soddisfatte", - ); - return; - } - const pointer = canvas.getPointer(event.e); - const img = backgroundRemovalImage; - - const tempCanvas = document.createElement("canvas"); - tempCanvas.width = img.width; - tempCanvas.height = img.height; - const ctx = tempCanvas.getContext("2d"); - ctx.drawImage(img.getElement(), 0, 0, img.width, img.height); - - const imgLeft = img.left; - const imgTop = img.top; - const scaleX = img.scaleX; - const scaleY = img.scaleY; - const x = (pointer.x - imgLeft) / scaleX; - const y = (pointer.y - imgTop) / scaleY; - - const pixelData = ctx.getImageData(x, y, 1, 1).data; - const targetColor = { - r: pixelData[0], - g: pixelData[1], - b: pixelData[2], - }; - - removeBackground(img, targetColor); - } - - function removeBackground(img, targetColor) { - const tempCanvas = document.createElement("canvas"); - tempCanvas.width = img.width; - tempCanvas.height = img.height; - const ctx = tempCanvas.getContext("2d"); - ctx.drawImage(img.getElement(), 0, 0, img.width, img.height); - - const imageData = ctx.getImageData( - 0, - 0, - tempCanvas.width, - tempCanvas.height, - ); - const data = imageData.data; - const tolerance = 50; - - for (let i = 0; i < data.length; i += 4) { - const r = data[i]; - const g = data[i + 1]; - const b = data[i + 2]; - if ( - Math.abs(r - targetColor.r) <= tolerance && - Math.abs(g - targetColor.g) <= tolerance && - Math.abs(b - targetColor.b) <= tolerance - ) { - data[i + 3] = 0; - } - } - - ctx.putImageData(imageData, 0, 0); - const newImageUrl = tempCanvas.toDataURL("image/png"); - - fabric.Image.fromURL( - newImageUrl, - (newImg) => { - newImg.set({ - left: img.left, - top: img.top, - scaleX: img.scaleX, - scaleY: img.scaleY, - hasControls: true, - hasBorders: true, - cornerColor: "black", - cornerStrokeColor: "black", - cornerSize: 12, - borderColor: "black", - transparentCorners: false, - }); - canvas.remove(img); - canvas.add(newImg); - canvas.setActiveObject(newImg); - exitBackgroundRemovalMode(); - saveCanvasState(); - updateLayersPanel(); - canvas.renderAll(); - }, - { crossOrigin: "anonymous" }, - ); - } - - function removeImage() { - const activeObject = canvas.getActiveObject(); - if (!activeObject || activeObject.type !== "image") { - console.warn("Nessuna immagine selezionata per la rimozione"); - alert("Seleziona un'immagine da rimuovere!"); - return; - } - canvas.remove(activeObject); - canvas.discardActiveObject(); - saveCanvasState(); - updateLayersPanel(); - canvas.renderAll(); - } - - const addToCanvasBtn = document.getElementById("addToCanvasBtn"); - if (addToCanvasBtn) { - addToCanvasBtn.addEventListener("click", () => { - const checkboxes = document.querySelectorAll( - ".photo-checkbox:checked", - ); - if (checkboxes.length === 0) { - alert("Seleziona almeno una foto!"); - return; - } - checkboxes.forEach((cb) => { - const imgPath = cb.getAttribute("data-path"); - fabric.Image.fromURL( - imgPath, - (img) => { - img.set({ - left: Math.random() * 600, - top: Math.random() * 400, - scaleX: 0.5, - scaleY: 0.5, - hasControls: true, - hasBorders: true, - cornerColor: "black", - cornerStrokeColor: "black", - cornerSize: 12, - borderColor: "black", - transparentCorners: false, - }); - canvas.add(img); - canvas.renderAll(); - }, - { crossOrigin: "anonymous" }, - ); - }); - checkboxes.forEach((cb) => (cb.checked = false)); - saveCanvasState(); - }); - } - - const saveCollageBtn = document.getElementById("saveCollageBtn"); - if (saveCollageBtn) { - saveCollageBtn.addEventListener("click", async () => { - if ( - canvas.getObjects().length === 0 && - !canvas.backgroundImage - ) { - alert("Il canvas è vuoto! Aggiungi almeno una foto."); - return; - } - const dataURL = canvas.toDataURL({ - format: "jpeg", - quality: 0.8, - }); - const blob = await (await fetch(dataURL)).blob(); - const file = new File([blob], `collage_${Date.now()}.jpg`, { - type: "image/jpeg", - }); - - await handleFiles([file], iddatadb, idquotations); - document.getElementById("collageModal").style.display = "none"; - loadPopupContent(iddatadb, idquotations); - }); - } - - const bringToFrontBtn = document.getElementById("bringToFrontBtn"); - if (bringToFrontBtn) { - bringToFrontBtn.addEventListener("click", () => { - const activeObject = canvas.getActiveObject(); - if (activeObject) { - canvas.bringToFront(activeObject); - canvas.renderAll(); - saveCanvasState(); - updateLayersPanel(); - } else { - alert("Seleziona un'immagine sul canvas!"); - } - }); - } - - const sendToBackBtn = document.getElementById("sendToBackBtn"); - if (sendToBackBtn) { - sendToBackBtn.addEventListener("click", () => { - const activeObject = canvas.getActiveObject(); - if (activeObject) { - canvas.sendToBack(activeObject); - canvas.renderAll(); - saveCanvasState(); - updateLayersPanel(); - } else { - alert("Seleziona un'immagine sul canvas!"); - } - }); - } - - const bringForwardBtn = document.getElementById("bringForwardBtn"); - if (bringForwardBtn) { - bringForwardBtn.addEventListener("click", () => { - const activeObject = canvas.getActiveObject(); - if (activeObject) { - canvas.bringForward(activeObject); - canvas.renderAll(); - saveCanvasState(); - updateLayersPanel(); - } else { - alert("Seleziona un'immagine sul canvas!"); - } - }); - } - - const sendBackwardBtn = document.getElementById("sendBackwardBtn"); - if (sendBackwardBtn) { - sendBackwardBtn.addEventListener("click", () => { - const activeObject = canvas.getActiveObject(); - if (activeObject) { - canvas.sendBackwards(activeObject); - canvas.renderAll(); - saveCanvasState(); - updateLayersPanel(); - } else { - alert("Seleziona un'immagine sul canvas!"); - } - }); - } - - const cropImageBtn = document.getElementById("cropImageBtn"); - if (cropImageBtn) { - cropImageBtn.addEventListener("click", () => { - enterCropMode(); - }); - } - - const applyCropBtn = document.getElementById("applyCropBtn"); - if (applyCropBtn) { - applyCropBtn.addEventListener("click", () => { - applyCrop(); - }); - } - - const cancelCropBtn = document.getElementById("cancelCropBtn"); - if (cancelCropBtn) { - cancelCropBtn.addEventListener("click", () => { - exitCropMode(); - }); - } - - const removeBackgroundBtn = document.getElementById( - "removeBackgroundBtn", - ); - if (removeBackgroundBtn) { - removeBackgroundBtn.addEventListener("click", () => { - enterBackgroundRemovalMode(); - }); - } - - const removeImageBtn = document.getElementById("removeImageBtn"); - if (removeImageBtn) { - removeImageBtn.addEventListener("click", () => { - removeImage(); - }); - } - - const undoBtn = document.getElementById("undoBtn"); - if (undoBtn) { - undoBtn.addEventListener("click", () => { - undo(); - }); - } - - const loader = document.getElementById("loader"); - if (loader) { - loader.style.display = "none"; - } - } - - const photosButtons = document.querySelectorAll(".photos-btn"); - const photosModal = document.getElementById("photosModal"); - const closeBtn = document.querySelector(".close-btn"); - - if (photosButtons.length && photosModal && closeBtn) { - photosButtons.forEach((button) => { - button.addEventListener("click", function () { - const iddatadb = this.getAttribute("data-iddatadb") || null; - const idquotations = - this.getAttribute("data-idquotations") || null; - console.log("Apertura modale foto con:", { - iddatadb, - idquotations, - }); - loadPopupContent(iddatadb, idquotations); - photosModal.style.display = "block"; - document.querySelector(".overlay").style.display = "none"; - }); - }); - - closeBtn.addEventListener("click", function () { - photosModal.style.display = "none"; - document.querySelector(".overlay").style.display = "none"; - document.body.style.pointerEvents = "auto"; - }); - - window.addEventListener("click", function (event) { - if (event.target === photosModal) { - photosModal.style.display = "none"; - document.querySelector(".overlay").style.display = "none"; - document.body.style.pointerEvents = "auto"; - } - }); - } else { - console.error("Elementi mancanti:", { - photosButtons, - photosModal, - closeBtn, - }); - } -}); diff --git a/public/userarea/photos_functions.php b/public/userarea/photos_functions.php deleted file mode 100644 index 9b68490..0000000 --- a/public/userarea/photos_functions.php +++ /dev/null @@ -1,68 +0,0 @@ - - -
              - × - -
              - \ No newline at end of file diff --git a/public/userarea/photos_popup.php b/public/userarea/photos_popup.php deleted file mode 100644 index e84019c..0000000 --- a/public/userarea/photos_popup.php +++ /dev/null @@ -1,428 +0,0 @@ - - - - -load(); -} catch (Exception $e) { - error_log("Errore nel caricamento del file .env: " . $e->getMessage()); -?> - - - -getConnection(); - -// Verifica che almeno uno degli ID sia passato -$iddatadb = isset($_GET['iddatadb']) && !empty($_GET['iddatadb']) ? intval($_GET['iddatadb']) : null; -$idquotations = isset($_GET['idquotations']) && !empty($_GET['idquotations']) ? intval($_GET['idquotations']) : null; - -if (!$iddatadb && !$idquotations) { - error_log("Errore: ID riga o ID quotations non fornito"); -?> - - - - prepare("SELECT {$paramName}, {$field} FROM {$table} WHERE {$paramName} = ?"); - $stmt->execute([$paramValue]); - $row = $stmt->fetch(PDO::FETCH_ASSOC); - - if (!$row) { - error_log("Errore: Riga non trovata per {$paramName} = {$paramValue}"); - ?> - - getMessage()); - ?> - -prepare("SELECT id, file_path, file_name, description, uploaded_at FROM {$photoTable} WHERE {$photoParamName} = ? ORDER BY uploaded_at DESC"); - $stmt->execute([$paramValue]); - $photos = $stmt->fetchAll(PDO::FETCH_ASSOC); -} catch (Exception $e) { - error_log("Errore query foto: " . $e->getMessage()); - $photos = []; // Imposta array vuoto in caso di errore -} - -// Definisci il percorso base per le foto -$photoBasePath = '../photostrf/'; - -// Usa la variabile d'ambiente BASE_URL -$baseUrl = rtrim($_ENV['BASE_URL'], '/'); -$uploadUrl = $iddatadb - ? $baseUrl . "/upload_photos_mobile.php?iddatadb=" . $iddatadb - : $baseUrl . "/upload_photos_mobile.php?idquotations=" . $idquotations; - -// Genera il QR code con endroid/qr-code 6.0.6 -$qrCodeDir = '../photostrf/qrcodes/'; -if (!is_dir($qrCodeDir)) { - mkdir($qrCodeDir, 0755, true); -} -$qrCodeFile = $qrCodeDir . "qrcode_{$id}.png"; - -$writer = new PngWriter(); -$qrCode = new QrCode( - data: $uploadUrl, - encoding: new Encoding('UTF-8'), - errorCorrectionLevel: ErrorCorrectionLevel::Low, - size: 150, - margin: 10, - roundBlockSizeMode: RoundBlockSizeMode::Margin, - foregroundColor: new Color(0, 0, 0), - backgroundColor: new Color(255, 255, 255) -); - -$result = $writer->write($qrCode); -$result->saveToFile($qrCodeFile); -?> - - - - \ No newline at end of file diff --git a/public/userarea/price_mapping_list.php b/public/userarea/price_mapping_list.php new file mode 100644 index 0000000..88bbc80 --- /dev/null +++ b/public/userarea/price_mapping_list.php @@ -0,0 +1,30 @@ +getConnection(); + + $sql = " + SELECT + pm.id, + c.client_name, + pm.price_ref, + pm.price, + pm.source_file, + pm.created_at + FROM price_mapping pm + LEFT JOIN clients c ON pm.idclient = c.idclient + ORDER BY pm.id DESC +"; + + + $stmt = $pdo->query($sql); + $data = $stmt->fetchAll(PDO::FETCH_ASSOC); + + echo json_encode($data, JSON_UNESCAPED_UNICODE); +} catch (Throwable $e) { + echo json_encode(['error' => $e->getMessage()]); +} diff --git a/public/userarea/process_edit_template_xls.php b/public/userarea/process_edit_template_xls.php deleted file mode 100644 index 3722783..0000000 --- a/public/userarea/process_edit_template_xls.php +++ /dev/null @@ -1,76 +0,0 @@ - false, "message" => ""]; - -try { - if ($_SERVER["REQUEST_METHOD"] !== "POST") { - throw new Exception("Invalid request method."); - } - - // Recupera e sanifica i dati - $id = intval($_POST['id']); - $name = trim($_POST['name']); - $header_row = intval($_POST['header_row']); - $start_column = trim($_POST['start_column']); - $description = trim($_POST['description'] ?? ''); - $target_table = trim($_POST['target_table']); - $idclient = intval($_POST['client_id'] ?? 0); // Usa client_id dal form - $clientname = trim($_POST['client_name'] ?? ''); // Usa client_name dal form - $idschema = intval($_POST['idschema'] ?? 0); // Nuovo campo - $schemaname = trim($_POST['schemaname'] ?? ''); // Corretto da schemamaname - $idroutine = isset($_POST['idroutine']) && $_POST['idroutine'] !== '' ? intval($_POST['idroutine']) : null; // Aggiunto idroutine - $button_size = trim($_POST['button_size'] ?? 'medium'); // Nuovo campo - $button_bg_color = trim($_POST['button_bg_color'] ?? '#007bff'); // Nuovo campo - $button_text_color = trim($_POST['button_text_color'] ?? '#ffffff'); // Nuovo campo - $button_label = trim($_POST['button_label'] ?? 'Click Me'); // Nuovo campo - - // Controllo sui campi obbligatori - if (empty($id) || empty($name) || empty($header_row) || empty($start_column) || empty($target_table) || $idschema <= 0) { - throw new Exception("All fields marked with * are required, including schema."); - } - - // Validazione del idclient - if ($idclient <= 0) { - throw new Exception("Please select a valid client."); - } - - // Connessione al database - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - // Aggiorna il database, includendo i nuovi campi - $stmt = $pdo->prepare("UPDATE excel_templates - SET name = ?, header_row = ?, start_column = ?, description = ?, target_table = ?, - idclient = ?, clientname = ?, schemaname = ?, idschema = ?, idroutine = ?, - button_size = ?, button_bg_color = ?, button_text_color = ?, button_label = ?, - updated_at = NOW() - WHERE id = ?"); - $stmt->execute([ - $name, - $header_row, - $start_column, - $description, - $target_table, - $idclient, - $clientname, - $schemaname, - $idschema, - $idroutine, - $button_size, - $button_bg_color, - $button_text_color, - $button_label, - $id - ]); - - // rowCount potrebbe essere 0 se non ci sono modifiche, quindi consideriamo comunque un successo - $response["success"] = true; - $response["message"] = "Template updated successfully!"; -} catch (Exception $e) { - $response["message"] = $e->getMessage(); -} - -// Restituisce un JSON per il fetch -echo json_encode($response); diff --git a/public/userarea/process_import_xls.php b/public/userarea/process_import_xls.php deleted file mode 100644 index 7ea091c..0000000 --- a/public/userarea/process_import_xls.php +++ /dev/null @@ -1,117 +0,0 @@ - '', 'rows' => [], 'columns' => [], 'template_id' => 0, 'filename' => '']; - -try { - if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['excel_file'])) { - $template_id = isset($_POST['template_id']) ? intval($_POST['template_id']) : 0; - $header_row = isset($_POST['header_row']) ? intval($_POST['header_row']) : 1; - $start_column = isset($_POST['start_column']) ? intval($_POST['start_column']) : 1; - - $file = $_FILES['excel_file']; - $fileError = $file['error']; - - if ($fileError === UPLOAD_ERR_OK) { - // Recupera l'ID dell'utente loggato (assumiamo sia disponibile in $iduserlogin) - if (!isset($iduserlogin)) { - $iduserlogin = 1; // Valore di default - error_log("Warning: iduserlogin non definito, usando 1 come default"); - } - - // Genera il nome del file rinominato - $timestamp = date('YmdHis'); - $originalFilename = basename($file['name']); - $newFilename = "{$iduserlogin}-{$timestamp}-{$originalFilename}"; - $importFolder = __DIR__ . '/imported_trf/'; - if (!file_exists($importFolder)) { - mkdir($importFolder, 0777, true); - } - $destination = $importFolder . $newFilename; - - // Sposta il file - if (!move_uploaded_file($file['tmp_name'], $destination)) { - throw new Exception("Errore durante lo spostamento del file in $destination"); - } - error_log("File spostato con successo in: $destination"); - - // Carica il file rinominato con PHPSpreadsheet - $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($destination); - $worksheet = $spreadsheet->getActiveSheet(); - $highestRow = $worksheet->getHighestRow(); - $highestColumn = $worksheet->getHighestColumn(); - $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn); - - $startRow = max(1, $header_row); - $startColumn = max(1, $start_column); - - // Debug dei parametri - error_log("Processing - startRow: $startRow, startColumn: $startColumn, highestRow: $highestRow, highestColumn: $highestColumn, highestColumnIndex: $highestColumnIndex"); - - // Validazione degli indici - if ($startRow > $highestRow) { - $response['error'] = "La riga di partenza ($startRow) supera il numero totale di righe ($highestRow)."; - } elseif ($startColumn > $highestColumnIndex) { - $response['error'] = "La colonna di partenza ($startColumn) supera il numero totale di colonne ($highestColumnIndex)."; - } else { - $excelData = []; - // Estrai la riga degli header - $headerRowData = []; - for ($col = $startColumn; $col <= $highestColumnIndex; $col++) { - $columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col); - $cell = $worksheet->getCell($columnLetter . $header_row); - $cellValue = $cell ? $cell->getCalculatedValue() : ''; // Usa getCalculatedValue per le formule - $headerRowData[] = htmlspecialchars($cellValue ?: ''); - } - - // Estrai i dati a partire dalla riga successiva - for ($row = $startRow + 1; $row <= $highestRow; $row++) { - $rowData = []; - for ($col = $startColumn; $col <= $highestColumnIndex; $col++) { - $columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col); - $cell = $worksheet->getCell($columnLetter . $row); - $cellValue = $cell ? $cell->getCalculatedValue() : ''; // Usa getCalculatedValue per le formule - $rowData[] = htmlspecialchars($cellValue ?: ''); - } - if (!empty(array_filter($rowData))) { - $excelData[] = $rowData; - } - } - - // Salva i dati in sessione - $_SESSION['excel_data'] = $excelData; - $_SESSION['template_id'] = $template_id; - $_SESSION['headers'] = $headerRowData; // Salva gli header in sessione - - $response['rows'] = $excelData; - $response['columns'] = $headerRowData; // Usa gli header reali - $response['template_id'] = $template_id; - $response['filename'] = $newFilename; // Aggiungi il nome del file rinominato - } - } else { - $response['error'] = "Errore nell'upload del file: Codice errore $fileError."; - } - } else { - $response['error'] = "Richiesta non valida."; - } -} catch (Exception $e) { - $response['error'] = "Errore durante il caricamento del file: " . $e->getMessage(); - error_log("Exception in process_import_xls.php: " . $e->getMessage()); -} - -// Pulisce qualsiasi output indesiderato -ob_end_clean(); - -// Invia la risposta JSON -header('Content-Type: application/json'); -echo json_encode($response); -exit; diff --git a/public/userarea/process_import_xls2.php b/public/userarea/process_import_xls2.php deleted file mode 100644 index 652a15b..0000000 --- a/public/userarea/process_import_xls2.php +++ /dev/null @@ -1,170 +0,0 @@ - '', 'rows' => [], 'columns' => [], 'template_id' => 0, 'filename' => '', 'apply_routine' => false]; - -try { - if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['excel_file'])) { - $template_id = isset($_POST['template_id']) ? intval($_POST['template_id']) : 0; - $header_row = isset($_POST['header_row']) ? intval($_POST['header_row']) : 1; - $start_column = isset($_POST['start_column']) ? intval($_POST['start_column']) : 1; - - // Debug del template_id ricevuto - error_log("Received template_id from POST: " . print_r($_POST['template_id'], true)); - error_log("Converted template_id: $template_id"); - - $file = $_FILES['excel_file']; - $fileError = $file['error']; - - if ($fileError === UPLOAD_ERR_OK) { - // Recupera l'ID dell'utente loggato - if (!isset($iduserlogin)) { - $iduserlogin = 1; - error_log("Warning: iduserlogin non definito, usando 1 come default"); - } - - // Genera il nome del file rinominato - $timestamp = date('YmdHis'); - $originalFilename = basename($file['name']); - $newFilename = "{$iduserlogin}-{$timestamp}-{$originalFilename}"; - $importFolder = __DIR__ . '/imported_trf/'; - if (!file_exists($importFolder)) { - mkdir($importFolder, 0777, true); - } - $destination = $importFolder . $newFilename; - - // Sposta il file - if (!move_uploaded_file($file['tmp_name'], $destination)) { - throw new Exception("Errore durante lo spostamento del file in $destination"); - } - error_log("File spostato con successo in: $destination"); - - // Connessione al database - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - // Recupera il mapping da template_mapping - $stmt = $pdo->prepare("SELECT field_id AS excel_column, field_id AS mysql_column, data_type, is_required, default_value, is_manual FROM template_mapping WHERE template_id = ?"); - $stmt->execute([$template_id]); - $mappings = $stmt->fetchAll(PDO::FETCH_ASSOC); - - // Debug dei mapping - error_log("Mappings found for template_id $template_id: " . print_r($mappings, true)); - - if (empty($mappings)) { - $response['error'] = "Nessun mapping trovato per il template con ID $template_id"; - } else { - // Carica il file rinominato con PHPSpreadsheet - $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($destination); - $worksheet = $spreadsheet->getActiveSheet(); - $highestRow = $worksheet->getHighestRow(); - $highestColumn = $worksheet->getHighestColumn(); - $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn); - - $startRow = max(1, $header_row); - $startColumn = max(1, $start_column); - - // Debug dei parametri - error_log("Processing - template_id: $template_id, startRow: $startRow, startColumn: $startColumn, highestRow: $highestRow, highestColumn: $highestColumn, highestColumnIndex: $highestColumnIndex"); - - // Validazione degli indici - if ($startRow > $highestRow) { - $response['error'] = "La riga di partenza ($startRow) supera il numero totale di righe ($highestRow)."; - } elseif ($startColumn > $highestColumnIndex) { - $response['error'] = "La colonna di partenza ($startColumn) supera il numero totale di colonne ($highestColumnIndex)."; - } else { - $excelData = []; - // Estrai la riga degli header - $headerRowData = []; - for ($col = $startColumn; $col <= $highestColumnIndex; $col++) { - $columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col); - $cell = $worksheet->getCell($columnLetter . $header_row); - $cellValue = $cell ? $cell->getCalculatedValue() : ''; - $headerRowData[] = htmlspecialchars($cellValue ?: ''); - } - - // Estrai i dati a partire dalla riga successiva, includendo excelrow - for ($row = $startRow + 1; $row <= $highestRow; $row++) { - $rowData = []; - for ($col = $startColumn; $col <= $highestColumnIndex; $col++) { - $columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col); - $cell = $worksheet->getCell($columnLetter . $row); - $cellValue = $cell ? $cell->getCalculatedValue() : ''; - $rowData[] = htmlspecialchars($cellValue ?: ''); - } - if (!empty(array_filter($rowData))) { - $excelData[] = ['data' => $rowData, 'excelrow' => $row]; - } - } - - // Recupera routine dal template - $stmt = $pdo->prepare("SELECT idroutine, idclient FROM excel_templates WHERE id = ?"); - $stmt->execute([$template_id]); - $template = $stmt->fetch(PDO::FETCH_ASSOC); - - if ($template && $template['idroutine']) { - $stmtRoutine = $pdo->prepare("SELECT idroutine, name, filename, headerrow, instruction FROM routine WHERE idroutine = ?"); - $stmtRoutine->execute([$template['idroutine']]); - $routineData = $stmtRoutine->fetch(PDO::FETCH_ASSOC); - - if ($routineData) { - $response['apply_routine'] = true; - $response['routine_data'] = [ - 'name' => $routineData['name'] ?? 'Routine Sconosciuta', - 'instruction' => $routineData['instruction'] ?? 'Nessuna descrizione disponibile', - 'filename' => $routineData['filename'] ?? '', - 'headerrow' => $routineData['headerrow'] ?? $header_row - ]; - error_log("Routine rilevata per template {$template_id}: " . print_r($routineData, true)); - } else { - error_log("Errore: Nessuna routine trovata per idroutine {$template['idroutine']}"); - } - } else { - error_log("Nessuna routine associata al template {$template_id}"); - } - - // Aggiungi idclient alla risposta - $response['idclient'] = $template['idclient'] ?? null; - - // Salva i dati in sessione - $_SESSION['excel_data'] = $excelData; - $_SESSION['template_id'] = $template_id; - $_SESSION['headers'] = $headerRowData; - $_SESSION['mappings'] = $mappings; - - // Includi excel_data nella risposta JSON in ogni caso - $response['excel_data'] = $excelData; - $response['rows'] = array_column($excelData, 'data'); - $response['columns'] = $headerRowData; - $response['template_id'] = $template_id; - $response['filename'] = $newFilename; - } - } - } else { - $response['error'] = "Errore nell'upload del file: Codice errore $fileError."; - } - } else { - $response['error'] = "Richiesta non valida."; - } -} catch (Exception $e) { - $response['error'] = "Errore durante il caricamento del file: " . $e->getMessage(); - error_log("Exception in process_import_xls2.php: " . $e->getMessage()); -} - -// Pulisce qualsiasi output indesiderato -ob_end_clean(); - -// Invia la risposta JSON -header('Content-Type: application/json'); -echo json_encode($response); -exit; diff --git a/public/userarea/process_insert_template_xls.php b/public/userarea/process_insert_template_xls.php deleted file mode 100644 index fda7a61..0000000 --- a/public/userarea/process_insert_template_xls.php +++ /dev/null @@ -1,67 +0,0 @@ - false, "message" => ""]; - -try { - if ($_SERVER["REQUEST_METHOD"] !== "POST") { - throw new Exception("Invalid request method."); - } - - // Recupera e sanifica i dati - $name = trim($_POST['name']); - $header_row = intval($_POST['header_row']); - $start_column = trim($_POST['start_column']); - $description = trim($_POST['description'] ?? ''); - $target_table = trim($_POST['target_table']); - $idclient = intval($_POST['client_id'] ?? 0); - $clientname = trim($_POST['client_name'] ?? ''); - $idschema = intval($_POST['idschema'] ?? 0); - $schemaname = trim($_POST['schemaname'] ?? ''); - $idroutine = isset($_POST['idroutine']) && $_POST['idroutine'] !== '' ? intval($_POST['idroutine']) : null; - $button_size = trim($_POST['button_size'] ?? 'medium'); - $button_bg_color = trim($_POST['button_bg_color'] ?? '#007bff'); - $button_text_color = trim($_POST['button_text_color'] ?? '#ffffff'); - $button_label = trim($_POST['button_label'] ?? 'Click Me'); - - // Controllo sui campi obbligatori - if (empty($name) || empty($header_row) || empty($start_column) || empty($target_table) || $idclient <= 0 || $idschema <= 0) { - throw new Exception("All fields marked with * are required, including client and schema."); - } - - // Connessione al database - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - // Inserisci il nuovo template - $stmt = $pdo->prepare(" - INSERT INTO excel_templates - (name, header_row, start_column, description, target_table, idclient, clientname, idschema, schemaname, idroutine, - button_size, button_bg_color, button_text_color, button_label, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW()) - "); - $stmt->execute([ - $name, - $header_row, - $start_column, - $description, - $target_table, - $idclient, - $clientname, - $idschema, - $schemaname, - $idroutine, - $button_size, - $button_bg_color, - $button_text_color, - $button_label - ]); - - $response["success"] = true; - $response["message"] = "Template created successfully!"; -} catch (Exception $e) { - $response["message"] = $e->getMessage(); -} - -echo json_encode($response); diff --git a/public/userarea/quotations.php b/public/userarea/quotations.php deleted file mode 100644 index f2d9b43..0000000 --- a/public/userarea/quotations.php +++ /dev/null @@ -1,574 +0,0 @@ -getConnection(); - -// Recupera l'ID dell'utente loggato -$user_id = $iduserlogin ?? 1; - -// Gestione creazione nuova quotation (crea record vuoto su conferma) -if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'create') { - $description = ''; - $customer = ''; - - try { - $stmt = $pdo->prepare("INSERT INTO quotations (description, customer, iduser) VALUES (?, ?, ?)"); - $success = $stmt->execute([$description, $customer, $user_id]); - if ($success) { - $newId = $pdo->lastInsertId(); - error_log("Creata nuova quotation ID: $newId"); - header("Location: quotations.php?edit_id=" . $newId . "&status=success&message=" . urlencode("Quotation creata con successo")); - } else { - error_log("Errore: Impossibile creare la quotation, nessun ID generato."); - header("Location: quotations.php?status=error&message=" . urlencode("Errore durante la creazione della quotation")); - } - } catch (PDOException $e) { - error_log("Errore PDO durante la creazione della quotation: " . $e->getMessage()); - header("Location: quotations.php?status=error&message=" . urlencode("Errore database: " . $e->getMessage())); - } - exit; -} - -// Gestione modifica quotation -if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'update' && isset($_POST['id'])) { - $id = intval($_POST['id']); - $description = $_POST['description'] ?? ''; - $customer = $_POST['customer'] ?? ''; - - try { - $stmt = $pdo->prepare("UPDATE quotations SET description = ?, customer = ? WHERE id = ? AND iduser = ?"); - $stmt->execute([$description, $customer, $id, $user_id]); - error_log("Modificata quotation ID: $id"); - header("Location: quotations.php?status=success&message=" . urlencode("Quotation modificata con successo")); - } catch (PDOException $e) { - error_log("Errore PDO durante la modifica della quotation: " . $e->getMessage()); - header("Location: quotations.php?status=error&message=" . urlencode("Errore database: " . $e->getMessage())); - } - exit; -} - -// Gestione cancellazione quotation -if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'delete' && isset($_POST['id'])) { - $id = intval($_POST['id']); - - try { - $stmt = $pdo->prepare("DELETE FROM quotations WHERE id = ? AND iduser = ?"); - $stmt->execute([$id, $user_id]); - error_log("Cancellata quotation ID: $id"); - header("Location: quotations.php?status=success&message=" . urlencode("Quotation cancellata con successo")); - } catch (PDOException $e) { - error_log("Errore PDO durante la cancellazione della quotation: " . $e->getMessage()); - header("Location: quotations.php?status=error&message=" . urlencode("Errore database: " . $e->getMessage())); - } - exit; -} - -// Recupera tutte le quotations per l'utente -try { - $stmt = $pdo->prepare("SELECT * FROM quotations WHERE iduser = ? ORDER BY creation_date DESC"); - $stmt->execute([$user_id]); - $quotations = $stmt->fetchAll(PDO::FETCH_ASSOC); -} catch (PDOException $e) { - error_log("Errore PDO durante il recupero delle quotations: " . $e->getMessage()); - $quotations = []; -} - -// Verifica se è richiesta la modifica di una quotation -$editQuotation = null; -if (isset($_GET['edit_id'])) { - $editId = intval($_GET['edit_id']); - try { - $stmt = $pdo->prepare("SELECT * FROM quotations WHERE id = ? AND iduser = ?"); - $stmt->execute([$editId, $user_id]); - $editQuotation = $stmt->fetch(PDO::FETCH_ASSOC); - if (!$editQuotation) { - error_log("Nessuna quotation trovata per id: $editId"); - } - } catch (PDOException $e) { - error_log("Errore PDO durante il recupero della quotation per modifica: " . $e->getMessage()); - $editQuotation = null; - } -} -?> - - - - - - - - - - - - - - Gestione Quotations - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> - - - -
              - - -
              -
              -
              -
              -
              -
              -
              Gestione Quotations
              -
              -
              -
              -
              - -
              - -
              - - - -
              Modifica Quotation ID:
              -
              - - -
              - - -
              -
              - - -
              - - Torna alla Lista -
              -
              -
              Azioni
              - - -
              - - -
              - -
              -
              Quotations Esistenti
              - - - - - - - - - - - - $row): ?> - - - - - - - - - -
              IDData CreazioneDescrizioneClienteAzioni
              - - - - - - - - - -
              - -
              -
              -
              -
              - - - - -
              - - -
              -
              -
              - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/rapporto_espanso_response.json b/public/userarea/rapporto_espanso_response.json deleted file mode 100644 index 28d03eb..0000000 --- a/public/userarea/rapporto_espanso_response.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "@odata.context": "https:\/\/93.43.5.102\/limsapi\/api\/odata\/$metadata#Rapporto\/$entity", - "IdRapporto": 515081, - "DataUltimaModifica": "2025-05-14T18:11:21.02+02:00", - "DaLeggere": false, - "CodiceRapporto": "2523026", - "Data": "2025-05-14T14:05:30+02:00", - "Versione": 0, - "DataStampa": "2025-05-14T14:11:00+02:00", - "Firmato": true -} \ No newline at end of file diff --git a/public/userarea/rapporto_expanded.json b/public/userarea/rapporto_expanded.json deleted file mode 100644 index c30e053..0000000 --- a/public/userarea/rapporto_expanded.json +++ /dev/null @@ -1,13340 +0,0 @@ -{ - "@odata.context": "https://93.43.5.102/limsapi/api/odata/$metadata#Rapporto(CampioniDatiRapporto(AnalisiDatiRapporto(),CustomFieldsDatiRapporto()))/$entity", - "IdRapporto": 515081, - "DataUltimaModifica": "2025-05-14T18:11:21.02+02:00", - "DaLeggere": false, - "CodiceRapporto": "2523026", - "Data": "2025-05-14T14:05:30+02:00", - "Versione": 0, - "DataStampa": "2025-05-14T14:11:00+02:00", - "Firmato": true, - "CampioniDatiRapporto": [ - { - "IdCampioneDatiRapporto": 651935, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.04", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28370998, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28370999, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28370994, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28370996, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28371001, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28371000, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28370995, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:22+02:00", - "FineAnalisi": "2025-05-12T10:33:16+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28371025, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371007, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371010, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371015, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371019, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371018, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371023, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371020, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371004, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371013, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371016, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371027, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371017, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371024, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371005, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371008, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371009, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371022, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371021, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371026, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371014, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371012, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371011, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28371006, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:20+02:00", - "FineAnalisi": "2025-05-12T14:40:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28370992, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:21+02:00", - "FineAnalisi": "2025-05-13T10:19:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28371002, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Dimethylfumarate (DMFu)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Test method to quantitatively determine Dimethylfumarate (DMFu) in footwear materials\r\n- Test Method:\r\nISO 16186: 2021", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,05", - "LimiteQuantificazione": "0,05", - "LimitiDiLegge": "<=0,1", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-12T10:07:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16186_DMFu_Da caricare su 2 MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=0,1" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925192, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925193, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925194, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925195, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925196, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925197, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925198, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925199, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925200, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925201, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925205, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925206, - "Titolo": "Tested Component:", - "Valore": "MIX LACES + TEXTILE TONGUE", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925207, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925208, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925209, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925210, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925211, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925224, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925225, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925235, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925236, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925237, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925238, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925239, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925240, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925244, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925245, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651912, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": 810, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-12T00:00:00+02:00", - "CodiceCampione": "2523026.01", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28332143, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332144, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332139, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332141, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332146, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332145, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332140, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:16+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332147, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:15+02:00", - "FineAnalisi": "2025-05-12T10:42:41+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27924018, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27924019, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27924020, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27924021, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27924022, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27924023, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27924024, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27924025, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27924026, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27924027, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27924031, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27924032, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN PART OF SOLE, WHITE PART OF SOLE AND WHITE OUTERSOLE", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27924033, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27924034, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27924035, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27924036, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27924037, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27924050, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27924051, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27924061, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27924062, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27924063, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27924064, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27924065, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27924066, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27924070, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27924071, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651931, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-12T00:00:00+02:00", - "CodiceCampione": "2523026.02", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28332665, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332666, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332661, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332663, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332668, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332667, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332662, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:18+02:00", - "FineAnalisi": "2025-05-12T08:17:38+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332669, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:17+02:00", - "FineAnalisi": "2025-05-12T10:44:02+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27924985, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27924986, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27924987, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27924988, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27924989, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27924990, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27924991, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27924992, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27924993, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27924994, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27924998, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27924999, - "Titolo": "Tested Component:", - "Valore": "MIX OF BLACK PART OF SOLE, CARBON FIBER AND WHITE BACK PART OF SOLE", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925000, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925001, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925002, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925003, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925004, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925017, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925018, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925028, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925029, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925030, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925031, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925032, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925033, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925037, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925038, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651933, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.03", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28332698, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332699, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332697, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332703, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332701, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332700, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332702, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-12T08:17:39+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332738, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:19+02:00", - "FineAnalisi": "2025-05-13T10:36:34+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925096, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925097, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925098, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925099, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925100, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925101, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925102, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925103, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925104, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925105, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925109, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925110, - "Titolo": "Tested Component:", - "Valore": "YELLOW VIBRAM LOGO ON SOLE", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925111, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925112, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925113, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925114, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925115, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925128, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925129, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925139, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925140, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925141, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925142, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925143, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925144, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925148, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925149, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651939, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.06", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333037, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333032, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333031, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333053, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333033, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333051, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333035, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333030, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333040, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333048, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333046, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333039, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333047, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333036, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333042, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333043, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333044, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333034, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333049, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333029, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333052, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333045, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333038, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333050, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:27+02:00", - "FineAnalisi": "2025-05-13T17:04:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333058, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333059, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333054, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333056, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333061, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333060, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333055, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333062, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:26+02:00", - "FineAnalisi": "2025-05-12T14:07:05+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333064, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Dimethylfumarate (DMFu)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Test method to quantitatively determine Dimethylfumarate (DMFu) in footwear materials\r\n- Test Method:\r\nISO 16186: 2021", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,05", - "LimiteQuantificazione": "0,05", - "LimitiDiLegge": "<=0,1", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:28+02:00", - "FineAnalisi": "2025-05-12T10:07:20+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16186_DMFu_Da caricare su 2 MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=0,1" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925414, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925415, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925416, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925417, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925418, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925419, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925420, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925421, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925422, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925423, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925427, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925428, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN SUEDE UPPER AND GREEN TOE CAP", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925429, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925430, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925431, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925432, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925433, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925446, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925447, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925457, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925458, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925459, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925460, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925461, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925462, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925466, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925467, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651942, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-14T00:00:00+02:00", - "CodiceCampione": "2523026.07", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333247, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Chromium [Cr VI]", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Chemical determination of chromium (VI) content in leather - Part 2: Chromatographic method\r\n-Test Method:\r\nISO 17075-2: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Inorg", - "Reparto": "Analytical_Inorganic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "3,0", - "LimiteQuantificazione": "3,0", - "LimitiDiLegge": "<=3", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "CrVI", - "CommentoFisso": "The official method establishes the quantification limit for Chromium VI at 3 mg / kg. At this concentration, the uncertainty of the method was estimated to be 50%.\r\nFor this reason, any number below 3 mg/kg could be affected by an uncertainty equal to or greater than that estimated at the quantification limit declared by the method.\r\nThe laboratory has performed the calculation of the recovery, as required by the method, and makes available the result if required.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:29+02:00", - "FineAnalisi": "2025-05-14T12:29:33+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17075-2_Cr VI_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": "<=3" - }, - { - "IdAnalisiDatoRapporto": 28333248, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Volatile Matter", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "%", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of volatile matter\r\n- Test Method:\r\nISO 4684: 2005", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Inorg", - "Reparto": "Analytical_Inorganic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "9,5", - "RisultatoPositivo": true, - "MinimoRilevabile": "0,5", - "LimiteQuantificazione": "0,5", - "LimitiDiLegge": null, - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "\u00b10,3", - "IncertezzaStampaNumerica": 0.3, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "4684", - "CommentoFisso": "The execution of the test is needed to express some chemical tests. This parameter is not limited by legislations and Pass or Fail is indicated only when a requirement is showed in Customer's documents (ref to Requirements section Denomination).", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:30+02:00", - "FineAnalisi": "2025-05-13T09:58:58+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "9,5", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17075-2_Cr VI_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": null - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925569, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925570, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925571, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925572, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925573, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925574, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925575, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925576, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925577, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925578, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925582, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925583, - "Titolo": "Tested Component:", - "Valore": "GREEN SUEDE UPPER", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925584, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925585, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925586, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925587, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925588, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925601, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925602, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925612, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925613, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925614, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925615, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925616, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925617, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925621, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925622, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651938, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.05", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28332958, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332940, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332943, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332948, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332952, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332951, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332956, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332953, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332937, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332946, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332949, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332960, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332950, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332957, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332938, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332941, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332942, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332955, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332954, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332959, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332947, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332945, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332944, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332939, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:23+02:00", - "FineAnalisi": "2025-05-13T17:13:27+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28332966, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332967, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332962, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332964, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332969, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332968, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332963, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:33:17+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332970, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:24+02:00", - "FineAnalisi": "2025-05-13T12:43:52+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28332972, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Dimethylfumarate (DMFu)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Test method to quantitatively determine Dimethylfumarate (DMFu) in footwear materials\r\n- Test Method:\r\nISO 16186: 2021", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,05", - "LimiteQuantificazione": "0,05", - "LimitiDiLegge": "<=0,1", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:25+02:00", - "FineAnalisi": "2025-05-12T10:07:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16186_DMFu_Da caricare su 2 MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=0,1" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925360, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925361, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925362, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925363, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925364, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925365, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925366, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925367, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925368, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925369, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925373, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925374, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN LATERAL BAND AND GREEN UPPER BAND", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925375, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925376, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925377, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925378, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925379, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925392, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925393, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925403, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925404, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925405, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925406, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925407, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925408, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925412, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925413, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651943, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-14T00:00:00+02:00", - "CodiceCampione": "2523026.08", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333249, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Chromium [Cr VI]", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Chemical determination of chromium (VI) content in leather - Part 2: Chromatographic method\r\n-Test Method:\r\nISO 17075-2: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Inorg", - "Reparto": "Analytical_Inorganic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "3,0", - "LimiteQuantificazione": "3,0", - "LimitiDiLegge": "<=3", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "CrVI", - "CommentoFisso": "The official method establishes the quantification limit for Chromium VI at 3 mg / kg. At this concentration, the uncertainty of the method was estimated to be 50%.\r\nFor this reason, any number below 3 mg/kg could be affected by an uncertainty equal to or greater than that estimated at the quantification limit declared by the method.\r\nThe laboratory has performed the calculation of the recovery, as required by the method, and makes available the result if required.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:31+02:00", - "FineAnalisi": "2025-05-14T12:29:29+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17075-2_Cr VI_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": "<=3" - }, - { - "IdAnalisiDatoRapporto": 28333250, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Volatile Matter", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "%", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of volatile matter\r\n- Test Method:\r\nISO 4684: 2005", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Inorg", - "Reparto": "Analytical_Inorganic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "9,7", - "RisultatoPositivo": true, - "MinimoRilevabile": "0,5", - "LimiteQuantificazione": "0,5", - "LimitiDiLegge": null, - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "\u00b10,3", - "IncertezzaStampaNumerica": 0.3, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "4684", - "CommentoFisso": "The execution of the test is needed to express some chemical tests. This parameter is not limited by legislations and Pass or Fail is indicated only when a requirement is showed in Customer's documents (ref to Requirements section Denomination).", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:32+02:00", - "FineAnalisi": "2025-05-13T09:58:58+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "9,7", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17075-2_Cr VI_Da caricare su singolo componente_Prezzo compreso", - "LimitiDiLeggeStampa": null - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925623, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925624, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925625, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925626, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925627, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925628, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925629, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925630, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925631, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925632, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925636, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925637, - "Titolo": "Tested Component:", - "Valore": "GREEN TOE CAP", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925638, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925639, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925640, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925641, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925642, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925655, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925656, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925666, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925667, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925668, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925669, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925670, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925671, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925675, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925676, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651945, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.09", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333072, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333073, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333068, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333070, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333075, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333074, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333069, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:33+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333076, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:32+02:00", - "FineAnalisi": "2025-05-13T10:36:34+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925736, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925737, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925738, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925739, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925740, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925741, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925742, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925743, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925744, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925745, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925749, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925750, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN EYELET AND PLASTIC END OF LACES", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925751, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925752, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925753, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925754, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925755, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925768, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925769, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925779, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925780, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925781, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925782, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925783, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925784, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925788, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925789, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651946, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.10", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333099, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333081, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333084, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333089, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333093, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333092, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333097, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333094, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333078, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333087, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333090, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333101, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333091, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333098, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333079, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333082, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333083, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333096, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333095, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333100, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333088, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333086, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333085, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333080, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022...", - "GruppoRapporto": "Aromatic amines derived from azodyes on fabric", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Textiles - Methods for determination of certain aromatic amines derived from azo colorants \r\nPart 1: Detection of the use of certain Azo colorants accessible with and without extracting the fibres\r\n- Test Method: \r\nUNI EN ISO 14362-1: 2017", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:34+02:00", - "FineAnalisi": "2025-05-13T17:13:28+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 14362-1_Azo (tessile)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925790, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925791, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925792, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925793, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925794, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925795, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925796, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925797, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925798, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925799, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925803, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925804, - "Titolo": "Tested Component:", - "Valore": "MIX OF GREEN LOOP OF LACES AND BACK LITLLE FLAG LABEL", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925805, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925806, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925807, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925808, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925809, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925822, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925823, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925833, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925834, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925835, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925836, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925837, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925838, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925842, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925843, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 651947, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-13T00:00:00+02:00", - "CodiceCampione": "2523026.11", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28333118, - "CodiceParametro": null, - "CodiceCas": "92-67-1", - "ParametroRapporto": "4-Aminobiphenyl", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333113, - "CodiceParametro": null, - "CodiceCas": "92-87-5", - "ParametroRapporto": "Benzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333112, - "CodiceParametro": null, - "CodiceCas": "95-69-2", - "ParametroRapporto": "4-Chloro-o-toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333134, - "CodiceParametro": null, - "CodiceCas": "91-59-8", - "ParametroRapporto": "2-Naphthylamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "(1)", - "CommentoFisso": "If the use of this analytical method has detected 4-aminodiphenyl and/or 2-naphtylamine, according to the current state of knowledge it cannot be unequivocally confirmed without additional information that azo colorants which release amines were used.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333114, - "CodiceParametro": null, - "CodiceCas": "97-56-3", - "ParametroRapporto": "o-Aminoazotoluene ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333132, - "CodiceParametro": null, - "CodiceCas": "99-55-8", - "ParametroRapporto": "5-nitro-o-toluidine ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333116, - "CodiceParametro": null, - "CodiceCas": "106-47-8", - "ParametroRapporto": "4-Chloroaniline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333111, - "CodiceParametro": null, - "CodiceCas": "615-05-04", - "ParametroRapporto": "4-methoxy-m-phenylenediamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333121, - "CodiceParametro": null, - "CodiceCas": "101-77-9", - "ParametroRapporto": "4,4'-methylenedianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "MDA", - "CommentoFisso": "\nIn case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 4,4'-methylene-dianiline (MDA, CAS number 101-77-9) are released from the PU component and not from a banned azo colorant.\r\nIn case of pigment prints care has to be taken that 4,4'-methylene-dianiline is not released from a source of banned azo colorants but from e.g. a chemical fixing agent.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333129, - "CodiceParametro": null, - "CodiceCas": "91-94-1", - "ParametroRapporto": "3,3'-Dichlorobenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333127, - "CodiceParametro": null, - "CodiceCas": "119-90-4", - "ParametroRapporto": "3,3'-Dimethoxybenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333120, - "CodiceParametro": null, - "CodiceCas": "119-93-7", - "ParametroRapporto": "3,3'-Dimethylbenzidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333128, - "CodiceParametro": null, - "CodiceCas": "838-88-0", - "ParametroRapporto": "4,4'-methylenedi-o-toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333117, - "CodiceParametro": null, - "CodiceCas": "120-71-8", - "ParametroRapporto": "p-cresidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333123, - "CodiceParametro": null, - "CodiceCas": "101-14-4", - "ParametroRapporto": "4-4'-Methylene-bis-(2-chloroaniline)", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333124, - "CodiceParametro": null, - "CodiceCas": "101-80-4", - "ParametroRapporto": "4-4'-Oxydianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333125, - "CodiceParametro": null, - "CodiceCas": "139-65-1", - "ParametroRapporto": "4-4'-Thiodianiline", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333115, - "CodiceParametro": null, - "CodiceCas": "95-53-4", - "ParametroRapporto": "o-Toluidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333130, - "CodiceParametro": null, - "CodiceCas": "95-80-7", - "ParametroRapporto": "4-methyl-m-phenylenediamine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": "TDA", - "CommentoFisso": "In case of polyurethane materials are used, e.g. PU foams and coatings and in prints, it cannot be ruled out that certain amines, e.g. 2,4-toluen-diamine (TDA, CAS 95-80-7) are released from the PU component and not from a banned azo colorant.", - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333110, - "CodiceParametro": null, - "CodiceCas": "137-17-7", - "ParametroRapporto": "2,4,5-Trimethylaniline ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333133, - "CodiceParametro": null, - "CodiceCas": "90-04-0", - "ParametroRapporto": "o-anisidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333126, - "CodiceParametro": null, - "CodiceCas": "60-09-3", - "ParametroRapporto": "4-Aminoazobenzene", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333119, - "CodiceParametro": null, - "CodiceCas": "95-68-1", - "ParametroRapporto": "2,4- Xylidine", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333131, - "CodiceParametro": null, - "CodiceCas": "87-62-7", - "ParametroRapporto": "2,6-Xylidine ", - "CodiceGruppo": "0022", - "GruppoRapporto": "Aromatic amines derived from azodyes on leather", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of certain AZO colorants in dyed leathers.\r\nPart 1: Determination of certain aromatic amines derived from azo colorants \r\n- Test Method:\r\nISO 17234-1: 2024", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "5", - "LimiteQuantificazione": "5", - "LimitiDiLegge": "<=30", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-13T17:04:36+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 17234-1_Azo (pelle)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=30" - }, - { - "IdAnalisiDatoRapporto": 28333171, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333172, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333167, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333169, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333174, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333173, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333168, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:36+02:00", - "FineAnalisi": "2025-05-12T10:33:18+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su MIX (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333175, - "CodiceParametro": null, - "CodiceCas": "NA", - "ParametroRapporto": "Dioctyl tin (DOT)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determination of Organotin Compounds in footwear materials\r\n- Test Method:\r\nISO/TS 16179: 2012", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,2", - "LimiteQuantificazione": "0,2", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:35+02:00", - "FineAnalisi": "2025-05-13T10:36:35+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16179_Organotin compounds (DOT)_Da caricare su MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28333177, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Dimethylfumarate (DMFu)", - "CodiceGruppo": null, - "GruppoRapporto": null, - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Test method to quantitatively determine Dimethylfumarate (DMFu) in footwear materials\r\n- Test Method:\r\nISO 16186: 2021", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "0,05", - "LimiteQuantificazione": "0,05", - "LimitiDiLegge": "<=0,1", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": true, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:35+02:00", - "FineAnalisi": "2025-05-12T10:07:20+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "ISO 16186_DMFu_Da caricare su 2 MIX_Prezzo compreso", - "LimitiDiLeggeStampa": "<=0,1" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27925844, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27925845, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27925846, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27925847, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27925848, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27925849, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27925850, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27925851, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27925852, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27925853, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27925857, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27925858, - "Titolo": "Tested Component:", - "Valore": "MIX OF INSOLE AND LINING", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27925859, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27925860, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27925861, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27925862, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27925863, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27925876, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27925877, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27925887, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27925888, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27925889, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27925890, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27925891, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27925892, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27925896, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27925897, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - }, - { - "IdCampioneDatiRapporto": 652180, - "DataAccettazione": "2025-05-06T00:00:00+02:00", - "DataCampione": "2025-05-06T00:00:00+02:00", - "NotaEmendamento": null, - "LegendaStampeCompagnia": null, - "LegendaAccreditamentoCompagnia": null, - "Riferimento": "Analyses purchased by Moncler Compliance_CB\r\nSeason 20251\r\nSample Code: K109B4M00140M6019\r\nSample Description TRAILGRIP LITE2\r\nColour Code: 80T\r\nStyle Code: K109B4M00140M6019\r\nStyle Description: TRAILGRIP LITE2\r\nCDC FP-ACC\r\nComposition Claimed /\r\nCollection: P\r\nRequirements: According to Turkey's customs regulations\r\nCategory: Adult\r\nApplication: Footwear\r\nType of Material: Shoe\r\nVendor: STELLA INTL TRADING (M.C.O.) LTD\r\nMONCLER\r\nRequested Tests: Turkey Shoes/Bags Package\r\nDelivery Note: NOT PROVIDED\r\nSampling: done by the client \r\nSample preparation for chemical tests: the leather sample is ground as requested in method UNI EN ISO 4044:2017 (when required in the test method).", - "NoteRapporto": null, - "GiudizioRapporto": null, - "GiudizioCertificato": null, - "LegendaStampeCompagniaCampione": null, - "LegendaAccreditamentoCompagniaCampione": null, - "NoteSegreteria": null, - "StatoCampione": "StampatoRapporto", - "StatoCampioneWeb": "Stampato Rapporto", - "DataInizioAnalisiCampione": "2025-05-07T00:00:00+02:00", - "DataFineAnalisiCampione": "2025-05-14T00:00:00+02:00", - "CodiceRapportoPrecedente": null, - "VersioneRapportoPrecedente": null, - "DataRapportoPrecedente": null, - "CodicePrimoRapporto": "2523026", - "DataPrimoRapporto": "2025-05-14T14:05:30+02:00", - "DataStampa": "2025-05-14T00:00:00+02:00", - "RiferimentoFisso": "", - "EsitoGiudizioLMR": null, - "EsitoGiudizioImpiego": null, - "StampaGiudizioLMR": false, - "StampaGiudizioImpieghi": false, - "CampioneBiologico": false, - "RisultatiPositivi": true, - "RisultatiIrregolari": false, - "Matrice": "MONCLER_Footwear_FINISHED PRODUCT_TURKEY PACKAGE + Turkey's customs regulations + Pack March 2025_ENG", - "Sottomatrice": null, - "DescrizioneMatrice": null, - "MacroMatrice": "MONCLER (@Fatturazione)", - "CodiceRapporto": "2523026", - "VersioneRapporto": 0, - "CodiceAccettazione": "2523026", - "DataRapporto": "2025-05-14T00:00:00+02:00", - "NominativoResponsabile": "COMPLIANCE +Gallin+Zavag+Costanzi (SCARPE E BORSE)", - "PrezzoCampione": null, - "DataModificaParcheggio": null, - "Scadenza": "2025-05-13T00:00:00+02:00", - "CodiceFattura": "RN25004873", - "DataFattura": "2025-05-29T00:00:00+02:00", - "BloccoInvio": false, - "DataValidazione": "2025-05-12T00:00:00+02:00", - "CodiceCampione": "2523026.12", - "OraCampione": "1900-01-01T17:43:17+01:00", - "AnalisiDatiRapporto": [ - { - "IdAnalisiDatoRapporto": 28343776, - "CodiceParametro": null, - "CodiceCas": "84-74-2", - "ParametroRapporto": "Dibutyl Phthalate (DBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343777, - "CodiceParametro": null, - "CodiceCas": "85-68-7", - "ParametroRapporto": "Butyl Benzil Phthalate (BBP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343775, - "CodiceParametro": null, - "CodiceCas": "117-81-7", - "ParametroRapporto": "Bis-2-Etylhexyl Phthalate (DEHP)", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343781, - "CodiceParametro": null, - "CodiceCas": "117-84-0", - "ParametroRapporto": "Di-n-octyll Phthalate (DnOP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "10", - "LimiteQuantificazione": "10", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343779, - "CodiceParametro": null, - "CodiceCas": "68515-49-1", - "ParametroRapporto": "Di-iso-decil Phthalate (DIDP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343778, - "CodiceParametro": null, - "CodiceCas": "68515-48-0", - "ParametroRapporto": "Di-iso-nonyl Phthalate (DINP) ", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": "100", - "LimiteQuantificazione": "100", - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - }, - { - "IdAnalisiDatoRapporto": 28343780, - "CodiceParametro": null, - "CodiceCas": null, - "ParametroRapporto": "Sum of all Phthalates", - "CodiceGruppo": "0036abd", - "GruppoRapporto": "Phthalates (*)", - "UnitaMisuraRapporto": "mg/kg", - "LegendaUnitaMisura": null, - "MetodoRapporto": "Determining Phthalates\r\n- Test Method:\r\nCPSC-CH-C1001-09.4: 2018", - "NotaIncertezzaMetodo": null, - "CodiceReparto": "Chim_Org", - "Reparto": "Analytical_Organic", - "NotaIncertezzaReparto": null, - "RisultatoStampa": "< L.O.Q.", - "RisultatoPositivo": false, - "MinimoRilevabile": null, - "LimiteQuantificazione": null, - "LimitiDiLegge": "<=1000", - "LimiteMinimo": null, - "LimitiCliente": null, - "CodiceDecretoLegge": null, - "DecretoLegge": null, - "IncertezzaStampaTestuale": "", - "IncertezzaStampaNumerica": 0, - "IncertezzaStampaTipo": "Nessuno", - "CodiceCommentoFisso": null, - "CommentoFisso": null, - "CodiceCommento": null, - "Commento": null, - "Accreditato": false, - "AccreditatoFlessibile": false, - "Esito": "Pass", - "TipoEsito": "Regolare", - "Subappalto": false, - "CodiceStabilimento": "CT", - "LegendaStabilimento": null, - "LegendaStabilimentoAccreditati": null, - "AccreditamentoStabilimento": "01123", - "InizioAnalisi": "2025-05-09T14:54:37+02:00", - "FineAnalisi": "2025-05-12T10:33:19+02:00", - "StampaInRapporto": true, - "RisultatoDescrittivo": null, - "IncertezzaManuale": null, - "Risultato": "N.R.", - "CodiceMacrogruppo": null, - "Macrogruppo": "CPSC C1001-09_Phthalates_Da caricare su singolo componente (fodera)_Prezzo compreso", - "LimitiDiLeggeStampa": "<=1000" - } - ], - "CustomFieldsDatiRapporto": [ - { - "IdCustomFieldDatoRapporto": 27938052, - "Titolo": "Fornitore:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 142 - }, - { - "IdCustomFieldDatoRapporto": 27938053, - "Titolo": "Tipologia di Trattamento Superficiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 146 - }, - { - "IdCustomFieldDatoRapporto": 27938054, - "Titolo": "Tipologia di concia: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 147 - }, - { - "IdCustomFieldDatoRapporto": 27938055, - "Titolo": "Destinazione d'uso: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 150 - }, - { - "IdCustomFieldDatoRapporto": 27938056, - "Titolo": "Tipologia di Materiale:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 156 - }, - { - "IdCustomFieldDatoRapporto": 27938057, - "Titolo": "Categoria:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 161 - }, - { - "IdCustomFieldDatoRapporto": 27938058, - "Titolo": "Campionamento:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 163 - }, - { - "IdCustomFieldDatoRapporto": 27938059, - "Titolo": "Condizionamento prima e durante il Test: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 165 - }, - { - "IdCustomFieldDatoRapporto": 27938060, - "Titolo": "Note:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 166 - }, - { - "IdCustomFieldDatoRapporto": 27938061, - "Titolo": "Capitolato di riferimento", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 167 - }, - { - "IdCustomFieldDatoRapporto": 27938065, - "Titolo": "Preparazione del campione ai test chimici: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 181 - }, - { - "IdCustomFieldDatoRapporto": 27938066, - "Titolo": "Tested Component:", - "Valore": "N\u00b0 38 INNER LABEL", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 189 - }, - { - "IdCustomFieldDatoRapporto": 27938067, - "Titolo": "DDT N. ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 193 - }, - { - "IdCustomFieldDatoRapporto": 27938068, - "Titolo": "Fabbricante:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 194 - }, - { - "IdCustomFieldDatoRapporto": 27938069, - "Titolo": "Composition Claimed", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 207 - }, - { - "IdCustomFieldDatoRapporto": 27938070, - "Titolo": "Sample Description ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 210 - }, - { - "IdCustomFieldDatoRapporto": 27938071, - "Titolo": "Season", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 214 - }, - { - "IdCustomFieldDatoRapporto": 27938084, - "Titolo": "Style Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 263 - }, - { - "IdCustomFieldDatoRapporto": 27938085, - "Titolo": "Color Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 264 - }, - { - "IdCustomFieldDatoRapporto": 27938095, - "Titolo": "Sample Code:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 467 - }, - { - "IdCustomFieldDatoRapporto": 27938096, - "Titolo": "Style Description:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 468 - }, - { - "IdCustomFieldDatoRapporto": 27938097, - "Titolo": "Collezione:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 543 - }, - { - "IdCustomFieldDatoRapporto": 27938098, - "Titolo": "Additional Info:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 555 - }, - { - "IdCustomFieldDatoRapporto": 27938099, - "Titolo": "Final Customer: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 595 - }, - { - "IdCustomFieldDatoRapporto": 27938100, - "Titolo": "Analisi Richieste:", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 748 - }, - { - "IdCustomFieldDatoRapporto": 27938104, - "Titolo": "CDC", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1014 - }, - { - "IdCustomFieldDatoRapporto": 27938105, - "Titolo": "MONCLER_Analisi Commissionate da: ", - "Valore": "", - "CodiceAnagrafica": null, - "FornitoDaCommittente": 0, - "ScostamentoDaCondizioni": 0, - "CustomField": 1083 - } - ] - } - ] -} \ No newline at end of file diff --git a/public/userarea/remove_column_mapping.php b/public/userarea/remove_column_mapping.php deleted file mode 100644 index 97316a9..0000000 --- a/public/userarea/remove_column_mapping.php +++ /dev/null @@ -1,62 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents("php://input"), true); - -if (!isset($data['template_id'], $data['excel_column'], $data['mysql_column'], $data['tablename'])) { - echo json_encode(["success" => false, "message" => "Missing required fields"]); - exit; -} - -// Rimuove l'associazione -$stmtDelete = $pdo->prepare(" - DELETE FROM excel_column_mappings - WHERE template_id = ? AND excel_column = ? AND mysql_column = ? AND tablename = ? -"); -$result = $stmtDelete->execute([ - $data['template_id'], - $data['excel_column'], - $data['mysql_column'], - $data['tablename'] -]); - -if (!$result) { - echo json_encode(["success" => false, "message" => "Failed to delete mapping"]); - exit; -} - -// Dopo la rimozione, aggiorna la lista delle colonne disponibili -$stmtColumns = $pdo->prepare("SHOW COLUMNS FROM " . $data['tablename']); -$stmtColumns->execute(); -$all_mysql_columns = array_column($stmtColumns->fetchAll(PDO::FETCH_ASSOC), 'Field'); - -$stmtHeader = $pdo->prepare("SELECT headerexcel FROM excel_column_mappings WHERE template_id = ? LIMIT 1"); -$stmtHeader->execute([$data['template_id']]); -$headerRow = $stmtHeader->fetch(PDO::FETCH_ASSOC); -$xls_headers = isset($headerRow['headerexcel']) ? explode(",", $headerRow['headerexcel']) : []; - -// Ricalcola le colonne non associate -$stmtMappings = $pdo->prepare("SELECT excel_column, mysql_column FROM excel_column_mappings WHERE template_id = ?"); -$stmtMappings->execute([$data['template_id']]); -$existingMappings = $stmtMappings->fetchAll(PDO::FETCH_ASSOC); - -$mapped_xls_columns = array_column($existingMappings, 'excel_column'); -$mapped_mysql_columns = array_column($existingMappings, 'mysql_column'); - -$remaining_xls_columns = array_diff($xls_headers, $mapped_xls_columns); -$remaining_mysql_columns = array_diff($all_mysql_columns, $mapped_mysql_columns); - -echo json_encode([ - "success" => true, - "remaining_xls_columns" => array_values($remaining_xls_columns), - "remaining_mysql_columns" => array_values($remaining_mysql_columns) -]); -exit; diff --git a/public/userarea/renumber_parts.php b/public/userarea/renumber_parts.php deleted file mode 100644 index e32f80c..0000000 --- a/public/userarea/renumber_parts.php +++ /dev/null @@ -1,63 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents('php://input'), true); - -$iddatadb = $data['iddatadb'] ?? null; -$parts = $data['parts'] ?? []; - -if (!$iddatadb || empty($parts)) { - echo json_encode(['success' => false, 'message' => 'Dati mancanti']); - exit; -} - -try { - $pdo->beginTransaction(); - - // Elimina tutte le parti esistenti per l'iddatadb per evitare conflitti di unicità - $stmt = $pdo->prepare("DELETE FROM identification_parts WHERE iddatadb = :iddatadb"); - $stmt->execute([':iddatadb' => $iddatadb]); - - // Prepara l'inserimento delle nuove parti - $stmt = $pdo->prepare(" - INSERT INTO identification_parts - (iddatadb, part_number, part_description, mix, created_at, updated_at) - VALUES (:iddatadb, :part_number, :part_description, :mix, NOW(), NOW()) - "); - - $part_ids = []; - foreach ($parts as $part) { - $partNumber = $part['part_number'] ?? null; - $partDescription = $part['part_description'] ?? ''; - $mix = $part['mix'] ?? 'N'; - - if (!$partNumber || !$partDescription) { - throw new PDOException("Numero parte o descrizione mancante per parte: " . json_encode($part)); - } - - $stmt->execute([ - ':iddatadb' => $iddatadb, - ':part_number' => $partNumber, - ':part_description' => $partDescription, - ':mix' => $mix - ]); - $part_ids[] = $pdo->lastInsertId(); - } - - $pdo->commit(); - echo json_encode([ - 'success' => true, - 'part_ids' => $part_ids, - 'message' => 'Parti rinumerate con successo' - ]); -} catch (PDOException $e) { - $pdo->rollBack(); - echo json_encode([ - 'success' => false, - 'message' => 'Errore nel salvataggio: ' . $e->getMessage() - ]); -} diff --git a/public/userarea/renumber_parts_quotation.php b/public/userarea/renumber_parts_quotation.php deleted file mode 100644 index 3c455cb..0000000 --- a/public/userarea/renumber_parts_quotation.php +++ /dev/null @@ -1,63 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents('php://input'), true); - -$idquotations = $data['idquotations'] ?? null; -$parts = $data['parts'] ?? []; - -if (!$idquotations || empty($parts)) { - echo json_encode(['success' => false, 'message' => 'Dati mancanti']); - exit; -} - -try { - $pdo->beginTransaction(); - - // Elimina tutte le parti esistenti per idquotations - $stmt = $pdo->prepare("DELETE FROM identification_parts WHERE idquotations = :idquotations"); - $stmt->execute([':idquotations' => $idquotations]); - - // Prepara l'inserimento delle nuove parti - $stmt = $pdo->prepare(" - INSERT INTO identification_parts - (idquotations, part_number, part_description, mix, created_at, updated_at) - VALUES (:idquotations, :part_number, :part_description, :mix, NOW(), NOW()) - "); - - $part_ids = []; - foreach ($parts as $part) { - $partNumber = $part['part_number'] ?? null; - $partDescription = $part['part_description'] ?? ''; - $mix = $part['mix'] ?? 'N'; - - if (!$partNumber || !$partDescription) { - throw new PDOException("Numero parte o descrizione mancante per parte: " . json_encode($part)); - } - - $stmt->execute([ - ':idquotations' => $idquotations, - ':part_number' => $partNumber, - ':part_description' => $partDescription, - ':mix' => $mix - ]); - $part_ids[] = $pdo->lastInsertId(); - } - - $pdo->commit(); - echo json_encode([ - 'success' => true, - 'part_ids' => $part_ids, - 'message' => 'Parti rinumerate con successo' - ]); -} catch (PDOException $e) { - $pdo->rollBack(); - echo json_encode([ - 'success' => false, - 'message' => 'Errore nel salvataggio: ' . $e->getMessage() - ]); -} diff --git a/public/userarea/save_annotated_photo.php b/public/userarea/save_annotated_photo.php deleted file mode 100644 index 2f277ba..0000000 --- a/public/userarea/save_annotated_photo.php +++ /dev/null @@ -1,76 +0,0 @@ - false, 'message' => 'Dati mancanti']); - exit; -} - -if (!preg_match('/^[a-zA-Z0-9_-]+\.(png|jpg|jpeg)$/', $filename)) { - echo json_encode(['success' => false, 'message' => 'Nome file non valido']); - exit; -} - -if (!is_numeric($iddatadb)) { - echo json_encode(['success' => false, 'message' => 'ID non valido']); - exit; -} - -$allowedTypes = ['image/png', 'image/jpeg']; -if (!in_array($file['type'], $allowedTypes)) { - echo json_encode(['success' => false, 'message' => 'Formato file non supportato']); - exit; -} - -try { - $dbHandler = DBHandlerSelect::getInstance(); - $pdo = $dbHandler->getConnection(); - $stmt = $pdo->prepare("SELECT iddatadb FROM datadb WHERE iddatadb = :iddatadb"); - $stmt->execute([':iddatadb' => $iddatadb]); - if (!$stmt->fetch()) { - echo json_encode(['success' => false, 'message' => 'iddatadb non valido']); - exit; - } - - $dirPath = '../photostrf/annotated'; - if (!file_exists($dirPath)) { - mkdir($dirPath, 0755, true); - } - - $filePath = $dirPath . '/' . $filename; - if (file_exists($filePath)) { - echo json_encode(['success' => false, 'message' => 'File già esistente']); - exit; - } - - if (!move_uploaded_file($file['tmp_name'], $filePath)) { - echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio del file']); - exit; - } - - $stmt = $pdo->prepare(" - INSERT INTO datadb_photos (iddatadb, file_path, file_name, uploaded_at, uploaded_by) - VALUES (:iddatadb, :file_path, :file_name, NOW(), :uploaded_by) - "); - $stmt->execute([ - ':iddatadb' => $iddatadb, - ':file_path' => $filePath, - ':file_name' => $filename, - ':uploaded_by' => $iduserlogin - ]); - - echo json_encode([ - 'success' => true, - 'file_path' => $filePath, - 'message' => 'Foto salvata con successo e registrata nel DB' - ]); -} catch (Exception $e) { - echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]); -} diff --git a/public/userarea/save_annotated_photo_quotation.php b/public/userarea/save_annotated_photo_quotation.php deleted file mode 100644 index 0abb218..0000000 --- a/public/userarea/save_annotated_photo_quotation.php +++ /dev/null @@ -1,76 +0,0 @@ - false, 'message' => 'Dati mancanti o utente non autenticato']); - exit; -} - -if (!preg_match('/^[a-zA-Z0-9_-]+\.(png|jpg|jpeg)$/', $filename)) { - echo json_encode(['success' => false, 'message' => 'Nome file non valido']); - exit; -} - -if (!is_numeric($idquotations)) { - echo json_encode(['success' => false, 'message' => 'ID non valido']); - exit; -} - -$allowedTypes = ['image/png', 'image/jpeg']; -if (!in_array($file['type'], $allowedTypes)) { - echo json_encode(['success' => false, 'message' => 'Formato file non supportato']); - exit; -} - -try { - $dbHandler = DBHandlerSelect::getInstance(); - $pdo = $dbHandler->getConnection(); - $stmt = $pdo->prepare("SELECT id FROM quotations WHERE id = :idquotations"); - $stmt->execute([':idquotations' => $idquotations]); - if (!$stmt->fetch()) { - echo json_encode(['success' => false, 'message' => 'idquotations non valido']); - exit; - } - - $dirPath = '../photostrf/annotated'; - if (!file_exists($dirPath)) { - mkdir($dirPath, 0755, true); - } - - $filePath = $dirPath . '/' . $filename; - if (file_exists($filePath)) { - echo json_encode(['success' => false, 'message' => 'File già esistente']); - exit; - } - - if (!move_uploaded_file($file['tmp_name'], $filePath)) { - echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio del file']); - exit; - } - - $stmt = $pdo->prepare(" - INSERT INTO datadb_photos (idquotations, file_path, file_name, uploaded_at, uploaded_by) - VALUES (:idquotations, :file_path, :file_name, NOW(), :uploaded_by) - "); - $stmt->execute([ - ':idquotations' => $idquotations, - ':file_path' => $filePath, - ':file_name' => $filename, - ':uploaded_by' => $iduserlogin - ]); - - echo json_encode([ - 'success' => true, - 'file_path' => $filePath, - 'message' => 'Foto salvata con successo e registrata nel DB' - ]); -} catch (Exception $e) { - echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]); -} diff --git a/public/userarea/save_column_mapping.php b/public/userarea/save_column_mapping.php deleted file mode 100644 index 6b826d8..0000000 --- a/public/userarea/save_column_mapping.php +++ /dev/null @@ -1,412 +0,0 @@ -getConnection(); -$stmt = $pdo->prepare("SELECT name, header_row, start_column, target_table, sample_xlsx, idclient, clientname, idschema, schemaname, schemajson FROM excel_templates WHERE id = ?"); -$stmt->execute([$id]); -$template = $stmt->fetch(PDO::FETCH_ASSOC); - -if (!$template) { - die("Template not found"); -} - -$clientName = $template['clientname'] ?: ''; -$schemaName = $template['schemaname'] ?: ''; -$schemajson = $template['schemajson'] ? json_decode($template['schemajson'], true) : []; -$isSchemajsonEmpty = empty(trim($template['schemajson'])); - -// Recupera i campi dalla tabella template_mapping -$stmt = $pdo->prepare("SELECT id, field_id, excel_column, is_manual, manual_default, data_type, is_required, default_value, has_list, length, decimals, min_value, max_value, default_curr_date, tablename, field_label FROM template_mapping WHERE template_id = ?"); -$stmt->execute([$id]); -$mappings = $stmt->fetchAll(PDO::FETCH_ASSOC); -?> - - - - - - - - - - Configure Template <?= htmlspecialchars($template['name'], ENT_QUOTES, 'UTF-8'); ?> - - - - -
              - - -
              -
              - - -
              -
              -
              -
              -
              Configure Template:
              -

              - Client: | - Schema: | - Header Row: | - Start Column: -

              -
              -
              -
              -
              -
              - - - - - ✅ Current file: - - No file uploaded yet. - - -
              - -
              -
              -
              -
              Schema Fields Configuration
              - -
              - - - - - - - - - - - - - - - - - - - - - - - -
              TitleIDTypeMappingDefault ValueAction
              - - - - - - - - -
              -
              -
              - -
              -
              Current Configurations
              -
                -
                - - -
                -
                -
                -
                -
                - - -
                - - - - - - \ No newline at end of file diff --git a/public/userarea/save_edited_data.php b/public/userarea/save_edited_data.php deleted file mode 100644 index 35a8ce0..0000000 --- a/public/userarea/save_edited_data.php +++ /dev/null @@ -1,47 +0,0 @@ - false, 'message' => '']; - -try { - if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['iddatadb'])) { - throw new Exception('Richiesta non valida'); - } - - $iddatadb = intval($_POST['iddatadb']); - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - // Campi non modificabili - $excludeFields = ['importdate', 'status', 'user_id', 'filename_import', 'importreferencecode', 'limscode']; - - // Prepara i dati da aggiornare - $updates = []; - $values = []; - foreach ($_POST as $key => $value) { - if ($key !== 'iddatadb' && !in_array($key, $excludeFields)) { - $updates[] = "$key = ?"; - $values[] = htmlspecialchars($value); - } - } - $values[] = $iddatadb; - - if (empty($updates)) { - throw new Exception('Nessun dato da aggiornare'); - } - - $sql = "UPDATE datadb SET " . implode(', ', $updates) . " WHERE iddatadb = ?"; - $stmt = $pdo->prepare($sql); - $stmt->execute($values); - - $response['success'] = true; - $response['message'] = 'Riga aggiornata con successo'; -} catch (Exception $e) { - $response['message'] = $e->getMessage(); - error_log("Errore in save_edited_row.php: " . $e->getMessage()); -} - -echo json_encode($response); -exit; diff --git a/public/userarea/save_edited_row.php b/public/userarea/save_edited_row.php deleted file mode 100644 index 966b43d..0000000 --- a/public/userarea/save_edited_row.php +++ /dev/null @@ -1,92 +0,0 @@ - false, 'message' => '']; - -try { - if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['iddatadb'])) { - throw new Exception('Richiesta non valida'); - } - - $iddatadb = intval($_POST['iddatadb']); - $idclient = isset($_POST['idclient']) ? (is_numeric($_POST['idclient']) ? intval($_POST['idclient']) : null) : null; - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - $data = $_POST; - $details = []; - - // 1. Estrarre i dettagli da POST - foreach ($data as $key => $value) { - if (preg_match('/^details(\d+)field_value$/', $key, $matches)) { - $id = $matches[1]; - $details[$id] = $value; - } - } - - // 2. Recupera i valori esistenti da import_data_details - $stmt = $pdo->prepare("SELECT mapping_id, field_value FROM import_data_details WHERE id = ?"); - $stmt->execute([$iddatadb]); - $currentValues = []; - while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { - $currentValues[$row['mapping_id']] = $row['field_value']; - } - - // 3. Confronta i valori nuovi con quelli esistenti - $changed = []; - foreach ($details as $id => $newValue) { - $oldValue = $currentValues[$id] ?? null; - if ($oldValue !== $newValue) { - $changed[$id] = [ - 'old' => $oldValue, - 'new' => $newValue - ]; - } - } - - // 4. Aggiorna i dettagli se ci sono modifiche - if (!empty($changed)) { - $updateStmt = $pdo->prepare(" - UPDATE import_data_details - SET field_value = :newValue - WHERE id = :iddatadb AND mapping_id = :mappingId - "); - - foreach ($changed as $mappingId => $values) { - $updateStmt->execute([ - ':newValue' => $values['new'], - ':iddatadb' => $iddatadb, - ':mappingId' => $mappingId - ]); - } - } - - // 5. Aggiorna idclient in datadb - if (isset($idclient)) { - $updateStmt = $pdo->prepare(" - UPDATE datadb - SET idclient = :idclient - WHERE iddatadb = :iddatadb - "); - $updateStmt->execute([ - ':idclient' => $idclient, - ':iddatadb' => $iddatadb - ]); - $response['message'] = !empty($changed) ? "Updated details and idclient successfully" : "Updated idclient successfully"; - } else { - $response['message'] = !empty($changed) ? "Updated details successfully" : "No changes found"; - } - - $response['success'] = true; - $response['changed'] = $changed; // Debug / optional - -} catch (Exception $e) { - $response['success'] = false; - $response['message'] = $e->getMessage(); - error_log("Errore in save_edited_row.php: " . $e->getMessage()); -} - -echo json_encode($response); -exit; diff --git a/public/userarea/save_mapping_json.php b/public/userarea/save_mapping_json.php deleted file mode 100644 index 9f11992..0000000 --- a/public/userarea/save_mapping_json.php +++ /dev/null @@ -1,39 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents("php://input"), true); - -if (!$data || !isset($data['id'])) { - echo json_encode(["success" => false, "message" => "Invalid or missing ID"]); - exit; -} - -$mappingId = $data['id']; -$mappingType = $data['mapping_type'] ?? ''; -$excelColumn = $data['excel_column'] ?? null; -$manualDefault = $data['manual_default'] ?? null; -$tablename = $data['tablename'] ?? ''; - -try { - $stmt = $pdo->prepare("UPDATE template_mapping SET is_manual = ?, excel_column = ?, manual_default = ? WHERE id = ?"); - $isManual = ($mappingType === 'manual') ? 1 : 0; - $result = $stmt->execute([$isManual, $excelColumn, $manualDefault, $mappingId]); - - if (!$result) { - echo json_encode(["success" => false, "message" => "Database update failed"]); - exit; - } - - echo json_encode(["success" => true, "message" => "Mapping updated successfully", "data" => $data]); // Aggiunto debug -} catch (Exception $e) { - echo json_encode(["success" => false, "message" => "Error: " . $e->getMessage()]); -} -exit; diff --git a/public/userarea/save_matrice.php b/public/userarea/save_matrice.php deleted file mode 100644 index e569e40..0000000 --- a/public/userarea/save_matrice.php +++ /dev/null @@ -1,39 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents('php://input'), true); - -$iddatadb = $data['iddatadb'] ?? null; -$parts = $data['parts'] ?? []; - -if (!$iddatadb || empty($parts)) { - echo json_encode(['success' => false, 'message' => 'Dati mancanti']); - exit; -} - -$part = $parts[0]; -$partId = $part['id'] ?? null; -$idmatrice = $part['idmatrice'] ?? null; - -if (!$partId) { - echo json_encode(['success' => false, 'message' => 'ID parte mancante']); - exit; -} - -try { - $stmt = $pdo->prepare("UPDATE identification_parts - SET idmatrice = :idmatrice, - updated_at = NOW() - WHERE id = :id"); - $stmt->execute([ - ':id' => $partId, - ':idmatrice' => $idmatrice // Può essere NULL - ]); - echo json_encode(['success' => true, 'message' => 'Matrice aggiornata con successo']); -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio della matrice: ' . $e->getMessage()]); -} diff --git a/public/userarea/save_parts.php b/public/userarea/save_parts.php deleted file mode 100644 index 1ba83d6..0000000 --- a/public/userarea/save_parts.php +++ /dev/null @@ -1,78 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents('php://input'), true); - -$iddatadb = $data['iddatadb'] ?? null; -$parts = $data['parts'] ?? []; - -if (!$iddatadb || empty($parts)) { - echo json_encode(['success' => false, 'message' => 'Dati mancanti']); - exit; -} - -try { - $pdo->beginTransaction(); - $results = []; - - foreach ($parts as $part) { - $partId = $part['id'] ?? null; - $partNumber = $part['part_number'] ?? null; - $partDescription = $part['part_description'] ?? ''; - $mix = $part['mix'] ?? 'N'; - $idmatrice = $part['idmatrice'] ?? null; - $note = $part['note'] ?? null; - $dateexpiry = $part['dateexpiry'] ?? null; - - if ($partDescription || $note || $dateexpiry) { - if ($partId) { - // UPDATE se la parte esiste - $stmt = $pdo->prepare("UPDATE identification_parts - SET part_number = :part_number, - part_description = :part_description, - mix = :mix, - idmatrice = :idmatrice, - note = :note, - dateexpiry = :dateexpiry, - updated_at = NOW() - WHERE id = :id"); - $stmt->execute([ - ':id' => $partId, - ':part_number' => $partNumber, - ':part_description' => $partDescription, - ':mix' => $mix, - ':idmatrice' => $idmatrice, - ':note' => $note, - ':dateexpiry' => $dateexpiry, - ]); - $results[] = ['part_id' => $partId, 'part_number' => $partNumber, 'message' => 'Parte aggiornata con successo']; - } else { - // INSERT per nuova parte - $stmt = $pdo->prepare("INSERT INTO identification_parts - (iddatadb, part_number, part_description, mix, idmatrice, note, dateexpiry, created_at, updated_at) - VALUES (:iddatadb, :part_number, :part_description, :mix, :idmatrice, :note, :dateexpiry, NOW(), NOW())"); - $stmt->execute([ - ':iddatadb' => $iddatadb, - ':part_number' => $partNumber, - ':part_description' => $partDescription, - ':mix' => $mix, - ':idmatrice' => $idmatrice, - ':note' => $note, - ':dateexpiry' => $dateexpiry, - ]); - $newId = $pdo->lastInsertId(); - $results[] = ['part_id' => $newId, 'part_number' => $partNumber, 'message' => 'Parte salvata con successo']; - } - } - } - - $pdo->commit(); - echo json_encode(['success' => true, 'results' => $results]); -} catch (PDOException $e) { - $pdo->rollBack(); - echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio: ' . $e->getMessage()]); -} diff --git a/public/userarea/save_parts_photo_iddatadb.php b/public/userarea/save_parts_photo_iddatadb.php deleted file mode 100644 index afa69d3..0000000 --- a/public/userarea/save_parts_photo_iddatadb.php +++ /dev/null @@ -1,48 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents('php://input'), true); - -$iddatadb = $data['iddatadb'] ?? null; -$partIds = $data['partIds'] ?? []; -$photoList = $data['photoList'] ?? null; - -if ($iddatadb) { - if (count($partIds) != 0) { - $idList = array_values(array_map('intval', $partIds)); - $placeholders = []; - $parameters = [':iddatadb' => $iddatadb]; - - foreach ($idList as $index => $id) { - $paramName = ":id{$index}"; - $placeholders[] = $paramName; - $parameters[$paramName] = $id; - } - - $sql = 'UPDATE identification_parts SET iddatadb = :iddatadb WHERE id IN (' . implode(',', $placeholders) . ')'; - $stmt = $pdo->prepare($sql); - $stmt->execute($parameters); - } - - if (count($photoList) != 0) { - $placeholders = []; - $parameters = [':iddatadb' => $iddatadb]; - - foreach ($photoList as $index => $photo) { - $paramName = ":photo{$index}"; - $placeholders[] = $paramName; - $parameters[$paramName] = $photo; - } - - $stmt = $pdo->prepare('UPDATE datadb_photos SET iddatadb = :iddatadb WHERE file_path IN (' . implode(',', $placeholders) . ')'); - $stmt->execute($parameters); - } - - echo json_encode(['success' => true, 'message' => '']); -} else { - echo json_encode(['success' => false, 'message' => 'Dati mancanti']); -} diff --git a/public/userarea/save_parts_quotation.php b/public/userarea/save_parts_quotation.php deleted file mode 100644 index 2445f70..0000000 --- a/public/userarea/save_parts_quotation.php +++ /dev/null @@ -1,60 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents('php://input'), true); - -$idquotations = $data['idquotations'] ?? null; -$parts = $data['parts'] ?? []; - -if (!$idquotations || empty($parts)) { - echo json_encode(['success' => false, 'message' => 'Dati mancanti']); - exit; -} - -$part = $parts[0]; -$partId = $part['id'] ?? null; -$partNumber = $part['part_number'] ?? null; -$partDescription = $part['part_description'] ?? ''; -$mix = $part['mix'] ?? 'N'; - -if ($partDescription) { - try { - if ($partId) { - // UPDATE se esiste già la parte - $stmt = $pdo->prepare("UPDATE identification_parts - SET part_number = :part_number, - part_description = :part_description, - mix = :mix, - updated_at = NOW() - WHERE id = :id"); - $stmt->execute([ - ':id' => $partId, - ':part_number' => $partNumber, - ':part_description' => $partDescription, - ':mix' => $mix - ]); - echo json_encode(['success' => true, 'part_id' => $partId, 'part_number' => $partNumber, 'message' => 'Parte aggiornata con successo']); - } else { - // INSERT se è nuova - $stmt = $pdo->prepare("INSERT INTO identification_parts - (idquotations, part_number, part_description, mix, created_at, updated_at) - VALUES (:idquotations, :part_number, :part_description, :mix, NOW(), NOW())"); - $stmt->execute([ - ':idquotations' => $idquotations, - ':part_number' => $partNumber, - ':part_description' => $partDescription, - ':mix' => $mix - ]); - $newId = $pdo->lastInsertId(); - echo json_encode(['success' => true, 'part_id' => $newId, 'part_number' => $partNumber, 'message' => 'Parte salvata con successo']); - } - } catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio: ' . $e->getMessage()]); - } -} else { - echo json_encode(['success' => false, 'message' => 'Descrizione mancante']); -} diff --git a/public/userarea/schema_dettagli_response.json b/public/userarea/schema_dettagli_response.json deleted file mode 100644 index 9cd4dd4..0000000 --- a/public/userarea/schema_dettagli_response.json +++ /dev/null @@ -1 +0,0 @@ -{"@odata.context":"https:\/\/93.43.5.102\/limsapi\/api\/odata\/$metadata#SchemaCustomField(SchemiCustomFieldsDettagli(CustomField()))\/$entity","IdSchemaCustomFields":48,"Nome":"Standard Generico \/ Generic Standard","Descrizione":"Schema per tutti i campioni di qualsiasi matrice escluso cuoio\/pelle\r\n\r\n","SchemiCustomFieldsDettagli":[{"IdSchemaCustomFieldsDettaglio":585,"Ordine":1,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":183,"TitoloTraduzione":"Analisi Commissionate da: ","Titolo":"Analisi Commissionate da: ","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":true}},{"IdSchemaCustomFieldsDettaglio":586,"Ordine":2,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":184,"TitoloTraduzione":"Ordine d'Acquisto: ","Titolo":"Ordine d'Acquisto: ","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":true,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":471,"Ordine":3,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":148,"TitoloTraduzione":"Articolo: ","Titolo":"Articolo: ","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":true}},{"IdSchemaCustomFieldsDettaglio":472,"Ordine":4,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":149,"TitoloTraduzione":"Colore: ","Titolo":"Colore: ","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":473,"Ordine":5,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":150,"TitoloTraduzione":"Destinazione d'uso: ","Titolo":"Destinazione d'uso: ","Descrizione":null,"Tipo":"SceltaMultipla","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":true,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":486,"Ordine":6,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":156,"TitoloTraduzione":"Tipologia di Materiale:","Titolo":"Tipologia di Materiale:","Descrizione":null,"Tipo":"SceltaMultipla","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":483,"Ordine":8,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":161,"TitoloTraduzione":"Categoria:","Titolo":"Categoria:","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":true,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":759,"Ordine":10,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":162,"TitoloTraduzione":"Stagione:","Titolo":"Stagione:","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":479,"Ordine":11,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":166,"TitoloTraduzione":"Note:","Titolo":"Note:","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":633,"Ordine":12,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":193,"TitoloTraduzione":"DDT N. ","Titolo":"DDT N. ","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":true,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":1646,"Ordine":13,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":370,"TitoloTraduzione":"DDT del","Titolo":"DDT del","Descrizione":null,"Tipo":"Data","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":true,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":606,"Ordine":16,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":189,"TitoloTraduzione":"Tested Component:","Titolo":"Tested Component:","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":476,"Ordine":17,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":142,"TitoloTraduzione":"Fornitore:","Titolo":"Fornitore:","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":true,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":477,"Ordine":18,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":143,"TitoloTraduzione":"Destinatario:","Titolo":"Destinatario:","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":663,"Ordine":29,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":169,"TitoloTraduzione":"Restituzione Materiale Residuo:","Titolo":"Restituzione Materiale Residuo:","Descrizione":null,"Tipo":"SceltaMultipla","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":"","Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":664,"Ordine":30,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":170,"TitoloTraduzione":"Originali:","Titolo":"Originali:","Descrizione":null,"Tipo":"SceltaMultipla","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":"","Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":false}},{"IdSchemaCustomFieldsDettaglio":665,"Ordine":31,"ObbligatorioWeb":"Predefinito","RaggruppamentoWeb":null,"CustomField":{"IdCustomField":171,"TitoloTraduzione":"Corriere:","Titolo":"Corriere:","Descrizione":null,"Tipo":"SceltaMultipla","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":"","Elenco":false,"DefaultCurrDate":false,"ObbligatorioWeb":false}}]} \ No newline at end of file diff --git a/public/userarea/schemi_base_response.json b/public/userarea/schemi_base_response.json deleted file mode 100644 index 982b85f..0000000 --- a/public/userarea/schemi_base_response.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "@odata.context": "https:\/\/93.43.5.102\/limsapi\/api\/odata\/$metadata#SchemaCustomField", - "value": [ - { - "IdSchemaCustomFields": 41, - "Nome": "Labostudio", - "Descrizione": null - }, - { - "IdSchemaCustomFields": 42, - "Nome": "Schema 1", - "Descrizione": null - }, - { - "IdSchemaCustomFields": 43, - "Nome": "Schema1", - "Descrizione": null - }, - { - "IdSchemaCustomFields": 44, - "Nome": "Cuoio\/Pelle Standard \/ Leather", - "Descrizione": "Schema per tutti i campioni in cuoio\/pelle per i quali non \u00e8 specificato un destinatario.\r\n" - }, - { - "IdSchemaCustomFields": 45, - "Nome": "Borse", - "Descrizione": null - }, - { - "IdSchemaCustomFields": 46, - "Nome": "Borse Burberry", - "Descrizione": null - }, - { - "IdSchemaCustomFields": 47, - "Nome": "pelle calzatura", - "Descrizione": null - }, - { - "IdSchemaCustomFields": 48, - "Nome": "Standard Generico \/ Generic Standard", - "Descrizione": "Schema per tutti i campioni di qualsiasi matrice escluso cuoio\/pelle\r\n\r\n" - }, - { - "IdSchemaCustomFields": 49, - "Nome": "Accessori Metallici \/ Metallic Accessories", - "Descrizione": "Schema per tutti gli Accessori Metallici\r\n\r\n\r\n" - }, - { - "IdSchemaCustomFields": 50, - "Nome": "Tessile \/ Textiles", - "Descrizione": "Schema per tutti i Tessuti\r\n" - }, - { - "IdSchemaCustomFields": 82, - "Nome": "MONCLER Brand", - "Descrizione": "Da utilizzare solo per il Brand Diretto\r\nGR 19\/03\/2024" - } - ] -} \ No newline at end of file diff --git a/public/userarea/schemi_custom_fields_response.json b/public/userarea/schemi_custom_fields_response.json deleted file mode 100644 index eb7df7f..0000000 --- a/public/userarea/schemi_custom_fields_response.json +++ /dev/null @@ -1 +0,0 @@ -{"@odata.context":"https:\/\/93.43.5.102\/limsapi\/api\/odata\/$metadata#UnitaMisura","value":[{"IdUnitaMisura":563,"NomeUnitaMisura":null},{"IdUnitaMisura":564,"NomeUnitaMisura":null},{"IdUnitaMisura":567,"NomeUnitaMisura":null},{"IdUnitaMisura":565,"NomeUnitaMisura":null},{"IdUnitaMisura":566,"NomeUnitaMisura":null},{"IdUnitaMisura":568,"NomeUnitaMisura":null},{"IdUnitaMisura":569,"NomeUnitaMisura":null},{"IdUnitaMisura":570,"NomeUnitaMisura":null},{"IdUnitaMisura":571,"NomeUnitaMisura":null},{"IdUnitaMisura":572,"NomeUnitaMisura":null},{"IdUnitaMisura":573,"NomeUnitaMisura":null},{"IdUnitaMisura":574,"NomeUnitaMisura":null},{"IdUnitaMisura":575,"NomeUnitaMisura":null},{"IdUnitaMisura":576,"NomeUnitaMisura":null},{"IdUnitaMisura":577,"NomeUnitaMisura":null},{"IdUnitaMisura":579,"NomeUnitaMisura":null},{"IdUnitaMisura":580,"NomeUnitaMisura":null},{"IdUnitaMisura":581,"NomeUnitaMisura":null},{"IdUnitaMisura":582,"NomeUnitaMisura":null},{"IdUnitaMisura":583,"NomeUnitaMisura":null},{"IdUnitaMisura":584,"NomeUnitaMisura":null},{"IdUnitaMisura":585,"NomeUnitaMisura":null},{"IdUnitaMisura":586,"NomeUnitaMisura":null},{"IdUnitaMisura":587,"NomeUnitaMisura":null},{"IdUnitaMisura":588,"NomeUnitaMisura":null},{"IdUnitaMisura":592,"NomeUnitaMisura":null},{"IdUnitaMisura":593,"NomeUnitaMisura":null},{"IdUnitaMisura":595,"NomeUnitaMisura":null},{"IdUnitaMisura":597,"NomeUnitaMisura":null},{"IdUnitaMisura":598,"NomeUnitaMisura":null},{"IdUnitaMisura":599,"NomeUnitaMisura":null},{"IdUnitaMisura":600,"NomeUnitaMisura":null},{"IdUnitaMisura":601,"NomeUnitaMisura":null},{"IdUnitaMisura":604,"NomeUnitaMisura":null},{"IdUnitaMisura":607,"NomeUnitaMisura":null},{"IdUnitaMisura":608,"NomeUnitaMisura":null},{"IdUnitaMisura":609,"NomeUnitaMisura":null},{"IdUnitaMisura":610,"NomeUnitaMisura":null},{"IdUnitaMisura":611,"NomeUnitaMisura":null},{"IdUnitaMisura":616,"NomeUnitaMisura":null},{"IdUnitaMisura":617,"NomeUnitaMisura":null},{"IdUnitaMisura":621,"NomeUnitaMisura":null},{"IdUnitaMisura":622,"NomeUnitaMisura":null},{"IdUnitaMisura":623,"NomeUnitaMisura":null},{"IdUnitaMisura":624,"NomeUnitaMisura":null},{"IdUnitaMisura":625,"NomeUnitaMisura":null},{"IdUnitaMisura":626,"NomeUnitaMisura":null},{"IdUnitaMisura":627,"NomeUnitaMisura":null},{"IdUnitaMisura":629,"NomeUnitaMisura":null},{"IdUnitaMisura":630,"NomeUnitaMisura":null},{"IdUnitaMisura":631,"NomeUnitaMisura":null},{"IdUnitaMisura":632,"NomeUnitaMisura":null},{"IdUnitaMisura":633,"NomeUnitaMisura":null},{"IdUnitaMisura":636,"NomeUnitaMisura":null},{"IdUnitaMisura":637,"NomeUnitaMisura":null},{"IdUnitaMisura":638,"NomeUnitaMisura":null},{"IdUnitaMisura":639,"NomeUnitaMisura":null},{"IdUnitaMisura":640,"NomeUnitaMisura":null},{"IdUnitaMisura":641,"NomeUnitaMisura":null},{"IdUnitaMisura":645,"NomeUnitaMisura":null},{"IdUnitaMisura":647,"NomeUnitaMisura":null},{"IdUnitaMisura":651,"NomeUnitaMisura":null},{"IdUnitaMisura":655,"NomeUnitaMisura":null},{"IdUnitaMisura":656,"NomeUnitaMisura":null},{"IdUnitaMisura":658,"NomeUnitaMisura":null},{"IdUnitaMisura":659,"NomeUnitaMisura":null},{"IdUnitaMisura":661,"NomeUnitaMisura":null},{"IdUnitaMisura":662,"NomeUnitaMisura":null},{"IdUnitaMisura":664,"NomeUnitaMisura":null},{"IdUnitaMisura":667,"NomeUnitaMisura":null},{"IdUnitaMisura":671,"NomeUnitaMisura":null},{"IdUnitaMisura":673,"NomeUnitaMisura":null},{"IdUnitaMisura":675,"NomeUnitaMisura":null},{"IdUnitaMisura":676,"NomeUnitaMisura":null},{"IdUnitaMisura":677,"NomeUnitaMisura":null},{"IdUnitaMisura":678,"NomeUnitaMisura":null},{"IdUnitaMisura":679,"NomeUnitaMisura":null},{"IdUnitaMisura":680,"NomeUnitaMisura":null},{"IdUnitaMisura":681,"NomeUnitaMisura":null},{"IdUnitaMisura":682,"NomeUnitaMisura":null},{"IdUnitaMisura":683,"NomeUnitaMisura":null},{"IdUnitaMisura":684,"NomeUnitaMisura":null},{"IdUnitaMisura":685,"NomeUnitaMisura":null},{"IdUnitaMisura":686,"NomeUnitaMisura":null},{"IdUnitaMisura":687,"NomeUnitaMisura":null},{"IdUnitaMisura":688,"NomeUnitaMisura":null},{"IdUnitaMisura":690,"NomeUnitaMisura":null},{"IdUnitaMisura":695,"NomeUnitaMisura":null},{"IdUnitaMisura":696,"NomeUnitaMisura":null},{"IdUnitaMisura":697,"NomeUnitaMisura":null},{"IdUnitaMisura":698,"NomeUnitaMisura":null},{"IdUnitaMisura":699,"NomeUnitaMisura":null},{"IdUnitaMisura":700,"NomeUnitaMisura":null},{"IdUnitaMisura":703,"NomeUnitaMisura":null},{"IdUnitaMisura":704,"NomeUnitaMisura":null},{"IdUnitaMisura":705,"NomeUnitaMisura":null},{"IdUnitaMisura":706,"NomeUnitaMisura":null},{"IdUnitaMisura":707,"NomeUnitaMisura":null},{"IdUnitaMisura":709,"NomeUnitaMisura":null},{"IdUnitaMisura":712,"NomeUnitaMisura":null},{"IdUnitaMisura":713,"NomeUnitaMisura":null},{"IdUnitaMisura":714,"NomeUnitaMisura":null},{"IdUnitaMisura":716,"NomeUnitaMisura":null},{"IdUnitaMisura":720,"NomeUnitaMisura":null},{"IdUnitaMisura":721,"NomeUnitaMisura":null},{"IdUnitaMisura":722,"NomeUnitaMisura":null},{"IdUnitaMisura":578,"NomeUnitaMisura":null},{"IdUnitaMisura":620,"NomeUnitaMisura":null},{"IdUnitaMisura":628,"NomeUnitaMisura":null},{"IdUnitaMisura":644,"NomeUnitaMisura":null},{"IdUnitaMisura":646,"NomeUnitaMisura":null},{"IdUnitaMisura":648,"NomeUnitaMisura":null},{"IdUnitaMisura":649,"NomeUnitaMisura":null},{"IdUnitaMisura":652,"NomeUnitaMisura":null},{"IdUnitaMisura":657,"NomeUnitaMisura":null},{"IdUnitaMisura":663,"NomeUnitaMisura":null},{"IdUnitaMisura":701,"NomeUnitaMisura":null},{"IdUnitaMisura":702,"NomeUnitaMisura":null},{"IdUnitaMisura":708,"NomeUnitaMisura":null},{"IdUnitaMisura":710,"NomeUnitaMisura":null},{"IdUnitaMisura":715,"NomeUnitaMisura":null},{"IdUnitaMisura":723,"NomeUnitaMisura":null},{"IdUnitaMisura":724,"NomeUnitaMisura":null},{"IdUnitaMisura":725,"NomeUnitaMisura":null},{"IdUnitaMisura":726,"NomeUnitaMisura":null},{"IdUnitaMisura":727,"NomeUnitaMisura":null},{"IdUnitaMisura":728,"NomeUnitaMisura":null},{"IdUnitaMisura":729,"NomeUnitaMisura":null},{"IdUnitaMisura":730,"NomeUnitaMisura":null},{"IdUnitaMisura":731,"NomeUnitaMisura":null},{"IdUnitaMisura":741,"NomeUnitaMisura":null},{"IdUnitaMisura":742,"NomeUnitaMisura":null},{"IdUnitaMisura":743,"NomeUnitaMisura":null},{"IdUnitaMisura":744,"NomeUnitaMisura":null},{"IdUnitaMisura":745,"NomeUnitaMisura":null},{"IdUnitaMisura":747,"NomeUnitaMisura":null},{"IdUnitaMisura":748,"NomeUnitaMisura":null},{"IdUnitaMisura":749,"NomeUnitaMisura":null},{"IdUnitaMisura":750,"NomeUnitaMisura":null},{"IdUnitaMisura":751,"NomeUnitaMisura":null},{"IdUnitaMisura":752,"NomeUnitaMisura":null},{"IdUnitaMisura":753,"NomeUnitaMisura":null},{"IdUnitaMisura":754,"NomeUnitaMisura":null},{"IdUnitaMisura":755,"NomeUnitaMisura":null},{"IdUnitaMisura":756,"NomeUnitaMisura":null},{"IdUnitaMisura":757,"NomeUnitaMisura":null},{"IdUnitaMisura":758,"NomeUnitaMisura":null},{"IdUnitaMisura":759,"NomeUnitaMisura":null},{"IdUnitaMisura":760,"NomeUnitaMisura":null},{"IdUnitaMisura":761,"NomeUnitaMisura":null},{"IdUnitaMisura":762,"NomeUnitaMisura":null},{"IdUnitaMisura":763,"NomeUnitaMisura":null},{"IdUnitaMisura":764,"NomeUnitaMisura":null},{"IdUnitaMisura":765,"NomeUnitaMisura":null},{"IdUnitaMisura":766,"NomeUnitaMisura":null},{"IdUnitaMisura":767,"NomeUnitaMisura":null},{"IdUnitaMisura":768,"NomeUnitaMisura":null},{"IdUnitaMisura":769,"NomeUnitaMisura":null},{"IdUnitaMisura":770,"NomeUnitaMisura":null},{"IdUnitaMisura":771,"NomeUnitaMisura":null},{"IdUnitaMisura":772,"NomeUnitaMisura":null},{"IdUnitaMisura":773,"NomeUnitaMisura":null},{"IdUnitaMisura":774,"NomeUnitaMisura":null},{"IdUnitaMisura":775,"NomeUnitaMisura":null},{"IdUnitaMisura":777,"NomeUnitaMisura":null},{"IdUnitaMisura":778,"NomeUnitaMisura":null},{"IdUnitaMisura":779,"NomeUnitaMisura":null},{"IdUnitaMisura":780,"NomeUnitaMisura":null},{"IdUnitaMisura":781,"NomeUnitaMisura":null},{"IdUnitaMisura":782,"NomeUnitaMisura":null},{"IdUnitaMisura":783,"NomeUnitaMisura":null},{"IdUnitaMisura":785,"NomeUnitaMisura":null},{"IdUnitaMisura":787,"NomeUnitaMisura":null},{"IdUnitaMisura":788,"NomeUnitaMisura":null},{"IdUnitaMisura":791,"NomeUnitaMisura":null},{"IdUnitaMisura":792,"NomeUnitaMisura":null},{"IdUnitaMisura":794,"NomeUnitaMisura":null},{"IdUnitaMisura":795,"NomeUnitaMisura":null},{"IdUnitaMisura":796,"NomeUnitaMisura":null},{"IdUnitaMisura":797,"NomeUnitaMisura":null},{"IdUnitaMisura":798,"NomeUnitaMisura":null},{"IdUnitaMisura":799,"NomeUnitaMisura":null},{"IdUnitaMisura":800,"NomeUnitaMisura":null},{"IdUnitaMisura":801,"NomeUnitaMisura":null},{"IdUnitaMisura":805,"NomeUnitaMisura":null},{"IdUnitaMisura":806,"NomeUnitaMisura":null},{"IdUnitaMisura":807,"NomeUnitaMisura":null},{"IdUnitaMisura":810,"NomeUnitaMisura":null},{"IdUnitaMisura":811,"NomeUnitaMisura":null},{"IdUnitaMisura":812,"NomeUnitaMisura":null},{"IdUnitaMisura":813,"NomeUnitaMisura":null},{"IdUnitaMisura":814,"NomeUnitaMisura":null},{"IdUnitaMisura":591,"NomeUnitaMisura":null},{"IdUnitaMisura":594,"NomeUnitaMisura":null},{"IdUnitaMisura":596,"NomeUnitaMisura":null},{"IdUnitaMisura":602,"NomeUnitaMisura":null},{"IdUnitaMisura":603,"NomeUnitaMisura":null},{"IdUnitaMisura":606,"NomeUnitaMisura":null},{"IdUnitaMisura":634,"NomeUnitaMisura":null},{"IdUnitaMisura":643,"NomeUnitaMisura":null},{"IdUnitaMisura":650,"NomeUnitaMisura":null},{"IdUnitaMisura":654,"NomeUnitaMisura":null},{"IdUnitaMisura":689,"NomeUnitaMisura":null},{"IdUnitaMisura":746,"NomeUnitaMisura":null},{"IdUnitaMisura":784,"NomeUnitaMisura":null},{"IdUnitaMisura":793,"NomeUnitaMisura":null},{"IdUnitaMisura":815,"NomeUnitaMisura":null},{"IdUnitaMisura":590,"NomeUnitaMisura":null},{"IdUnitaMisura":605,"NomeUnitaMisura":null},{"IdUnitaMisura":665,"NomeUnitaMisura":null},{"IdUnitaMisura":786,"NomeUnitaMisura":null},{"IdUnitaMisura":612,"NomeUnitaMisura":null},{"IdUnitaMisura":614,"NomeUnitaMisura":null},{"IdUnitaMisura":635,"NomeUnitaMisura":null},{"IdUnitaMisura":666,"NomeUnitaMisura":null},{"IdUnitaMisura":719,"NomeUnitaMisura":null},{"IdUnitaMisura":613,"NomeUnitaMisura":null},{"IdUnitaMisura":642,"NomeUnitaMisura":null},{"IdUnitaMisura":660,"NomeUnitaMisura":null},{"IdUnitaMisura":668,"NomeUnitaMisura":null},{"IdUnitaMisura":669,"NomeUnitaMisura":null},{"IdUnitaMisura":718,"NomeUnitaMisura":null},{"IdUnitaMisura":776,"NomeUnitaMisura":null},{"IdUnitaMisura":789,"NomeUnitaMisura":null},{"IdUnitaMisura":790,"NomeUnitaMisura":null},{"IdUnitaMisura":653,"NomeUnitaMisura":null},{"IdUnitaMisura":717,"NomeUnitaMisura":null}]} \ No newline at end of file diff --git a/public/userarea/schemi_liberi.html b/public/userarea/schemi_liberi.html deleted file mode 100644 index 576e502..0000000 --- a/public/userarea/schemi_liberi.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - Schemi Liberi - - - -

                Elenco Schemi Liberi

                -
                - - - - diff --git a/public/userarea/schemi_liberi.php b/public/userarea/schemi_liberi.php deleted file mode 100644 index abd7da3..0000000 --- a/public/userarea/schemi_liberi.php +++ /dev/null @@ -1,123 +0,0 @@ - 'WebApiUser', - 'Password' => 'webapiuser01' -]; - -// Autenticazione → ottieni token -$ch = curl_init("$base_url/api/authentication/authenticate"); -curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); -curl_setopt($ch, CURLOPT_POST, true); -curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($credentials)); -curl_setopt($ch, CURLOPT_HTTPHEADER, [ - 'Content-Type: application/json', - 'Accept: application/json' -]); -curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); -curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); -curl_setopt($ch, CURLOPT_VERBOSE, true); -$log = fopen('curl_auth_debug.log', 'w'); -curl_setopt($ch, CURLOPT_STDERR, $log); - -$response = curl_exec($ch); -$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); -$curl_error = curl_error($ch); -fclose($log); -curl_close($ch); - -// Verifica la risposta -if ($response === false || $http_code != 200) { - http_response_code($http_code ? $http_code : 500); - echo json_encode([ - 'error' => 'Errore nella richiesta di autenticazione', - 'http_code' => $http_code, - 'curl_error' => $curl_error, - 'raw_response' => substr($response, 0, 1000) - ]); - exit; -} - -// Decodifica la risposta JSON -$token_data = json_decode($response, true); - -// Gestisci sia il caso in cui la risposta è una stringa (token diretto) sia un oggetto con chiave 'token' -$token = null; -if (is_array($token_data) && isset($token_data['token'])) { - $token = $token_data['token']; -} elseif (is_string($token_data) && !empty($token_data)) { - $token = trim($token_data, '"'); -} elseif (is_string($response) && !empty($response)) { - $token = trim($response, '"'); -} - -if (empty($token)) { - http_response_code(401); - echo json_encode([ - 'error' => 'Token non ricevuto', - 'http_code' => $http_code, - 'curl_error' => $curl_error, - 'raw_response' => substr($response, 0, 1000) - ]); - exit; -} - -// Chiamata GET per recuperare gli schemi con IdCliente = 0 -$cliente_id = 0; // Definiamo l'ID cliente -$endpoint = "$base_url/api/odata/Cliente($cliente_id)?\$expand=SchemiAbilitati"; // Nota: usiamo \$ per escape in PHP -$ch = curl_init($endpoint); -curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); -curl_setopt($ch, CURLOPT_HTTPHEADER, [ - "Authorization: Bearer $token", - "Accept: application/json" -]); -curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); -curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); -curl_setopt($ch, CURLOPT_VERBOSE, true); -$log = fopen('curl_schemi_liberi_debug.log', 'w'); -curl_setopt($ch, CURLOPT_STDERR, $log); - -$schemi_response = curl_exec($ch); -$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); -$curl_error = curl_error($ch); -fclose($log); -curl_close($ch); - -// Gestisci la risposta -if ($schemi_response === false) { - http_response_code(500); - echo json_encode([ - 'error' => 'Errore nella richiesta cURL', - 'curl_error' => $curl_error - ]); - exit; -} - -if ($http_code === 200) { - $schemi_data = json_decode($schemi_response, true); - if (json_last_error() === JSON_ERROR_NONE) { - echo json_encode($schemi_data); - } else { - http_response_code(500); - echo json_encode([ - 'error' => 'Risposta non JSON valida', - 'http_code' => $http_code, - 'response' => substr($schemi_response, 0, 1000) - ]); - } -} else { - $schemi_data = json_decode($schemi_response, true); - if (json_last_error() === JSON_ERROR_NONE) { - echo json_encode($schemi_data); - } else { - http_response_code($http_code); - echo json_encode([ - 'error' => 'Errore nel recupero schemi', - 'http_code' => $http_code, - 'curl_error' => $curl_error, - 'response' => substr($schemi_response, 0, 1000) - ]); - } -} diff --git a/public/userarea/schemi_response.json b/public/userarea/schemi_response.json deleted file mode 100644 index d687e89..0000000 --- a/public/userarea/schemi_response.json +++ /dev/null @@ -1 +0,0 @@ -{"@odata.context":"https:\/\/93.43.5.102\/limsapi\/api\/odata\/$metadata#SchemaCustomField","value":[{"IdSchemaCustomFields":41,"Nome":"Labostudio","Descrizione":null},{"IdSchemaCustomFields":42,"Nome":"Schema 1","Descrizione":null},{"IdSchemaCustomFields":43,"Nome":"Schema1","Descrizione":null},{"IdSchemaCustomFields":44,"Nome":"Cuoio\/Pelle Standard \/ Leather","Descrizione":"Schema per tutti i campioni in cuoio\/pelle per i quali non \u00e8 specificato un destinatario.\r\n"},{"IdSchemaCustomFields":45,"Nome":"Borse","Descrizione":null},{"IdSchemaCustomFields":46,"Nome":"Borse Burberry","Descrizione":null},{"IdSchemaCustomFields":47,"Nome":"pelle calzatura","Descrizione":null},{"IdSchemaCustomFields":48,"Nome":"Standard Generico \/ Generic Standard","Descrizione":"Schema per tutti i campioni di qualsiasi matrice escluso cuoio\/pelle\r\n\r\n"},{"IdSchemaCustomFields":49,"Nome":"Accessori Metallici \/ Metallic Accessories","Descrizione":"Schema per tutti gli Accessori Metallici\r\n\r\n\r\n"},{"IdSchemaCustomFields":50,"Nome":"Tessile \/ Textiles","Descrizione":"Schema per tutti i Tessuti\r\n"},{"IdSchemaCustomFields":183,"Nome":"TWINSET","Descrizione":"Schema da usare per Twinset - come da mail di EP del 20\/05\/2025\r\n\r\n"},{"IdSchemaCustomFields":186,"Nome":"TWINSET","Descrizione":"Schema per tutti i campioni di qualsiasi matrice escluso cuoio\/pelle\r\n\r\n"}]} \ No newline at end of file diff --git a/public/userarea/templates_dashboard.php b/public/userarea/templates_dashboard.php deleted file mode 100644 index 635bafc..0000000 --- a/public/userarea/templates_dashboard.php +++ /dev/null @@ -1,276 +0,0 @@ - - - - - - - - - - - - TRF-Project - Template Dashboard - - - - - - -
                - - - - - - - -
                -
                - - -
                -
                -
                -
                XLS Templates Dashboard
                - - New Template - -
                -
                - -
                -
                - - - - - - - - - - - - - - - - - -
                IDClient NameButton LabelStatus
                -
                -
                -
                - -
                -
                - - -
                - - - - - -
                - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/tracking.js b/public/userarea/tracking.js deleted file mode 100644 index 00beedb..0000000 --- a/public/userarea/tracking.js +++ /dev/null @@ -1,55 +0,0 @@ -document.addEventListener("DOMContentLoaded", function () { - // Gestione del tracking - document.querySelectorAll(".go-btn").forEach((button) => { - button.addEventListener("click", async function () { - const rowIndex = this.getAttribute("data-row"); - const awbInput = document.querySelector( - `input[name="rows[${rowIndex}][awb_number]"]`, - ); - const carrierSelect = document.querySelector( - `select[name="rows[${rowIndex}][carrier]"]`, - ); - const trackingResult = document.querySelector( - `.tracking-info[data-row="${rowIndex}"] .tracking-result`, - ); - const trackingHidden = document.querySelector( - `input[name="rows[${rowIndex}][tracking_info]"]`, - ); - const trackingNumber = awbInput.value.trim(); - const carrierCode = carrierSelect.value; - - if (!trackingNumber) { - alert("Inserisci un numero AWB valido!"); - return; - } - - try { - trackingResult.textContent = "Caricamento..."; - this.disabled = true; - const formData = new FormData(); - formData.append("tracking_number", trackingNumber); - formData.append("courier_code", carrierCode); - const response = await fetch("fetch_tracking_info.php", { - method: "POST", - body: formData, - }); - const result = await response.json(); - - if (!result.success) throw new Error(result.message); - const trackingText = `Date: ${result.deliveryDate}, Signed by: ${result.signedBy}, Courier: ${result.carrierName}`; - trackingResult.textContent = trackingText; - trackingHidden.value = JSON.stringify({ - deliveryDate: result.deliveryDate, - signedBy: result.signedBy, - carrierName: result.carrierName, - }); - } catch (error) { - console.error("Errore:", error); - trackingResult.textContent = "Errore: " + error.message; - trackingHidden.value = ""; - } finally { - this.disabled = false; - } - }); - }); -}); diff --git a/public/userarea/tracking_functions.php b/public/userarea/tracking_functions.php deleted file mode 100644 index e69de29..0000000 diff --git a/public/userarea/update-profile.php b/public/userarea/update-profile.php deleted file mode 100644 index d4bc5a7..0000000 --- a/public/userarea/update-profile.php +++ /dev/null @@ -1,52 +0,0 @@ -getConnection(); - - // Gestione avatar - $avatar = $user->present()->avatar; - if (isset($_FILES['avatar']) && $_FILES['avatar']['error'] === UPLOAD_ERR_OK) { - $avatar = time() . '_' . basename($_FILES['avatar']['name']); - $uploadDir = __DIR__ . '/../../public/upload/users/'; - if (!is_dir($uploadDir)) { - mkdir($uploadDir, 0755, true); - } - move_uploaded_file($_FILES['avatar']['tmp_name'], $uploadDir . $avatar); - } - - // Aggiornamento dati - $sql = "UPDATE auth_users SET first_name = ?, last_name = ?, email = ?, avatar = ? WHERE id = ?"; - $stmt = $db->prepare($sql); - $stmt->execute([$first_name, $last_name, $email, $avatar, $id]); - - // Aggiornamento password se fornita - if ($password) { - $hashedPassword = password_hash($password, PASSWORD_BCRYPT); - $sql = "UPDATE auth_users SET password = ? WHERE id = ?"; - $stmt = $db->prepare($sql); - $stmt->execute([$hashedPassword, $id]); - } - - // Aggiorna la sessione con i nuovi dati - $_SESSION["nameuser"] = $first_name; - $_SESSION["surnameuser"] = $last_name; - $_SESSION["emailuser"] = $email; - $_SESSION["photouser"] = $avatar; - - header('Location: user-profile.php'); - exit; -} diff --git a/public/userarea/update_main_field.php b/public/userarea/update_main_field.php deleted file mode 100644 index 6500480..0000000 --- a/public/userarea/update_main_field.php +++ /dev/null @@ -1,41 +0,0 @@ - false, 'message' => 'Invalid IDs']); - exit; -} - -$db = DBHandlerSelect::getInstance(); -$pdo = $db->getConnection(); - -try { - $pdo->beginTransaction(); - - if ($value === 1) { - // Setta tutti main_field a 0 per questo template - $stmt = $pdo->prepare("UPDATE template_mapping SET main_field = 0 WHERE template_id = ?"); - $stmt->execute([$template_id]); - } - - // Setta il valore per questo mapping - $stmt = $pdo->prepare("UPDATE template_mapping SET main_field = ? WHERE id = ? AND template_id = ?"); - $stmt->execute([$value, $mapping_id, $template_id]); - - $pdo->commit(); - echo json_encode(['success' => true]); -} catch (Exception $e) { - $pdo->rollBack(); - echo json_encode(['success' => false, 'message' => $e->getMessage()]); -} diff --git a/public/userarea/update_prices_chatpdf.php b/public/userarea/update_prices_chatpdf.php new file mode 100644 index 0000000..9997027 --- /dev/null +++ b/public/userarea/update_prices_chatpdf.php @@ -0,0 +1,129 @@ +getConnection(); + + $rows = json_decode($_POST['rows'] ?? '[]', true); + $idclient = intval($_POST['idclient'] ?? 0); + + if (!$idclient) { + throw new Exception('Missing idclient.'); + } + if (empty($rows) || !is_array($rows)) { + throw new Exception('No rows provided.'); + } + + // Recupera il SOURCE_ID del listino + $stmt = $pdo->prepare(" + SELECT source_id + FROM client_files + WHERE idclient = :idclient + AND file_type = 'pricelist' + AND source_id IS NOT NULL + ORDER BY upload_date DESC + LIMIT 1 + "); + $stmt->execute([':idclient' => $idclient]); + $sourceId = $stmt->fetchColumn(); + + if (!$sourceId) { + throw new Exception('No valid pricelist (source_id) found for this client.'); + } + + // Helper format codice + $formatRef = function (string $modCode): ?string { + $code = preg_replace('/\s+/', '', strtoupper($modCode)); + if (strlen($code) < 12) return null; + $core = substr($code, 3, -2); + if (strlen($core) < 7) return null; + return substr($core, 0, 3) . ' ' . substr($core, 3, 2) . ' ' . substr($core, 5, 2); + }; + + // Helper estrazione prezzo + $extractPrice = function (string $text): ?float { + if (preg_match('/(\d{1,6}[.,]\d{2})/', $text, $m)) { + $num = str_replace(',', '.', $m[1]); + return floatval($num); + } + return null; + }; + + $chatpdf = new ChatPDFHelper(); + $updated = 0; + $results = []; + + $pdo->beginTransaction(); + + foreach ($rows as $r) { + $modCode = $r['mod_code'] ?? ''; + $rowId = $r['id'] ?? 0; + + if (!$modCode) { + $results[] = ['id' => $rowId, 'mod_code' => $modCode, 'status' => 'skip']; + continue; + } + + $formattedRef = $formatRef($modCode); + if (!$formattedRef) { + $results[] = ['id' => $rowId, 'mod_code' => $modCode, 'status' => 'invalid_format']; + continue; + } + + $question = "In this price list, find the price in euros for the code reference: {$formattedRef}. Return only the number (e.g. 123,45)."; + $answer = $chatpdf->askPdf($sourceId, $question); + + $price = $extractPrice($answer ?? ''); + if ($price) { + $stmtU = $pdo->prepare(" + UPDATE importdb + SET price = :price, updated_on = NOW() + WHERE mod_code = :code AND idclient = :idclient + "); + $stmtU->execute([ + ':price' => $price, + ':code' => $modCode, + ':idclient' => $idclient + ]); + + if ($stmtU->rowCount() > 0) { + $updated++; + $results[] = [ + 'id' => $rowId, + 'mod_code' => $modCode, + 'status' => 'updated', + 'price' => $price + ]; + } + } else { + $results[] = [ + 'id' => $rowId, + 'mod_code' => $modCode, + 'status' => 'notfound', + 'answer' => $answer + ]; + } + } + + $pdo->commit(); + ob_clean(); + echo json_encode(['status' => 'ok', 'updated' => $updated, 'details' => $results], JSON_UNESCAPED_UNICODE); +} catch (Exception $e) { + if (isset($pdo) && $pdo->inTransaction()) { + $pdo->rollBack(); + } + ob_clean(); + echo json_encode(['status' => 'error', 'message' => $e->getMessage()], JSON_UNESCAPED_UNICODE); +} +exit; diff --git a/public/userarea/update_schemajson.php b/public/userarea/update_schemajson.php deleted file mode 100644 index b261afe..0000000 --- a/public/userarea/update_schemajson.php +++ /dev/null @@ -1,120 +0,0 @@ - false, "message" => ""]; - -try { - if ($_SERVER["REQUEST_METHOD"] !== "POST") { - throw new Exception("Invalid request method."); - } - - // Recupera i dati dal body JSON - $input = json_decode(file_get_contents('php://input'), true); - $template_id = isset($input['template_id']) ? intval($input['template_id']) : null; - $schemajson = isset($input['schemajson']) ? trim($input['schemajson']) : ''; - - // Controllo sui campi obbligatori - if (empty($template_id) || empty($schemajson)) { - throw new Exception("All fields marked with * are required, including schemajson."); - } - - // Validazione del JSON - $decoded_json = json_decode($schemajson, true); - if (json_last_error() !== JSON_ERROR_NONE) { - throw new Exception("Invalid JSON format for schemajson."); - } - - // Connessione al database - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - // Recupera il target_table e verifica l'esistenza del template - $stmt = $pdo->prepare("SELECT target_table FROM excel_templates WHERE id = ?"); - $stmt->execute([$template_id]); - $template = $stmt->fetch(PDO::FETCH_ASSOC); - if (!$template) { - throw new Exception("Template not found."); - } - $target_table = $template['target_table']; - - // Inizia una transazione - $pdo->beginTransaction(); - - // Aggiorna il schemajson in excel_templates - $stmt = $pdo->prepare("UPDATE excel_templates - SET schemajson = ?, updated_at = NOW() - WHERE id = ?"); - $stmt->execute([$schemajson, $template_id]); - - // Estrai i campi dallo schema - $schema_id = $decoded_json['IdSchemaCustomFields'] ?? null; - $schema_fields = $decoded_json['SchemiCustomFieldsDettagli'] ?? []; - if (empty($schema_id)) { - throw new Exception("Schema ID not found in schemajson."); - } - if (empty($schema_fields)) { - throw new Exception("No fields found in schema."); - } - - // Prepara la query per l'inserimento condizionato in template_mapping - $insert_stmt = $pdo->prepare(" - INSERT INTO template_mapping ( - template_id, schema_id, field_id, data_type, is_required, default_value, - has_list, length, decimals, min_value, max_value, default_curr_date, - tablename, field_label - ) - SELECT :template_id, :schema_id, :field_id, :data_type, :is_required, :default_value, - :has_list, :length, :decimals, :min_value, :max_value, :default_curr_date, - :tablename, :field_label - WHERE NOT EXISTS ( - SELECT 1 FROM template_mapping - WHERE template_id = :template_id_check AND field_id = :field_id_check - ) - "); - - // Itera sui campi dello schema e inserisci quelli mancanti - foreach ($schema_fields as $field) { - $custom_field = $field['CustomField'] ?? []; - if (empty($custom_field['IdCustomField'])) { - continue; // Salta se manca l'ID del campo - } - - $insert_stmt->execute([ - ':template_id' => $template_id, - ':schema_id' => $schema_id, - ':field_id' => $custom_field['IdCustomField'], - ':data_type' => $custom_field['Tipo'] ?? 'Testo', - ':is_required' => $custom_field['ObbligatorioWeb'] ? 1 : 0, - ':default_value' => $custom_field['ValoreDefault'] ?? null, - ':has_list' => $custom_field['Elenco'] ? 1 : 0, - ':length' => $custom_field['Lunghezza'] ?? 0, - ':decimals' => $custom_field['Decimali'] ?? 0, - ':min_value' => $custom_field['Minimo'] ?? null, - ':max_value' => $custom_field['Massimo'] ?? null, - ':default_curr_date' => $custom_field['DefaultCurrDate'] ? 1 : 0, - ':tablename' => $target_table, - ':field_label' => $custom_field['TitoloTraduzione'] ?? '', - ':template_id_check' => $template_id, - ':field_id_check' => $custom_field['IdCustomField'] - ]); - } - - // Commit della transazione - $pdo->commit(); - - $response["success"] = true; - $response["message"] = "Schema JSON updated and template mappings created successfully!"; -} catch (Exception $e) { - if (isset($pdo) && $pdo->inTransaction()) { - $pdo->rollback(); - } - $response["message"] = $e->getMessage(); -} - -// Restituisce un JSON per il fetch -echo json_encode($response); diff --git a/public/userarea/update_template_status.php b/public/userarea/update_template_status.php deleted file mode 100644 index 1f31665..0000000 --- a/public/userarea/update_template_status.php +++ /dev/null @@ -1,30 +0,0 @@ - false, "message" => ""]; - -try { - if ($_SERVER["REQUEST_METHOD"] !== "POST") { - throw new Exception("Invalid request."); - } - - $id = intval($_POST['id']); - $status = ($_POST['status'] === "active") ? "active" : "inactive"; - - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - $stmt = $pdo->prepare("UPDATE excel_templates SET status = ?, updated_at = NOW() WHERE id = ?"); - $stmt->execute([$status, $id]); - - if ($stmt->rowCount() > 0) { - $response["success"] = true; - } else { - throw new Exception("Update failed."); - } -} catch (Exception $e) { - $response["message"] = $e->getMessage(); -} - -echo json_encode($response); diff --git a/public/userarea/update_visible_import.php b/public/userarea/update_visible_import.php deleted file mode 100644 index 75651ad..0000000 --- a/public/userarea/update_visible_import.php +++ /dev/null @@ -1,26 +0,0 @@ - false, 'message' => 'Invalid input']); - exit; -} - -$db = DBHandlerSelect::getInstance(); -$pdo = $db->getConnection(); - -$stmt = $pdo->prepare("UPDATE template_mapping SET is_visible_import = ? WHERE id = ? AND template_id = ?"); -$result = $stmt->execute([$value, $mapping_id, $template_id]); - -if ($result) { - echo json_encode(['success' => true]); -} else { - echo json_encode(['success' => false, 'message' => 'Failed to update is_visible_import']); -} diff --git a/public/userarea/update_xls_headers.php b/public/userarea/update_xls_headers.php deleted file mode 100644 index 96e043a..0000000 --- a/public/userarea/update_xls_headers.php +++ /dev/null @@ -1,35 +0,0 @@ -getConnection(); - -$data = json_decode(file_get_contents("php://input"), true); - -if (!$data || !isset($data['template_id'], $data['xls_headers'])) { - echo json_encode(["success" => false, "message" => "Invalid or missing data"]); - exit; -} - -$templateId = $data['template_id']; -$xlsHeaders = $data['xls_headers']; - -try { - $stmt = $pdo->prepare("UPDATE excel_templates SET xls_headers = ? WHERE id = ?"); - $result = $stmt->execute([$xlsHeaders, $templateId]); - - if (!$result) { - echo json_encode(["success" => false, "message" => "Database update failed"]); - exit; - } - - echo json_encode(["success" => true, "message" => "XLS headers saved successfully"]); -} catch (Exception $e) { - echo json_encode(["success" => false, "message" => "Error: " . $e->getMessage()]); -} -exit; diff --git a/public/userarea/upload_photo.php b/public/userarea/upload_photo.php deleted file mode 100644 index 9db0284..0000000 --- a/public/userarea/upload_photo.php +++ /dev/null @@ -1,150 +0,0 @@ - false, 'message' => 'Richiesta non valida']); - exit; -} - -$iddatadb = isset($_POST['iddatadb']) ? intval($_POST['iddatadb']) : null; -$idquotations = isset($_POST['idquotations']) ? intval($_POST['idquotations']) : null; - -if ($iddatadb && $idquotations) { - echo json_encode(['success' => false, 'message' => 'Non è possibile specificare sia iddatadb che idquotations']); - exit; -} - -if (!$iddatadb && !$idquotations) { - echo json_encode(['success' => false, 'message' => 'ID TRF o ID quotations mancante']); - exit; -} - -// Verifica che l'utente loggato esista in auth_users -$db = DBHandlerSelect::getInstance(); -$pdo = $db->getConnection(); - -$stmt = $pdo->prepare("SELECT id FROM auth_users WHERE id = ?"); -$stmt->execute([$iduserlogin]); -$userExists = $stmt->fetch(PDO::FETCH_ASSOC); - -if (!$userExists) { - echo json_encode(['success' => false, 'message' => 'Utente non valido']); - exit; -} - -// Verifica l'esistenza dell'ID nella tabella corrispondente -try { - if ($iddatadb) { - $stmt = $pdo->prepare("SELECT iddatadb FROM datadb WHERE iddatadb = ?"); - $stmt->execute([$iddatadb]); - if (!$stmt->fetch()) { - echo json_encode(['success' => false, 'message' => 'iddatadb non valido']); - exit; - } - } else { - $stmt = $pdo->prepare("SELECT id FROM quotations WHERE id = ?"); - $stmt->execute([$idquotations]); - if (!$stmt->fetch()) { - echo json_encode(['success' => false, 'message' => 'idquotations non valido']); - exit; - } - } -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore nella validazione: ' . $e->getMessage()]); - exit; -} - -// Usa un percorso assoluto per la cartella photostrf -$uploadDir = realpath(__DIR__ . '/../photostrf') . '/'; -if (!is_dir($uploadDir)) { - if (!mkdir($uploadDir, 0755, true)) { - echo json_encode(['success' => false, 'message' => 'Impossibile creare la cartella photostrf']); - exit; - } -} - -// Verifica i permessi della cartella -if (!is_writable($uploadDir)) { - echo json_encode(['success' => false, 'message' => 'La cartella photostrf non è scrivibile']); - exit; -} - -// Verifica che il file sia un'immagine (inclusi HEIC/HEIF) -$photo = $_FILES['photo']; -$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/heic', 'image/heif']; -if (!in_array($photo['type'], $allowedTypes)) { - echo json_encode(['success' => false, 'message' => 'Il file deve essere un\'immagine (JPEG, PNG, GIF, HEIC)']); - exit; -} - -// Verifica che il file temporaneo esista -if (!file_exists($photo['tmp_name']) || !is_uploaded_file($photo['tmp_name'])) { - echo json_encode(['success' => false, 'message' => 'File temporaneo non valido']); - exit; -} - -// Rinomina il file: id-timestamp-nomeoriginale.estensione -$timestamp = date('YmdHis'); -$originalName = pathinfo($photo['name'], PATHINFO_FILENAME); -$extension = strtolower(pathinfo($photo['name'], PATHINFO_EXTENSION)); -$id = $iddatadb ?: $idquotations; - -// Se il file è HEIC/HEIF, convertilo in JPEG -if (in_array($photo['type'], ['image/heic', 'image/heif'])) { - // Verifica che la libreria GD sia disponibile - if (!extension_loaded('gd')) { - echo json_encode(['success' => false, 'message' => 'La libreria GD non è disponibile per convertire il file HEIC']); - exit; - } - - // Carica il file HEIC - $image = imagecreatefromstring(file_get_contents($photo['tmp_name'])); - if ($image === false) { - echo json_encode(['success' => false, 'message' => 'Impossibile caricare il file HEIC']); - exit; - } - - // Crea un nuovo nome per il file JPEG - $newFileName = "{$id}-{$timestamp}-{$originalName}.jpg"; - $destination = $uploadDir . $newFileName; - - // Salva l'immagine come JPEG - if (!imagejpeg($image, $destination, 90)) { - imagedestroy($image); - echo json_encode(['success' => false, 'message' => 'Errore durante la conversione del file HEIC in JPEG']); - exit; - } - - // Libera la memoria - imagedestroy($image); -} else { - // Per i formati non HEIC, usa il nome e l'estensione originali - $newFileName = "{$id}-{$timestamp}-{$originalName}.{$extension}"; - $destination = $uploadDir . $newFileName; - - // Salva il file - if (!move_uploaded_file($photo['tmp_name'], $destination)) { - $error = error_get_last(); - echo json_encode(['success' => false, 'message' => 'Errore durante il caricamento del file: ' . (isset($error['message']) ? $error['message'] : 'Sconosciuto')]); - exit; - } -} - -// Debug: verifica i percorsi -error_log("Upload directory: $uploadDir"); -error_log("Destination: $destination"); -error_log("Temp file: " . $photo['tmp_name']); - -// Salva il riferimento nel database -try { - $stmt = $pdo->prepare("INSERT INTO datadb_photos (iddatadb, idquotations, file_path, file_name, uploaded_by) VALUES (?, ?, ?, ?, ?)"); - $stmt->execute([$iddatadb, $idquotations, $newFileName, $newFileName, $iduserlogin]); -} catch (PDOException $e) { - echo json_encode(['success' => false, 'message' => 'Errore durante il salvataggio nel database: ' . $e->getMessage()]); - exit; -} - -echo json_encode(['success' => true, 'message' => 'Foto caricata con successo']); diff --git a/public/userarea/upload_photos_mobile.php b/public/userarea/upload_photos_mobile.php deleted file mode 100644 index b2ebe08..0000000 --- a/public/userarea/upload_photos_mobile.php +++ /dev/null @@ -1,286 +0,0 @@ -getConnection(); - -// Verifica che almeno uno degli ID sia passato -$iddatadb = isset($_GET['iddatadb']) && !empty($_GET['iddatadb']) ? intval($_GET['iddatadb']) : null; -$idquotations = isset($_GET['idquotations']) && !empty($_GET['idquotations']) ? intval($_GET['idquotations']) : null; - -if (!$iddatadb && !$idquotations) { - die('ID riga o ID quotations non fornito'); -} - -if ($iddatadb && $idquotations) { - die('Non è possibile specificare sia iddatadb che idquotations'); -} - -// Verifica che l'utente loggato esista -$stmt = $pdo->prepare("SELECT id FROM auth_users WHERE id = ?"); -$stmt->execute([$iduserlogin]); -if (!$stmt->fetch(PDO::FETCH_ASSOC)) { - die('Utente non valido'); -} - -// Determina quale ID usare e verifica l'esistenza -$paramName = $iddatadb ? 'iddatadb' : 'idquotations'; -$paramValue = $iddatadb ?: $idquotations; -$table = $iddatadb ? 'datadb' : 'quotations'; -$field = $iddatadb ? 'sample_code' : 'quotation_code'; - -$stmt = $pdo->prepare("SELECT {$paramName}, {$field} FROM {$table} WHERE {$paramName} = ?"); -$stmt->execute([$paramValue]); -$row = $stmt->fetch(PDO::FETCH_ASSOC); - -if (!$row) { - die('Riga non trovata'); -} - -$id = $row[$paramName]; -$code = $row[$field] ?? 'Non disponibile'; -?> - - - - - - - - Carica Foto da Mobile - - - - - -

                Carica Foto per ID:

                -

                Codice:

                -
                -
                - -

                Caricamento in corso...

                -
                -
                -
                -
                -

                Scatta una foto o seleziona immagini

                - -
                -
                - - - - - \ No newline at end of file diff --git a/public/userarea/upload_xls_example.php b/public/userarea/upload_xls_example.php deleted file mode 100644 index 04ce32c..0000000 --- a/public/userarea/upload_xls_example.php +++ /dev/null @@ -1,48 +0,0 @@ - false, "message" => "Invalid template ID"]); - exit; -} - -$template_id = intval($_POST['template_id']); - -if (!isset($_FILES['xls_file']) || $_FILES['xls_file']['error'] !== UPLOAD_ERR_OK) { - echo json_encode(["success" => false, "message" => "File upload error"]); - exit; -} - -$file = $_FILES['xls_file']; -$originalFilename = pathinfo($file['name'], PATHINFO_FILENAME); -$extension = pathinfo($file['name'], PATHINFO_EXTENSION); - -// Crea il nuovo nome del file: {idtemplate}-{timestamp}-{nomeoriginale}.ext -$newFilename = $template_id . "-" . time() . "-" . preg_replace("/[^a-zA-Z0-9_-]/", "", $originalFilename) . "." . $extension; -$uploadDir = __DIR__ . '/xlstemplates/'; -$uploadPath = $uploadDir . $newFilename; - -// Assicura che la cartella esista -if (!is_dir($uploadDir)) { - mkdir($uploadDir, 0777, true); -} - -// Salva il file -if (!move_uploaded_file($file['tmp_name'], $uploadPath)) { - echo json_encode(["success" => false, "message" => "Failed to save file"]); - exit; -} - -// Aggiorna il database con il nome del file -try { - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - $stmt = $pdo->prepare("UPDATE excel_templates SET sample_xlsx = ? WHERE id = ?"); - $stmt->execute([$newFilename, $template_id]); - - echo json_encode(["success" => true, "filename" => $newFilename, "filepath" => "xlstemplates/" . $newFilename]); -} catch (PDOException $e) { - echo json_encode(["success" => false, "message" => "Database error: " . $e->getMessage()]); -} diff --git a/public/userarea/uploads/Cassina Indoor Listino Prezzi € (IVA Esclusa) ITALIA - Febbraio 2024-68.pdf b/public/userarea/uploads/Cassina Indoor Listino Prezzi € (IVA Esclusa) ITALIA - Febbraio 2024-68.pdf new file mode 100644 index 0000000..6760859 Binary files /dev/null and b/public/userarea/uploads/Cassina Indoor Listino Prezzi € (IVA Esclusa) ITALIA - Febbraio 2024-68.pdf differ diff --git a/public/userarea/uploads/Cassina Indoor Listino Prezzi € (IVA Esclusa) ITALIA - Febbraio 2024.pdf b/public/userarea/uploads/Cassina Indoor Listino Prezzi € (IVA Esclusa) ITALIA - Febbraio 2024.pdf new file mode 100644 index 0000000..5dc03ca Binary files /dev/null and b/public/userarea/uploads/Cassina Indoor Listino Prezzi € (IVA Esclusa) ITALIA - Febbraio 2024.pdf differ diff --git a/public/userarea/uploads/client_files/1762870139_provapagina.pdf b/public/userarea/uploads/client_files/1762870139_provapagina.pdf new file mode 100644 index 0000000..3f997ec Binary files /dev/null and b/public/userarea/uploads/client_files/1762870139_provapagina.pdf differ diff --git a/public/userarea/uploads/provapagina.pdf b/public/userarea/uploads/provapagina.pdf new file mode 100644 index 0000000..3f997ec Binary files /dev/null and b/public/userarea/uploads/provapagina.pdf differ diff --git a/public/userarea/xlstemplates_creation.php b/public/userarea/xlstemplates_creation.php deleted file mode 100644 index 98bfc55..0000000 --- a/public/userarea/xlstemplates_creation.php +++ /dev/null @@ -1,765 +0,0 @@ - - - - - - - - - - Edmate Learning Dashboard HTML Template - - - - - - - - - -
                -
                -
                - - - -
                - - - - - - - -
                - - - -
                - -
                -
                - -
                -
                -
                -
                XLS TEMPLATE
                - -
                - -
                - -
                -
                - - -
                -
                - - -
                -
                Colonne Excel
                -
                - -
                -
                -
                - -
                -
                -
                Colonne MySQL
                -
                - -
                -
                - - -
                -
                Binding Creati
                -
                -
                  -
                  -
                  - - -
                  - -
                  -
                  - -
                  -
                  - - - -
                  -
                  -
                  -

                  Top Courses Pick for You

                  - See All -
                  - -
                  -
                  -
                  -
                  - - Course Image - -
                  - Development -
                  Full Stack Web Development
                  - -
                  - User Image -
                  - Created by Albert James -
                  -
                  - -
                  -
                  - - 24 Lesson -
                  -
                  - - 40 Hours -
                  -
                  - -
                  -
                  - - 4.9 - (12k) -
                  - View Details -
                  -
                  -
                  -
                  -
                  -
                  -
                  -
                  - - Course Image - -
                  - Design -
                  Design System
                  - -
                  - User Image -
                  - Created by Albert James -
                  -
                  - -
                  -
                  - - 24 Lesson -
                  -
                  - - 40 Hours -
                  -
                  - -
                  -
                  - - 4.9 - (12k) -
                  - View Details -
                  -
                  -
                  -
                  -
                  -
                  -
                  -
                  - - Course Image - -
                  - Frontend -
                  React Native Courese
                  - -
                  - User Image -
                  - Created by Albert James -
                  -
                  - -
                  -
                  - - 24 Lesson -
                  -
                  - - 40 Hours -
                  -
                  - -
                  -
                  - - 4.9 - (12k) -
                  - View Details -
                  -
                  -
                  -
                  -
                  -
                  -
                  -
                  - -
                  - - - -
                  -
                  - -
                  - - - - - - - - - - - - \ No newline at end of file diff --git a/public/userarea/xlstemplates_grid.php b/public/userarea/xlstemplates_grid.php deleted file mode 100644 index 222eced..0000000 --- a/public/userarea/xlstemplates_grid.php +++ /dev/null @@ -1,206 +0,0 @@ - - - - - - - - - - Edmate Learning Dashboard HTML Template - - - - - - - - - - - - -
                  -
                  -
                  - - - -
                  - - - - - - - -
                  - - - -
                  - -
                  -
                  - - -
                  -
                  -
                  -

                  XLS Templates

                  - -
                  - - - -
                  -
                  -
                  - - - - - - - - - - - - - -
                  ID
                  - -
                  -
                  -
                  - -
                  -
                  - - - -
                  - - - -
                  -
                  - -
                  - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/autoload.php b/vendor/autoload.php index 5d5afaa..167db80 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -14,10 +14,7 @@ if (PHP_VERSION_ID < 50600) { echo $err; } } - trigger_error( - $err, - E_USER_ERROR - ); + throw new RuntimeException($err); } require_once __DIR__ . '/composer/autoload_real.php'; diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 51e734a..2052022 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -26,12 +26,23 @@ use Composer\Semver\VersionParser; */ class InstalledVersions { + /** + * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to + * @internal + */ + private static $selfDir = null; + /** * @var mixed[]|null * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null */ private static $installed; + /** + * @var bool + */ + private static $installedIsLocalDir; + /** * @var bool|null */ @@ -309,6 +320,24 @@ class InstalledVersions { self::$installed = $data; self::$installedByVendor = array(); + + // when using reload, we disable the duplicate protection to ensure that self::$installed data is + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, + // so we have to assume it does not, and that may result in duplicate data being returned when listing + // all installed packages for example + self::$installedIsLocalDir = false; + } + + /** + * @return string + */ + private static function getSelfDir() + { + if (self::$selfDir === null) { + self::$selfDir = strtr(__DIR__, '\\', '/'); + } + + return self::$selfDir; } /** @@ -322,19 +351,27 @@ class InstalledVersions } $installed = array(); + $copiedLocalDir = false; if (self::$canGetVendors) { + $selfDir = self::getSelfDir(); foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + $vendorDir = strtr($vendorDir, '\\', '/'); if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ $required = require $vendorDir.'/composer/installed.php'; - $installed[] = self::$installedByVendor[$vendorDir] = $required; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { + self::$installed = $required; + self::$installedIsLocalDir = true; } } + if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { + $copiedLocalDir = true; + } } } @@ -350,7 +387,7 @@ class InstalledVersions } } - if (self::$installed !== array()) { + if (self::$installed !== array() && !$copiedLocalDir) { $installed[] = self::$installed; } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 69f2620..601d0eb 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -5303,6 +5303,8 @@ return array( 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\ConditionalDataBarExtension' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\ConditionalFormatValueObject' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\ConditionalFormattingRuleExtension' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php', + 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\ConditionalIconSet' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalIconSet.php', + 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\IconSetValues' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/IconSetValues.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\StyleMerger' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/StyleMerger.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\Wizard' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\Wizard\\Blanks' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Blanks.php', @@ -5400,6 +5402,7 @@ return array( 'PhpOffice\\PhpSpreadsheet\\Writer\\Pdf\\Dompdf' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Pdf\\Mpdf' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Pdf\\Tcpdf' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php', + 'PhpOffice\\PhpSpreadsheet\\Writer\\Pdf\\TcpdfNoDie' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/TcpdfNoDie.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Xls' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Xls\\BIFFwriter' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/BIFFwriter.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Xls\\CellDataValidation' => $vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/CellDataValidation.php', @@ -6314,6 +6317,52 @@ return array( 'SebastianBergmann\\Type\\UnknownType' => $vendorDir . '/sebastian/type/src/type/UnknownType.php', 'SebastianBergmann\\Type\\VoidType' => $vendorDir . '/sebastian/type/src/type/VoidType.php', 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', + 'Smalot\\PdfParser\\Config' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Config.php', + 'Smalot\\PdfParser\\Document' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Document.php', + 'Smalot\\PdfParser\\Element' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element.php', + 'Smalot\\PdfParser\\Element\\ElementArray' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementArray.php', + 'Smalot\\PdfParser\\Element\\ElementBoolean' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementBoolean.php', + 'Smalot\\PdfParser\\Element\\ElementDate' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementDate.php', + 'Smalot\\PdfParser\\Element\\ElementHexa' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementHexa.php', + 'Smalot\\PdfParser\\Element\\ElementMissing' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementMissing.php', + 'Smalot\\PdfParser\\Element\\ElementName' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementName.php', + 'Smalot\\PdfParser\\Element\\ElementNull' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementNull.php', + 'Smalot\\PdfParser\\Element\\ElementNumeric' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementNumeric.php', + 'Smalot\\PdfParser\\Element\\ElementString' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementString.php', + 'Smalot\\PdfParser\\Element\\ElementStruct' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementStruct.php', + 'Smalot\\PdfParser\\Element\\ElementXRef' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementXRef.php', + 'Smalot\\PdfParser\\Encoding' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding.php', + 'Smalot\\PdfParser\\Encoding\\AbstractEncoding' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/AbstractEncoding.php', + 'Smalot\\PdfParser\\Encoding\\EncodingLocator' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/EncodingLocator.php', + 'Smalot\\PdfParser\\Encoding\\ISOLatin1Encoding' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/ISOLatin1Encoding.php', + 'Smalot\\PdfParser\\Encoding\\ISOLatin9Encoding' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/ISOLatin9Encoding.php', + 'Smalot\\PdfParser\\Encoding\\MacRomanEncoding' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/MacRomanEncoding.php', + 'Smalot\\PdfParser\\Encoding\\PDFDocEncoding' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/PDFDocEncoding.php', + 'Smalot\\PdfParser\\Encoding\\PostScriptGlyphs' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/PostScriptGlyphs.php', + 'Smalot\\PdfParser\\Encoding\\StandardEncoding' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/StandardEncoding.php', + 'Smalot\\PdfParser\\Encoding\\WinAnsiEncoding' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/WinAnsiEncoding.php', + 'Smalot\\PdfParser\\Exception\\EmptyPdfException' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/EmptyPdfException.php', + 'Smalot\\PdfParser\\Exception\\EncodingNotFoundException' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/EncodingNotFoundException.php', + 'Smalot\\PdfParser\\Exception\\InvalidDictionaryObjectException' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/InvalidDictionaryObjectException.php', + 'Smalot\\PdfParser\\Exception\\MissingCatalogException' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/MissingCatalogException.php', + 'Smalot\\PdfParser\\Exception\\MissingPdfHeaderException' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/MissingPdfHeaderException.php', + 'Smalot\\PdfParser\\Exception\\NotImplementedException' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/NotImplementedException.php', + 'Smalot\\PdfParser\\Font' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Font.php', + 'Smalot\\PdfParser\\Font\\FontCIDFontType0' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontCIDFontType0.php', + 'Smalot\\PdfParser\\Font\\FontCIDFontType2' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontCIDFontType2.php', + 'Smalot\\PdfParser\\Font\\FontTrueType' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontTrueType.php', + 'Smalot\\PdfParser\\Font\\FontType0' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontType0.php', + 'Smalot\\PdfParser\\Font\\FontType1' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontType1.php', + 'Smalot\\PdfParser\\Font\\FontType3' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontType3.php', + 'Smalot\\PdfParser\\Header' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Header.php', + 'Smalot\\PdfParser\\PDFObject' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/PDFObject.php', + 'Smalot\\PdfParser\\Page' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Page.php', + 'Smalot\\PdfParser\\Pages' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Pages.php', + 'Smalot\\PdfParser\\Parser' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/Parser.php', + 'Smalot\\PdfParser\\RawData\\FilterHelper' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/RawData/FilterHelper.php', + 'Smalot\\PdfParser\\RawData\\RawDataParser' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/RawData/RawDataParser.php', + 'Smalot\\PdfParser\\XObject\\Form' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/XObject/Form.php', + 'Smalot\\PdfParser\\XObject\\Image' => $vendorDir . '/smalot/pdfparser/src/Smalot/PdfParser/XObject/Image.php', 'SocialiteProviders\\Manager\\Config' => $vendorDir . '/socialiteproviders/manager/src/Config.php', 'SocialiteProviders\\Manager\\ConfigTrait' => $vendorDir . '/socialiteproviders/manager/src/ConfigTrait.php', 'SocialiteProviders\\Manager\\Contracts\\ConfigInterface' => $vendorDir . '/socialiteproviders/manager/src/Contracts/ConfigInterface.php', diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index 5dcae5d..58426dd 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -7,6 +7,7 @@ $baseDir = dirname($vendorDir); return array( 'Webpatser\\Countries' => array($vendorDir . '/webpatser/laravel-countries/src'), + 'Smalot\\PdfParser\\' => array($vendorDir . '/smalot/pdfparser/src'), 'Detection' => array($vendorDir . '/mobiledetect/mobiledetectlib/namespaced'), 'Barryvdh' => array($vendorDir . '/barryvdh/reflection-docblock/src'), ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 98a2b36..89947f5 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -8,7 +8,7 @@ $baseDir = dirname($vendorDir); return array( 'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'), 'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), - 'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src'), + 'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-common/src'), 'ZipStream\\' => array($vendorDir . '/maennchen/zipstream-php/src'), 'Whoops\\' => array($vendorDir . '/filp/whoops/src/Whoops'), 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), @@ -55,8 +55,8 @@ return array( 'Spatie\\QueryBuilder\\Database\\Factories\\' => array($vendorDir . '/spatie/laravel-query-builder/database/factories'), 'Spatie\\QueryBuilder\\' => array($vendorDir . '/spatie/laravel-query-builder/src'), 'Spatie\\LaravelPackageTools\\' => array($vendorDir . '/spatie/laravel-package-tools/src'), - 'Spatie\\LaravelIgnition\\' => array($vendorDir . '/spatie/error-solutions/legacy/laravel-ignition', $vendorDir . '/spatie/laravel-ignition/src'), - 'Spatie\\Ignition\\' => array($vendorDir . '/spatie/error-solutions/legacy/ignition', $vendorDir . '/spatie/ignition/src'), + 'Spatie\\LaravelIgnition\\' => array($vendorDir . '/spatie/laravel-ignition/src', $vendorDir . '/spatie/error-solutions/legacy/laravel-ignition'), + 'Spatie\\Ignition\\' => array($vendorDir . '/spatie/ignition/src', $vendorDir . '/spatie/error-solutions/legacy/ignition'), 'Spatie\\FlareClient\\' => array($vendorDir . '/spatie/flare-client-php/src'), 'Spatie\\ErrorSolutions\\' => array($vendorDir . '/spatie/error-solutions/src'), 'Spatie\\Backtrace\\' => array($vendorDir . '/spatie/backtrace/src'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 2feeac8..6302cef 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -257,8 +257,8 @@ class ComposerStaticInitc91cd9c5b1e6a9e8573a14b799ea9342 ), 'phpDocumentor\\Reflection\\' => array ( - 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', - 1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', + 0 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', + 1 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', ), 'ZipStream\\' => array ( @@ -446,13 +446,13 @@ class ComposerStaticInitc91cd9c5b1e6a9e8573a14b799ea9342 ), 'Spatie\\LaravelIgnition\\' => array ( - 0 => __DIR__ . '/..' . '/spatie/error-solutions/legacy/laravel-ignition', - 1 => __DIR__ . '/..' . '/spatie/laravel-ignition/src', + 0 => __DIR__ . '/..' . '/spatie/laravel-ignition/src', + 1 => __DIR__ . '/..' . '/spatie/error-solutions/legacy/laravel-ignition', ), 'Spatie\\Ignition\\' => array ( - 0 => __DIR__ . '/..' . '/spatie/error-solutions/legacy/ignition', - 1 => __DIR__ . '/..' . '/spatie/ignition/src', + 0 => __DIR__ . '/..' . '/spatie/ignition/src', + 1 => __DIR__ . '/..' . '/spatie/error-solutions/legacy/ignition', ), 'Spatie\\FlareClient\\' => array ( @@ -805,6 +805,13 @@ class ComposerStaticInitc91cd9c5b1e6a9e8573a14b799ea9342 0 => __DIR__ . '/..' . '/webpatser/laravel-countries/src', ), ), + 'S' => + array ( + 'Smalot\\PdfParser\\' => + array ( + 0 => __DIR__ . '/..' . '/smalot/pdfparser/src', + ), + ), 'D' => array ( 'Detection' => @@ -6119,6 +6126,8 @@ class ComposerStaticInitc91cd9c5b1e6a9e8573a14b799ea9342 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\ConditionalDataBarExtension' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\ConditionalFormatValueObject' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\ConditionalFormattingRuleExtension' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php', + 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\ConditionalIconSet' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalIconSet.php', + 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\IconSetValues' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/IconSetValues.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\StyleMerger' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/StyleMerger.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\Wizard' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard.php', 'PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\Wizard\\Blanks' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Blanks.php', @@ -6216,6 +6225,7 @@ class ComposerStaticInitc91cd9c5b1e6a9e8573a14b799ea9342 'PhpOffice\\PhpSpreadsheet\\Writer\\Pdf\\Dompdf' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Pdf\\Mpdf' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Pdf\\Tcpdf' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php', + 'PhpOffice\\PhpSpreadsheet\\Writer\\Pdf\\TcpdfNoDie' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/TcpdfNoDie.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Xls' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Xls\\BIFFwriter' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/BIFFwriter.php', 'PhpOffice\\PhpSpreadsheet\\Writer\\Xls\\CellDataValidation' => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/CellDataValidation.php', @@ -7130,6 +7140,52 @@ class ComposerStaticInitc91cd9c5b1e6a9e8573a14b799ea9342 'SebastianBergmann\\Type\\UnknownType' => __DIR__ . '/..' . '/sebastian/type/src/type/UnknownType.php', 'SebastianBergmann\\Type\\VoidType' => __DIR__ . '/..' . '/sebastian/type/src/type/VoidType.php', 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', + 'Smalot\\PdfParser\\Config' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Config.php', + 'Smalot\\PdfParser\\Document' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Document.php', + 'Smalot\\PdfParser\\Element' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element.php', + 'Smalot\\PdfParser\\Element\\ElementArray' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementArray.php', + 'Smalot\\PdfParser\\Element\\ElementBoolean' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementBoolean.php', + 'Smalot\\PdfParser\\Element\\ElementDate' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementDate.php', + 'Smalot\\PdfParser\\Element\\ElementHexa' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementHexa.php', + 'Smalot\\PdfParser\\Element\\ElementMissing' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementMissing.php', + 'Smalot\\PdfParser\\Element\\ElementName' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementName.php', + 'Smalot\\PdfParser\\Element\\ElementNull' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementNull.php', + 'Smalot\\PdfParser\\Element\\ElementNumeric' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementNumeric.php', + 'Smalot\\PdfParser\\Element\\ElementString' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementString.php', + 'Smalot\\PdfParser\\Element\\ElementStruct' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementStruct.php', + 'Smalot\\PdfParser\\Element\\ElementXRef' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Element/ElementXRef.php', + 'Smalot\\PdfParser\\Encoding' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding.php', + 'Smalot\\PdfParser\\Encoding\\AbstractEncoding' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/AbstractEncoding.php', + 'Smalot\\PdfParser\\Encoding\\EncodingLocator' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/EncodingLocator.php', + 'Smalot\\PdfParser\\Encoding\\ISOLatin1Encoding' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/ISOLatin1Encoding.php', + 'Smalot\\PdfParser\\Encoding\\ISOLatin9Encoding' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/ISOLatin9Encoding.php', + 'Smalot\\PdfParser\\Encoding\\MacRomanEncoding' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/MacRomanEncoding.php', + 'Smalot\\PdfParser\\Encoding\\PDFDocEncoding' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/PDFDocEncoding.php', + 'Smalot\\PdfParser\\Encoding\\PostScriptGlyphs' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/PostScriptGlyphs.php', + 'Smalot\\PdfParser\\Encoding\\StandardEncoding' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/StandardEncoding.php', + 'Smalot\\PdfParser\\Encoding\\WinAnsiEncoding' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Encoding/WinAnsiEncoding.php', + 'Smalot\\PdfParser\\Exception\\EmptyPdfException' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/EmptyPdfException.php', + 'Smalot\\PdfParser\\Exception\\EncodingNotFoundException' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/EncodingNotFoundException.php', + 'Smalot\\PdfParser\\Exception\\InvalidDictionaryObjectException' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/InvalidDictionaryObjectException.php', + 'Smalot\\PdfParser\\Exception\\MissingCatalogException' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/MissingCatalogException.php', + 'Smalot\\PdfParser\\Exception\\MissingPdfHeaderException' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/MissingPdfHeaderException.php', + 'Smalot\\PdfParser\\Exception\\NotImplementedException' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Exception/NotImplementedException.php', + 'Smalot\\PdfParser\\Font' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Font.php', + 'Smalot\\PdfParser\\Font\\FontCIDFontType0' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontCIDFontType0.php', + 'Smalot\\PdfParser\\Font\\FontCIDFontType2' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontCIDFontType2.php', + 'Smalot\\PdfParser\\Font\\FontTrueType' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontTrueType.php', + 'Smalot\\PdfParser\\Font\\FontType0' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontType0.php', + 'Smalot\\PdfParser\\Font\\FontType1' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontType1.php', + 'Smalot\\PdfParser\\Font\\FontType3' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Font/FontType3.php', + 'Smalot\\PdfParser\\Header' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Header.php', + 'Smalot\\PdfParser\\PDFObject' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/PDFObject.php', + 'Smalot\\PdfParser\\Page' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Page.php', + 'Smalot\\PdfParser\\Pages' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Pages.php', + 'Smalot\\PdfParser\\Parser' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/Parser.php', + 'Smalot\\PdfParser\\RawData\\FilterHelper' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/RawData/FilterHelper.php', + 'Smalot\\PdfParser\\RawData\\RawDataParser' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/RawData/RawDataParser.php', + 'Smalot\\PdfParser\\XObject\\Form' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/XObject/Form.php', + 'Smalot\\PdfParser\\XObject\\Image' => __DIR__ . '/..' . '/smalot/pdfparser/src/Smalot/PdfParser/XObject/Image.php', 'SocialiteProviders\\Manager\\Config' => __DIR__ . '/..' . '/socialiteproviders/manager/src/Config.php', 'SocialiteProviders\\Manager\\ConfigTrait' => __DIR__ . '/..' . '/socialiteproviders/manager/src/ConfigTrait.php', 'SocialiteProviders\\Manager\\Contracts\\ConfigInterface' => __DIR__ . '/..' . '/socialiteproviders/manager/src/Contracts/ConfigInterface.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 670e46b..97a9efe 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -5464,17 +5464,17 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "4.1.0", - "version_normalized": "4.1.0.0", + "version": "5.2.0", + "version_normalized": "5.2.0.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "6ff18c3a8df3a945492f75ce455d77f7ad55dd5c" + "reference": "3b8994b3aac4b61018bc04fc8c441f4fd68c18eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/6ff18c3a8df3a945492f75ce455d77f7ad55dd5c", - "reference": "6ff18c3a8df3a945492f75ce455d77f7ad55dd5c", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/3b8994b3aac4b61018bc04fc8c441f4fd68c18eb", + "reference": "3b8994b3aac4b61018bc04fc8c441f4fd68c18eb", "shasum": "" }, "require": { @@ -5504,23 +5504,24 @@ "dealerdirect/phpcodesniffer-composer-installer": "dev-main", "dompdf/dompdf": "^2.0 || ^3.0", "friendsofphp/php-cs-fixer": "^3.2", - "mitoteam/jpgraph": "^10.3", + "mitoteam/jpgraph": "^10.5", "mpdf/mpdf": "^8.1.1", "phpcompatibility/php-compatibility": "^9.3", - "phpstan/phpstan": "^1.1", - "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan": "^1.1 || ^2.0", + "phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0", + "phpstan/phpstan-phpunit": "^1.0 || ^2.0", "phpunit/phpunit": "^10.5", "squizlabs/php_codesniffer": "^3.7", "tecnickcom/tcpdf": "^6.5" }, "suggest": { "dompdf/dompdf": "Option for rendering PDF with PDF Writer", - "ext-intl": "PHP Internationalization Functions", + "ext-intl": "PHP Internationalization Functions, regquired for NumberFormat Wizard", "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", "mpdf/mpdf": "Option for rendering PDF with PDF Writer", "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" }, - "time": "2025-03-02T06:52:24+00:00", + "time": "2025-10-26T15:54:22+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -5566,7 +5567,7 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/4.1.0" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.2.0" }, "install-path": "../phpoffice/phpspreadsheet" }, @@ -8107,6 +8108,60 @@ ], "install-path": "../sebastian/version" }, + { + "name": "smalot/pdfparser", + "version": "v2.12.1", + "version_normalized": "2.12.1.0", + "source": { + "type": "git", + "url": "https://github.com/smalot/pdfparser.git", + "reference": "98d31ba34ef5b5a98897ef4b6c3925d502ea53b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/smalot/pdfparser/zipball/98d31ba34ef5b5a98897ef4b6c3925d502ea53b1", + "reference": "98d31ba34ef5b5a98897ef4b6c3925d502ea53b1", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-zlib": "*", + "php": ">=7.1", + "symfony/polyfill-mbstring": "^1.18" + }, + "time": "2025-07-31T06:19:56+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Smalot\\PdfParser\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Sebastien MALOT", + "email": "sebastien@malot.fr" + } + ], + "description": "Pdf parser library. Can read and extract information from pdf file.", + "homepage": "https://www.pdfparser.org", + "keywords": [ + "extract", + "parse", + "parser", + "pdf", + "text" + ], + "support": { + "issues": "https://github.com/smalot/pdfparser/issues", + "source": "https://github.com/smalot/pdfparser/tree/v2.12.1" + }, + "install-path": "../smalot/pdfparser" + }, { "name": "socialiteproviders/manager", "version": "v4.8.1", diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 5833429..5ad65f2 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'loshmis/vanguard', 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'baf3f6da32fd5bc669ac7360970be21407d1d384', + 'reference' => 'e75be99e43b28088315b19f86eee2e6869c7c844', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -688,7 +688,7 @@ 'loshmis/vanguard' => array( 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'baf3f6da32fd5bc669ac7360970be21407d1d384', + 'reference' => 'e75be99e43b28088315b19f86eee2e6869c7c844', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -890,9 +890,9 @@ 'dev_requirement' => false, ), 'phpoffice/phpspreadsheet' => array( - 'pretty_version' => '4.1.0', - 'version' => '4.1.0.0', - 'reference' => '6ff18c3a8df3a945492f75ce455d77f7ad55dd5c', + 'pretty_version' => '5.2.0', + 'version' => '5.2.0.0', + 'reference' => '3b8994b3aac4b61018bc04fc8c441f4fd68c18eb', 'type' => 'library', 'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet', 'aliases' => array(), @@ -1295,6 +1295,15 @@ 'aliases' => array(), 'dev_requirement' => true, ), + 'smalot/pdfparser' => array( + 'pretty_version' => 'v2.12.1', + 'version' => '2.12.1.0', + 'reference' => '98d31ba34ef5b5a98897ef4b6c3925d502ea53b1', + 'type' => 'library', + 'install_path' => __DIR__ . '/../smalot/pdfparser', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'socialiteproviders/manager' => array( 'pretty_version' => 'v4.8.1', 'version' => '4.8.1.0', diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index d515d34..8748439 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -23,8 +23,7 @@ if ($issues) { echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; } } - trigger_error( - 'Composer detected issues in your platform: ' . implode(' ', $issues), - E_USER_ERROR + throw new \RuntimeException( + 'Composer detected issues in your platform: ' . implode(' ', $issues) ); } diff --git a/vendor/phpoffice/phpspreadsheet/CHANGELOG.md b/vendor/phpoffice/phpspreadsheet/CHANGELOG.md index 1a5bc4e..4e36a8d 100644 --- a/vendor/phpoffice/phpspreadsheet/CHANGELOG.md +++ b/vendor/phpoffice/phpspreadsheet/CHANGELOG.md @@ -3,9 +3,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com) -and this project adheres to [Semantic Versioning](https://semver.org). +and this project adheres to [Semantic Versioning](https://semver.org). Thia is always true of the master branch. Some earlier branches remain supported and security fixes are applied to them; if the security fix represents a breaking change, it may have to be applied as a minor or patch version. -## TBD - 4.2.0 +## TBD - 5.3.0 ### Added @@ -31,12 +31,182 @@ and this project adheres to [Semantic Versioning](https://semver.org). - Nothing yet. +## 2025-10-25 - 5.2.0 + +### Added + +- This release should be usable with Php8.5 Release Candidates without deprecation messages. +- Option to display numbers with less precision. [Issue #4626](https://github.com/PHPOffice/PhpSpreadsheet/issues/4626) [PR #4640](https://github.com/PHPOffice/PhpSpreadsheet/pull/4640) +- Offer Tcpdf Interface which throws exception rather than die. [PR #4666](https://github.com/PHPOffice/PhpSpreadsheet/pull/4666) +- Xls Reader ListWorksheetDimensions method. [PR #4689](https://github.com/PHPOffice/PhpSpreadsheet/pull/4689) + +### Deprecated + +- Worksheet::getHashInt serves no useful purpose. No replacement. +- Spreadsheet::getId serves no useful purpose. No replacement. + +### Fixed + +- Performance improvement when working with large amounts of cells. [Issue #4607](https://github.com/PHPOffice/PhpSpreadsheet/issues/4607) [PR #4609](https://github.com/PHPOffice/PhpSpreadsheet/pull/4609) +- Minor improvements to Calculation coverage. [PR #4624](https://github.com/PHPOffice/PhpSpreadsheet/pull/4624) +- Conditional formatting in extLst. [Issue #4629](https://github.com/PHPOffice/PhpSpreadsheet/issues/4629) [PR #4633](https://github.com/PHPOffice/PhpSpreadsheet/pull/4633) +- Php8.5 deprecates use of null as array index. [PR #4634](https://github.com/PHPOffice/PhpSpreadsheet/pull/4634) +- Wrapped cells and default row height. [Issue #4584](https://github.com/PHPOffice/PhpSpreadsheet/issues/4584) [PR #4645](https://github.com/PHPOffice/PhpSpreadsheet/pull/4645) +- For Php8.5, replace one of our two uses of `__wakeup` with `__unserialize`, and eliminate the other. [PR #4639](https://github.com/PHPOffice/PhpSpreadsheet/pull/4639) +- Use prefix _xlfn for BASE function. [Issue #4638](https://github.com/PHPOffice/PhpSpreadsheet/issues/4638) [PR #4641](https://github.com/PHPOffice/PhpSpreadsheet/pull/4641) +- Warning messages with corrupt Xls file. [Issue #4647](https://github.com/PHPOffice/PhpSpreadsheet/issues/4647) [PR #4648](https://github.com/PHPOffice/PhpSpreadsheet/pull/4648) +- Additional support for union and intersection. [PR #4596](https://github.com/PHPOffice/PhpSpreadsheet/pull/4596) +- Missing array keys x,o,v for Xml Reader. [Issue #4668](https://github.com/PHPOffice/PhpSpreadsheet/issues/4668) [PR #4669](https://github.com/PHPOffice/PhpSpreadsheet/pull/4669) +- Missing array key x for Xlsx Reader VML. [Issue #4505](https://github.com/PHPOffice/PhpSpreadsheet/issues/4505) [PR #4676](https://github.com/PHPOffice/PhpSpreadsheet/pull/4676) +- Better support for Style Alignment Read Order. [Issue #850](https://github.com/PHPOffice/PhpSpreadsheet/issues/850) [PR #4655](https://github.com/PHPOffice/PhpSpreadsheet/pull/4655) +- More sophisticated workbook password algorithms (Xlsx only). [Issue #4673](https://github.com/PHPOffice/PhpSpreadsheet/issues/4673) [PR #4675](https://github.com/PHPOffice/PhpSpreadsheet/pull/4675) +- Xls Writer fix DIMENSIONS record. [Issue #4682](https://github.com/PHPOffice/PhpSpreadsheet/issues/4682) [PR #4687](https://github.com/PHPOffice/PhpSpreadsheet/pull/4687) +- Xls Reader listWorksheetInfo process MULRK records. [PR #4689](https://github.com/PHPOffice/PhpSpreadsheet/pull/4689) +- Make Reader Xls Escher generic. [PR #4690](https://github.com/PHPOffice/PhpSpreadsheet/pull/4690) + +## 2025-09-03 - 5.1.0 + +### Added + +- Add Conditional Formatting with IconSet (Xlsx only). [Issue #4560](https://github.com/PHPOffice/PhpSpreadsheet/issues/4560) [PR #4574](https://github.com/PHPOffice/PhpSpreadsheet/pull/4574) +- Copy cell adjusting formula. [Issue #1203](https://github.com/PHPOffice/PhpSpreadsheet/issues/1203) [PR #4577](https://github.com/PHPOffice/PhpSpreadsheet/pull/4577) +- splitRange and ProtectedRange. [Issue #1457](https://github.com/PHPOffice/PhpSpreadsheet/issues/1457) [PR #4580](https://github.com/PHPOffice/PhpSpreadsheet/pull/4580) +- Option to create Blank Sheet if LoadSheetsOnly doesn't find any. [PR #4618](https://github.com/PHPOffice/PhpSpreadsheet/pull/4618) + +### Fixed + +- Google-only formulas exported from Google Sheets. [Issue #1637](https://github.com/PHPOffice/PhpSpreadsheet/issues/1637) [PR #4579](https://github.com/PHPOffice/PhpSpreadsheet/pull/4579) +- Maximum column width. [PR #4581](https://github.com/PHPOffice/PhpSpreadsheet/pull/4581) +- PrintArea after row/column delete. [Issue #2912](https://github.com/PHPOffice/PhpSpreadsheet/issues/2912) [PR #4598](https://github.com/PHPOffice/PhpSpreadsheet/pull/4598) +- Remove deprecated imagedestroy call. [PR #4625](https://github.com/PHPOffice/PhpSpreadsheet/pull/4625) +- Excel 2007 problem with newlines. [Issue #4619](https://github.com/PHPOffice/PhpSpreadsheet/issues/4619) [PR #4620](https://github.com/PHPOffice/PhpSpreadsheet/pull/4620) +- Compatibility changes for Php 8.5. [PR #4601](https://github.com/PHPOffice/PhpSpreadsheet/pull/4601) [PR #4611](https://github.com/PHPOffice/PhpSpreadsheet/pull/4611) + +## 2025-08-10 - 5.0.0 + +### Breaking Changes + +- Images will be loaded from an external source (e.g. http://example.com/img.png) only if the reader is explicitly set to allow it via `$reader->setAllowExternalImages(true)`. We do not believe that loading of external images is a widely used feature. +- Deletion of items deprecated in Release 4. See "removed" below. +- Move some properties from Base Reader to Html Reader. [PR #4551](https://github.com/PHPOffice/PhpSpreadsheet/pull/4551) +- DefaultValueBinder will treat integers with more than 15 digits as strings. [Issue #4522](https://github.com/PHPOffice/PhpSpreadsheet/issues/4522) [PR #4527](https://github.com/PHPOffice/PhpSpreadsheet/pull/4527) + +### Removed + +- Theme public constants COLOR_SCHEME_2013_PLUS_NAME (use COLOR_SCHEME_2013_2022_NAME) and COLOR_SCHEME_2013_PLUS (use COLOR_SCHEME_2013_2022). + +### Fixed + +- Additional floating-point precision changes. [Issue #1324](https://github.com/PHPOffice/PhpSpreadsheet/issues/1324) [PR #4575](https://github.com/PHPOffice/PhpSpreadsheet/pull/4575) +- Header/Footer images expand location. [Issue #484](https://github.com/PHPOffice/PhpSpreadsheet/issues/484) [Issue #1318](https://github.com/PHPOffice/PhpSpreadsheet/issues/1318) [PR #4572](https://github.com/PHPOffice/PhpSpreadsheet/pull/4572) +- Create uninitialized cell if used in calculation. [Issue #4558](https://github.com/PHPOffice/PhpSpreadsheet/issues/4558) [Issue #4530](https://github.com/PHPOffice/PhpSpreadsheet/issues/4530) [PR #4565](https://github.com/PHPOffice/PhpSpreadsheet/pull/4565) +- Shared/Date::isDateTime handle cells which calculate as arrays. [Issue #4557](https://github.com/PHPOffice/PhpSpreadsheet/issues/4557) [PR #4562](https://github.com/PHPOffice/PhpSpreadsheet/pull/4562) +- Xlsx Writer eliminate xml:space from non-text nodes. [Issue #4542](https://github.com/PHPOffice/PhpSpreadsheet/issues/4542) [PR #4556](https://github.com/PHPOffice/PhpSpreadsheet/pull/4556) + +## 2025-07-23 - 4.5.0 + +### Added + +- Add to all readers the option to allow or forbid fetching external images. This is unconditionally allowed now. The default will be set to "allow", so no code changes are necessary. However, we are giving consideration to changing the default. [PR #4543](https://github.com/PHPOffice/PhpSpreadsheet/pull/4543) +- Address Excel Inappropriate Number Format Substitution. [PR #4532](https://github.com/PHPOffice/PhpSpreadsheet/pull/4532) + +### Fixed + +- Html Writer Conditional Formatting Inline Css. [Issue #4539](https://github.com/PHPOffice/PhpSpreadsheet/issues/4539) [PR #4541](https://github.com/PHPOffice/PhpSpreadsheet/pull/4541) +- Do not use htmlspecialchars when formatting XML. [Issue #4537](https://github.com/PHPOffice/PhpSpreadsheet/issues/4537) [PR #4540](https://github.com/PHPOffice/PhpSpreadsheet/pull/4540) +- Writer Html/Pdf support RTL alignment of tables. [Issue #1104](https://github.com/PHPOffice/PhpSpreadsheet/issues/1104) [PR #4535](https://github.com/PHPOffice/PhpSpreadsheet/pull/4535) +- Xlsx Reader use dynamic arrays if spreadsheet did so. [PR #4533](https://github.com/PHPOffice/PhpSpreadsheet/pull/4533) +- Ods Reader Nested table-row. [Issue #4528](https://github.com/PHPOffice/PhpSpreadsheet/issues/4528) [Issue #2507](https://github.com/PHPOffice/PhpSpreadsheet/issues/2507) [PR #4531](https://github.com/PHPOffice/PhpSpreadsheet/pull/4531) +- Recognize application/x-empty mimetype. [Issue #4521](https://github.com/PHPOffice/PhpSpreadsheet/issues/4521) [PR #4524](https://github.com/PHPOffice/PhpSpreadsheet/pull/4524) +- Micro-optimization in getSheetByName. [PR #4499](https://github.com/PHPOffice/PhpSpreadsheet/pull/4499) +- Bug in resizeMatricesExtend. [Issue #4451](https://github.com/PHPOffice/PhpSpreadsheet/issues/4451) [PR #4474](https://github.com/PHPOffice/PhpSpreadsheet/pull/4474) +- Allow Replace of Dummy Function with Custom Function. [PR #4544](https://github.com/PHPOffice/PhpSpreadsheet/pull/4544) +- Preserve 0x0a in Strings if Desired. [Issue #347](https://github.com/PHPOffice/PhpSpreadsheet/issues/347) [PR #4536](https://github.com/PHPOffice/PhpSpreadsheet/pull/4536) + +## 2025-06-22 - 4.4.0 + +### Added + +- VSTACK and HSTACK. [Issue #4485](https://github.com/PHPOffice/PhpSpreadsheet/issues/4485) [PR #4492](https://github.com/PHPOffice/PhpSpreadsheet/pull/4492) +- TOCOL and TOROW. [PR #4493](https://github.com/PHPOffice/PhpSpreadsheet/pull/4493) +- Support Current Office Theme. [PR #4500](https://github.com/PHPOffice/PhpSpreadsheet/pull/4500) + +### Deprecated + +- Theme constants COLOR_SCHEME_2013_PLUS_NAME (use COLOR_SCHEME_2013_2022_NAME) and COLOR_SCHEME_2013_PLUS (use COLOR_SCHEME_2013_2022). + +### Fixed + +- Various Writers RichText TextElement Should Inherit Cell Style. [Issue #1154](https://github.com/PHPOffice/PhpSpreadsheet/issues/1154) [PR #4487](https://github.com/PHPOffice/PhpSpreadsheet/pull/4487) +- Minor Changes to FILTER function. [PR #4491](https://github.com/PHPOffice/PhpSpreadsheet/pull/4491) +- Allow Xlsx Reader/Writer to support Font Charset. [Issue #2760](https://github.com/PHPOffice/PhpSpreadsheet/issues/2760) [PR #4501](https://github.com/PHPOffice/PhpSpreadsheet/pull/4501) +- AutoColor for LibreOffice Dark Mode [Discussion 4502](https://github.com/PHPOffice/PhpSpreadsheet/discussions/4502) [PR #4503](https://github.com/PHPOffice/PhpSpreadsheet/pull/4503) +- Xlsx Style Writer Minor Refactoring. [PR #4508](https://github.com/PHPOffice/PhpSpreadsheet/pull/4508) +- Allow Xlsx Reader to Specify ParseHuge. [Issue #4260](https://github.com/PHPOffice/PhpSpreadsheet/issues/4260) [PR #4515](https://github.com/PHPOffice/PhpSpreadsheet/pull/4515) + +## 2025-05-26 - 4.3.1 + +### Fixed + +- Regression in Date::stringToExcel. [Issue #4488](https://github.com/PHPOffice/PhpSpreadsheet/issues/4488) [PR #4489](https://github.com/PHPOffice/PhpSpreadsheet/pull/4489) + +## 2025-05-25 - 4.3.0 + +### Added + +- Xml Reader recognize indents. [Issue #4448](https://github.com/PHPOffice/PhpSpreadsheet/issues/4448) [PR #4449](https://github.com/PHPOffice/PhpSpreadsheet/pull/4449) + +### Changed + +- Phpstan Level 10. + +### Fixed + +- Micro-optimization for excelToDateTimeObject. [Issue #4438](https://github.com/PHPOffice/PhpSpreadsheet/issues/4438) [PR #4442](https://github.com/PHPOffice/PhpSpreadsheet/pull/4442) +- Removing Columns/Rows Containing Merged Cells. [Issue #282](https://github.com/PHPOffice/PhpSpreadsheet/issues/282) [PR #4465](https://github.com/PHPOffice/PhpSpreadsheet/pull/4465) +- Print Area and Row Break. [Issue #1275](https://github.com/PHPOffice/PhpSpreadsheet/issues/1275) [PR #4450](https://github.com/PHPOffice/PhpSpreadsheet/pull/4450) +- Copy Styles after insertNewColumnBefore. [Issue #1425](https://github.com/PHPOffice/PhpSpreadsheet/issues/1425) [PR #4468](https://github.com/PHPOffice/PhpSpreadsheet/pull/4468) +- Xls Writer Treat Hyperlink Starting with # as Internal. [Issue #56](https://github.com/PHPOffice/PhpSpreadsheet/issues/56) [PR #4453](https://github.com/PHPOffice/PhpSpreadsheet/pull/4453) +- More Precision for Float to String Casts. [Issue #3899](https://github.com/PHPOffice/PhpSpreadsheet/issues/3899) [PR #4479](https://github.com/PHPOffice/PhpSpreadsheet/pull/4479) +- Hyperlink Styles. [Issue #1632](https://github.com/PHPOffice/PhpSpreadsheet/issues/1632) [PR #4478](https://github.com/PHPOffice/PhpSpreadsheet/pull/4478) +- ODS Handling of Ceiling and Floor. [Issue #477](https://github.com/PHPOffice/PhpSpreadsheet/issues/407) [PR #4466](https://github.com/PHPOffice/PhpSpreadsheet/pull/4466) +- Xlsx Reader Do Not Process Printer Settings for Dataonly. [Issue #4477](https://github.com/PHPOffice/PhpSpreadsheet/issues/4477) [PR #4480](https://github.com/PHPOffice/PhpSpreadsheet/pull/4480) + +## 2025-04-16 - 4.2.0 + +### Added + +- Add ability to add custom functions to Calculation. [PR #4390](https://github.com/PHPOffice/PhpSpreadsheet/pull/4390) +- Add FormulaRange to IgnoredErrors. [PR #4393](https://github.com/PHPOffice/PhpSpreadsheet/pull/4393) +- TextGrid improvements. [PR #4418](https://github.com/PHPOffice/PhpSpreadsheet/pull/4418) +- Permit read to class which extends Spreadsheet. [Discussion #4402](https://github.com/PHPOffice/PhpSpreadsheet/discussions/4402) [PR #4404](https://github.com/PHPOffice/PhpSpreadsheet/pull/4404) +- Conditional and table formatting support for html writer [PR #4412](https://github.com/PHPOffice/PhpSpreadsheet/pull/4412) + +### Changed + +- Phpstan Version 2. [PR #4384](https://github.com/PHPOffice/PhpSpreadsheet/pull/4384) +- Start migration to Phpstan level 9. [PR #4396](https://github.com/PHPOffice/PhpSpreadsheet/pull/4396) +- Calculation locale logic moved to separate class. [PR #4398](https://github.com/PHPOffice/PhpSpreadsheet/pull/4398) +- TREND_POLYNOMIAL_* and TREND_BEST_FIT do not work, and are changed to throw Exceptions if attempted. (TREND_BEST_FIT_NO_POLY works.) An attempt to use an unknown trend type will now also throw an exception. [Issue #4400](https://github.com/PHPOffice/PhpSpreadsheet/issues/4400) [PR #4339](https://github.com/PHPOffice/PhpSpreadsheet/pull/4339) +- Month parameter of DATE function will now return VALUE if an ordinal string (e.g. '3rd') is used, but will accept bool or null. [PR #4420](https://github.com/PHPOffice/PhpSpreadsheet/pull/4420) + +### Fixed + +- Ignore fractional part of Drawing Shadow Alpha. [Issue #4415](https://github.com/PHPOffice/PhpSpreadsheet/issues/4415) [PR #4417](https://github.com/PHPOffice/PhpSpreadsheet/pull/4417) +- BIN2DEC, OCT2DEC, and HEX2DEC return numbers rather than strings. [Issue #4383](https://github.com/PHPOffice/PhpSpreadsheet/issues/4383) [PR #4389](https://github.com/PHPOffice/PhpSpreadsheet/pull/4389) +- Fix TREND_BEST_FIT_NO_POLY. [Issue #4400](https://github.com/PHPOffice/PhpSpreadsheet/issues/4400) [PR #4339](https://github.com/PHPOffice/PhpSpreadsheet/pull/4339) +- Ods Reader No DataType for Null Value. [Issue #4435](https://github.com/PHPOffice/PhpSpreadsheet/issues/4435) [PR #4436](https://github.com/PHPOffice/PhpSpreadsheet/pull/4436) +- Column widths not preserved when using read filter. [Issue #4416](https://github.com/PHPOffice/PhpSpreadsheet/issues/4416) [PR #4423](https://github.com/PHPOffice/PhpSpreadsheet/pull/4423) +- Fix typo in Style exportArray quotePrefix. [Issue #4422](https://github.com/PHPOffice/PhpSpreadsheet/issues/4422) [PR #4424](https://github.com/PHPOffice/PhpSpreadsheet/pull/4424) +- Tweak Spreadsheet clone. [PR #4419](https://github.com/PHPOffice/PhpSpreadsheet/pull/4419) +- Better handling of Chart DisplayBlanksAs. [Issue #4411](https://github.com/PHPOffice/PhpSpreadsheet/issues/4411) [PR #4414](https://github.com/PHPOffice/PhpSpreadsheet/pull/4414) + ## 2025-03-02 - 4.1.0 ### Added - Support Justify Last Line. [Issue #4374](https://github.com/PHPOffice/PhpSpreadsheet/issues/4374) [PR #4373](https://github.com/PHPOffice/PhpSpreadsheet/pull/4373) -- Allow Spreadsheet clone. [PR #437-](https://github.com/PHPOffice/PhpSpreadsheet/pull/4370) +- Allow Spreadsheet clone. [PR #4370](https://github.com/PHPOffice/PhpSpreadsheet/pull/4370) ### Changed diff --git a/vendor/phpoffice/phpspreadsheet/CONTRIBUTING.md b/vendor/phpoffice/phpspreadsheet/CONTRIBUTING.md index 88a0339..6cbf9fb 100644 --- a/vendor/phpoffice/phpspreadsheet/CONTRIBUTING.md +++ b/vendor/phpoffice/phpspreadsheet/CONTRIBUTING.md @@ -43,7 +43,7 @@ This makes it easier to see exactly what is being tested when reviewing the PR. 4. By default, Github removes markdown headings in the Release Notes. You can either edit to restore these, or, probably preferably, change the default comment character on your system - `git config core.commentChar ";"`. > **Note:** Tagged releases are made from the `master` branch. Only in an emergency should a tagged release be made from the `release` branch. (i.e. cherry-picked hot-fixes.) However, there are 4 branches which have been updated to apply security patches, and those may be tagged if future security updates are needed. -- release1291 -- release210 +- release1291 (no further updates aside from security patches, including code changes needed for Php 8.5 compatibility) +- release210 (no further updates aside from security patches, including code changes needed for Php 8.5 compatibility) - release222 - release390 diff --git a/vendor/phpoffice/phpspreadsheet/README.md b/vendor/phpoffice/phpspreadsheet/README.md index 84b4b7b..8286e3a 100644 --- a/vendor/phpoffice/phpspreadsheet/README.md +++ b/vendor/phpoffice/phpspreadsheet/README.md @@ -1,8 +1,7 @@ # PhpSpreadsheet [![Build Status](https://github.com/PHPOffice/PhpSpreadsheet/workflows/main/badge.svg)](https://github.com/PHPOffice/PhpSpreadsheet/actions) -[![Code Quality](https://scrutinizer-ci.com/g/PHPOffice/PhpSpreadsheet/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/PHPOffice/PhpSpreadsheet/?branch=master) -[![Code Coverage](https://scrutinizer-ci.com/g/PHPOffice/PhpSpreadsheet/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/PHPOffice/PhpSpreadsheet/?branch=master) +[![Code Coverage](https://coveralls.io/repos/github/PHPOffice/PhpSpreadsheet/badge.svg?branch=master)](https://coveralls.io/github/PHPOffice/PhpSpreadsheet?branch=master) [![Total Downloads](https://img.shields.io/packagist/dt/PHPOffice/PhpSpreadsheet)](https://packagist.org/packages/phpoffice/phpspreadsheet) [![Latest Stable Version](https://img.shields.io/github/v/release/PHPOffice/PhpSpreadsheet)](https://packagist.org/packages/phpoffice/phpspreadsheet) [![License](https://img.shields.io/github/license/PHPOffice/PhpSpreadsheet)](https://packagist.org/packages/phpoffice/phpspreadsheet) @@ -11,6 +10,17 @@ PhpSpreadsheet is a library written in pure PHP and offers a set of classes that allow you to read and write various spreadsheet file formats such as Excel and LibreOffice Calc. +This is the master branch, and is maintained for security and bug fixes. + +## PHP Version Support + +LTS: For maintained branches, support for PHP versions will only be maintained for a period of six months beyond the +[end of life](https://www.php.net/supported-versions) of that PHP version. + +Currently the required PHP minimum version is PHP __8.1__, and we [will support that version](https://www.php.net/supported-versions.php) until 30th June 2026. + +See the `composer.json` for other requirements. + ## Installation See the [install instructions](https://phpspreadsheet.readthedocs.io/en/latest/#installation). diff --git a/vendor/phpoffice/phpspreadsheet/composer.json b/vendor/phpoffice/phpspreadsheet/composer.json index 1635f4f..d26157e 100644 --- a/vendor/phpoffice/phpspreadsheet/composer.json +++ b/vendor/phpoffice/phpspreadsheet/composer.json @@ -46,7 +46,7 @@ ], "scripts": { "check": [ - "php ./bin/check-phpdoc-types", + "php bin/check-phpdoc-types.php", "phpcs samples/ src/ tests/ --report=checkstyle", "phpcs samples/ src/ tests/ --standard=PHPCompatibility --runtime-set testVersion 8.0- --exclude=PHPCompatibility.Variables.ForbiddenThisUseContexts -n", "php-cs-fixer fix --ansi --dry-run --diff", @@ -92,17 +92,18 @@ "dealerdirect/phpcodesniffer-composer-installer": "dev-main", "dompdf/dompdf": "^2.0 || ^3.0", "friendsofphp/php-cs-fixer": "^3.2", - "mitoteam/jpgraph": "^10.3", + "mitoteam/jpgraph": "^10.5", "mpdf/mpdf": "^8.1.1", "phpcompatibility/php-compatibility": "^9.3", - "phpstan/phpstan": "^1.1", - "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan": "^1.1 || ^2.0", + "phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0", + "phpstan/phpstan-phpunit": "^1.0 || ^2.0", "phpunit/phpunit": "^10.5", "squizlabs/php_codesniffer": "^3.7", "tecnickcom/tcpdf": "^6.5" }, "suggest": { - "ext-intl": "PHP Internationalization Functions", + "ext-intl": "PHP Internationalization Functions, regquired for NumberFormat Wizard", "mpdf/mpdf": "Option for rendering PDF with PDF Writer", "dompdf/dompdf": "Option for rendering PDF with PDF Writer", "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer", diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/ArrayEnabled.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/ArrayEnabled.php index 7b78b6f..038b716 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/ArrayEnabled.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/ArrayEnabled.php @@ -12,21 +12,25 @@ trait ArrayEnabled private static ArrayArgumentHelper $arrayArgumentHelper; /** - * @param array|false $arguments Can be changed to array for Php8.1+ + * @param mixed[] $arguments */ - private static function initialiseHelper($arguments): void + private static function initialiseHelper(array $arguments): void { if (self::$initializationNeeded === true) { self::$arrayArgumentHelper = new ArrayArgumentHelper(); self::$initializationNeeded = false; } - self::$arrayArgumentHelper->initialise(($arguments === false) ? [] : $arguments); + self::$arrayArgumentHelper->initialise($arguments); } /** * Handles array argument processing when the function accepts a single argument that can be an array argument. * Example use for: * DAYOFMONTH() or FACT(). + * + * @param mixed[] $values + * + * @return mixed[] */ protected static function evaluateSingleArgumentArray(callable $method, array $values): array { @@ -43,6 +47,8 @@ trait ArrayEnabled * and any of them can be an array argument. * Example use for: * ROUND() or DATE(). + * + * @return mixed[] */ protected static function evaluateArrayArguments(callable $method, mixed ...$arguments): array { @@ -58,6 +64,8 @@ trait ArrayEnabled * Example use for: * NETWORKDAYS() or CONCATENATE(), where the last argument is a matrix (or a series of values) that need * to be treated as a such rather than as an array arguments. + * + * @return mixed[] */ protected static function evaluateArrayArgumentsSubset(callable $method, int $limit, mixed ...$arguments): array { @@ -80,6 +88,8 @@ trait ArrayEnabled * Example use for: * Z.TEST() or INDEX(), where the first argument 1 is a matrix that needs to be treated as a dataset * rather than as an array argument. + * + * @return mixed[] */ protected static function evaluateArrayArgumentsSubsetFrom(callable $method, int $start, mixed ...$arguments): array { @@ -105,6 +115,8 @@ trait ArrayEnabled * Example use for: * HLOOKUP() and VLOOKUP(), where argument 1 is a matrix that needs to be treated as a database * rather than as an array argument. + * + * @return mixed[] */ protected static function evaluateArrayArgumentsIgnore(callable $method, int $ignore, mixed ...$arguments): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/BinaryComparison.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/BinaryComparison.php index e4bc156..1f69794 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/BinaryComparison.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/BinaryComparison.php @@ -14,13 +14,15 @@ class BinaryComparison /** * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters. * - * @param null|string $str1 First string value for the comparison - * @param null|string $str2 Second string value for the comparison + * @param mixed $str1 First string value for the comparison, expect ?string + * @param mixed $str2 Second string value for the comparison, expect ?string */ - private static function strcmpLowercaseFirst(?string $str1, ?string $str2): int + private static function strcmpLowercaseFirst(mixed $str1, mixed $str2): int { - $inversedStr1 = StringHelper::strCaseReverse($str1 ?? ''); - $inversedStr2 = StringHelper::strCaseReverse($str2 ?? ''); + $str1 = StringHelper::convertToString($str1); + $str2 = StringHelper::convertToString($str2); + $inversedStr1 = StringHelper::strCaseReverse($str1); + $inversedStr2 = StringHelper::strCaseReverse($str2); return strcmp($inversedStr1, $inversedStr2); } @@ -28,12 +30,15 @@ class BinaryComparison /** * PHP8.1 deprecates passing null to strcmp. * - * @param null|string $str1 First string value for the comparison - * @param null|string $str2 Second string value for the comparison + * @param mixed $str1 First string value for the comparison, expect ?string + * @param mixed $str2 Second string value for the comparison, expect ?string */ - private static function strcmpAllowNull(?string $str1, ?string $str2): int + private static function strcmpAllowNull(mixed $str1, mixed $str2): int { - return strcmp($str1 ?? '', $str2 ?? ''); + $str1 = StringHelper::convertToString($str1); + $str2 = StringHelper::convertToString($str2); + + return strcmp($str1, $str2); } public static function compare(mixed $operand1, mixed $operand2, string $operator): bool diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php index 28b4645..abdd4c8 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php @@ -15,15 +15,16 @@ use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\DefinedName; use PhpOffice\PhpSpreadsheet\NamedRange; use PhpOffice\PhpSpreadsheet\ReferenceHelper; -use PhpOffice\PhpSpreadsheet\Shared; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use ReflectionClassConstant; use ReflectionMethod; use ReflectionParameter; use Throwable; +use TypeError; -class Calculation +class Calculation extends CalculationLocale { /** Constants */ /** Regular Expressions */ @@ -34,9 +35,7 @@ class Calculation // Opening bracket const CALCULATION_REGEXP_OPENBRACE = '\('; // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it) - const CALCULATION_REGEXP_FUNCTION = '@?(?:_xlfn\.)?(?:_xlws\.)?([\p{L}][\p{L}\p{N}\.]*)[\s]*\('; - // Strip xlfn and xlws prefixes from function name - const CALCULATION_REGEXP_STRIP_XLFN_XLWS = '/(_xlfn[.])?(_xlws[.])?(?=[\p{L}][\p{L}\p{N}\.]*[\s]*[(])/'; + const CALCULATION_REGEXP_FUNCTION = '@?(?:_xlfn\.)?(?:_xlws\.)?((?:__xludf\.)?[\p{L}][\p{L}\p{N}\.]*)[\s]*\('; // Cell reference (cell or range of cells, with or without a sheet reference) const CALCULATION_REGEXP_CELLREF = '((([^\s,!&%^\/\*\+<>=:`-]*)|(\'(?:[^\']|\'[^!])+?\')|(\"(?:[^\"]|\"[^!])+?\"))!)?\$?\b([a-z]{1,3})\$?(\d{1,7})(?![\w.])'; // Used only to detect spill operator # @@ -61,12 +60,6 @@ class Calculation const RETURN_ARRAY_AS_VALUE = 'value'; const RETURN_ARRAY_AS_ARRAY = 'array'; - const FORMULA_OPEN_FUNCTION_BRACE = '('; - const FORMULA_CLOSE_FUNCTION_BRACE = ')'; - const FORMULA_OPEN_MATRIX_BRACE = '{'; - const FORMULA_CLOSE_MATRIX_BRACE = '}'; - const FORMULA_STRING_QUOTE = '"'; - /** Preferable to use instance variable instanceArrayReturnType rather than this static property. */ private static string $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; @@ -85,6 +78,8 @@ class Calculation /** * Calculation cache. + * + * @var mixed[] */ private array $calculationCache = []; @@ -138,6 +133,7 @@ class Calculation */ private CyclicReferenceStack $cyclicReferenceStack; + /** @var mixed[] */ private array $cellStack = []; /** @@ -154,51 +150,11 @@ class Calculation */ public int $cyclicFormulaCount = 1; - /** - * The current locale setting. - */ - private static string $localeLanguage = 'en_us'; // US English (default locale) - - /** - * List of available locale settings - * Note that this is read for the locale subdirectory only when requested. - * - * @var string[] - */ - private static array $validLocaleLanguages = [ - 'en', // English (default language) - ]; - - /** - * Locale-specific argument separator for function arguments. - */ - private static string $localeArgumentSeparator = ','; - - private static array $localeFunctions = []; - - /** - * Locale-specific translations for Excel constants (True, False and Null). - * - * @var array - */ - private static array $localeBoolean = [ - 'TRUE' => 'TRUE', - 'FALSE' => 'FALSE', - 'NULL' => 'NULL', - ]; - - public static function getLocaleBoolean(string $index): string - { - return self::$localeBoolean[$index]; - } - /** * Excel constant string translations to their PHP equivalents * Constant conversion from text name/value to actual (datatyped) value. - * - * @var array */ - private static array $excelConstants = [ + private const EXCEL_CONSTANTS = [ 'TRUE' => true, 'FALSE' => false, 'NULL' => null, @@ -206,2668 +162,18 @@ class Calculation public static function keyInExcelConstants(string $key): bool { - return array_key_exists($key, self::$excelConstants); + return array_key_exists($key, self::EXCEL_CONSTANTS); } public static function getExcelConstants(string $key): bool|null { - return self::$excelConstants[$key]; + return self::EXCEL_CONSTANTS[$key]; } - /** - * Array of functions usable on Spreadsheet. - * In theory, this could be const rather than static; - * however, Phpstan breaks trying to analyze it when attempted. - */ - private static array $phpSpreadsheetFunctions = [ - 'ABS' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Absolute::class, 'evaluate'], - 'argumentCount' => '1', - ], - 'ACCRINT' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\AccruedInterest::class, 'periodic'], - 'argumentCount' => '4-8', - ], - 'ACCRINTM' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\AccruedInterest::class, 'atMaturity'], - 'argumentCount' => '3-5', - ], - 'ACOS' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cosine::class, 'acos'], - 'argumentCount' => '1', - ], - 'ACOSH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cosine::class, 'acosh'], - 'argumentCount' => '1', - ], - 'ACOT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cotangent::class, 'acot'], - 'argumentCount' => '1', - ], - 'ACOTH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cotangent::class, 'acoth'], - 'argumentCount' => '1', - ], - 'ADDRESS' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Address::class, 'cell'], - 'argumentCount' => '2-5', - ], - 'AGGREGATE' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3+', - ], - 'AMORDEGRC' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Amortization::class, 'AMORDEGRC'], - 'argumentCount' => '6,7', - ], - 'AMORLINC' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Amortization::class, 'AMORLINC'], - 'argumentCount' => '6,7', - ], - 'ANCHORARRAY' => [ - 'category' => Category::CATEGORY_MICROSOFT_INTERNAL, - 'functionCall' => [Internal\ExcelArrayPseudoFunctions::class, 'anchorArray'], - 'argumentCount' => '1', - 'passCellReference' => true, - 'passByReference' => [true], - ], - 'AND' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Operations::class, 'logicalAnd'], - 'argumentCount' => '1+', - ], - 'ARABIC' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Arabic::class, 'evaluate'], - 'argumentCount' => '1', - ], - 'AREAS' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1', - ], - 'ARRAYTOTEXT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Text::class, 'fromArray'], - 'argumentCount' => '1,2', - ], - 'ASC' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1', - ], - 'ASIN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Sine::class, 'asin'], - 'argumentCount' => '1', - ], - 'ASINH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Sine::class, 'asinh'], - 'argumentCount' => '1', - ], - 'ATAN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Tangent::class, 'atan'], - 'argumentCount' => '1', - ], - 'ATAN2' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Tangent::class, 'atan2'], - 'argumentCount' => '2', - ], - 'ATANH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Tangent::class, 'atanh'], - 'argumentCount' => '1', - ], - 'AVEDEV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Averages::class, 'averageDeviations'], - 'argumentCount' => '1+', - ], - 'AVERAGE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Averages::class, 'average'], - 'argumentCount' => '1+', - ], - 'AVERAGEA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Averages::class, 'averageA'], - 'argumentCount' => '1+', - ], - 'AVERAGEIF' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'AVERAGEIF'], - 'argumentCount' => '2,3', - ], - 'AVERAGEIFS' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'AVERAGEIFS'], - 'argumentCount' => '3+', - ], - 'BAHTTEXT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1', - ], - 'BASE' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Base::class, 'evaluate'], - 'argumentCount' => '2,3', - ], - 'BESSELI' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BesselI::class, 'BESSELI'], - 'argumentCount' => '2', - ], - 'BESSELJ' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BesselJ::class, 'BESSELJ'], - 'argumentCount' => '2', - ], - 'BESSELK' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BesselK::class, 'BESSELK'], - 'argumentCount' => '2', - ], - 'BESSELY' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BesselY::class, 'BESSELY'], - 'argumentCount' => '2', - ], - 'BETADIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Beta::class, 'distribution'], - 'argumentCount' => '3-5', - ], - 'BETA.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '4-6', - ], - 'BETAINV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Beta::class, 'inverse'], - 'argumentCount' => '3-5', - ], - 'BETA.INV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Beta::class, 'inverse'], - 'argumentCount' => '3-5', - ], - 'BIN2DEC' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertBinary::class, 'toDecimal'], - 'argumentCount' => '1', - ], - 'BIN2HEX' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertBinary::class, 'toHex'], - 'argumentCount' => '1,2', - ], - 'BIN2OCT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertBinary::class, 'toOctal'], - 'argumentCount' => '1,2', - ], - 'BINOMDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Binomial::class, 'distribution'], - 'argumentCount' => '4', - ], - 'BINOM.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Binomial::class, 'distribution'], - 'argumentCount' => '4', - ], - 'BINOM.DIST.RANGE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Binomial::class, 'range'], - 'argumentCount' => '3,4', - ], - 'BINOM.INV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Binomial::class, 'inverse'], - 'argumentCount' => '3', - ], - 'BITAND' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITAND'], - 'argumentCount' => '2', - ], - 'BITOR' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITOR'], - 'argumentCount' => '2', - ], - 'BITXOR' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITXOR'], - 'argumentCount' => '2', - ], - 'BITLSHIFT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITLSHIFT'], - 'argumentCount' => '2', - ], - 'BITRSHIFT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITRSHIFT'], - 'argumentCount' => '2', - ], - 'BYCOL' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '*', - ], - 'BYROW' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '*', - ], - 'CEILING' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Ceiling::class, 'ceiling'], - 'argumentCount' => '1-2', // 2 for Excel, 1-2 for Ods/Gnumeric - ], - 'CEILING.MATH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Ceiling::class, 'math'], - 'argumentCount' => '1-3', - ], - 'CEILING.PRECISE' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Ceiling::class, 'precise'], - 'argumentCount' => '1,2', - ], - 'CELL' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1,2', - ], - 'CHAR' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\CharacterConvert::class, 'character'], - 'argumentCount' => '1', - ], - 'CHIDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\ChiSquared::class, 'distributionRightTail'], - 'argumentCount' => '2', - ], - 'CHISQ.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\ChiSquared::class, 'distributionLeftTail'], - 'argumentCount' => '3', - ], - 'CHISQ.DIST.RT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\ChiSquared::class, 'distributionRightTail'], - 'argumentCount' => '2', - ], - 'CHIINV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\ChiSquared::class, 'inverseRightTail'], - 'argumentCount' => '2', - ], - 'CHISQ.INV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\ChiSquared::class, 'inverseLeftTail'], - 'argumentCount' => '2', - ], - 'CHISQ.INV.RT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\ChiSquared::class, 'inverseRightTail'], - 'argumentCount' => '2', - ], - 'CHITEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\ChiSquared::class, 'test'], - 'argumentCount' => '2', - ], - 'CHISQ.TEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\ChiSquared::class, 'test'], - 'argumentCount' => '2', - ], - 'CHOOSE' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Selection::class, 'CHOOSE'], - 'argumentCount' => '2+', - ], - 'CHOOSECOLS' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\ChooseRowsEtc::class, 'chooseCols'], - 'argumentCount' => '2+', - ], - 'CHOOSEROWS' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\ChooseRowsEtc::class, 'chooseRows'], - 'argumentCount' => '2+', - ], - 'CLEAN' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Trim::class, 'nonPrintable'], - 'argumentCount' => '1', - ], - 'CODE' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\CharacterConvert::class, 'code'], - 'argumentCount' => '1', - ], - 'COLUMN' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\RowColumnInformation::class, 'COLUMN'], - 'argumentCount' => '-1', - 'passCellReference' => true, - 'passByReference' => [true], - ], - 'COLUMNS' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\RowColumnInformation::class, 'COLUMNS'], - 'argumentCount' => '1', - ], - 'COMBIN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Combinations::class, 'withoutRepetition'], - 'argumentCount' => '2', - ], - 'COMBINA' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Combinations::class, 'withRepetition'], - 'argumentCount' => '2', - ], - 'COMPLEX' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Complex::class, 'COMPLEX'], - 'argumentCount' => '2,3', - ], - 'CONCAT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Concatenate::class, 'CONCATENATE'], - 'argumentCount' => '1+', - ], - 'CONCATENATE' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Concatenate::class, 'actualCONCATENATE'], - 'argumentCount' => '1+', - ], - 'CONFIDENCE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Confidence::class, 'CONFIDENCE'], - 'argumentCount' => '3', - ], - 'CONFIDENCE.NORM' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Confidence::class, 'CONFIDENCE'], - 'argumentCount' => '3', - ], - 'CONFIDENCE.T' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3', - ], - 'CONVERT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertUOM::class, 'CONVERT'], - 'argumentCount' => '3', - ], - 'CORREL' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'CORREL'], - 'argumentCount' => '2', - ], - 'COS' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cosine::class, 'cos'], - 'argumentCount' => '1', - ], - 'COSH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cosine::class, 'cosh'], - 'argumentCount' => '1', - ], - 'COT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cotangent::class, 'cot'], - 'argumentCount' => '1', - ], - 'COTH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cotangent::class, 'coth'], - 'argumentCount' => '1', - ], - 'COUNT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Counts::class, 'COUNT'], - 'argumentCount' => '1+', - ], - 'COUNTA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Counts::class, 'COUNTA'], - 'argumentCount' => '1+', - ], - 'COUNTBLANK' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Counts::class, 'COUNTBLANK'], - 'argumentCount' => '1', - ], - 'COUNTIF' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'COUNTIF'], - 'argumentCount' => '2', - ], - 'COUNTIFS' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'COUNTIFS'], - 'argumentCount' => '2+', - ], - 'COUPDAYBS' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPDAYBS'], - 'argumentCount' => '3,4', - ], - 'COUPDAYS' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPDAYS'], - 'argumentCount' => '3,4', - ], - 'COUPDAYSNC' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPDAYSNC'], - 'argumentCount' => '3,4', - ], - 'COUPNCD' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPNCD'], - 'argumentCount' => '3,4', - ], - 'COUPNUM' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPNUM'], - 'argumentCount' => '3,4', - ], - 'COUPPCD' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPPCD'], - 'argumentCount' => '3,4', - ], - 'COVAR' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'COVAR'], - 'argumentCount' => '2', - ], - 'COVARIANCE.P' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'COVAR'], - 'argumentCount' => '2', - ], - 'COVARIANCE.S' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'CRITBINOM' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Binomial::class, 'inverse'], - 'argumentCount' => '3', - ], - 'CSC' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cosecant::class, 'csc'], - 'argumentCount' => '1', - ], - 'CSCH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Cosecant::class, 'csch'], - 'argumentCount' => '1', - ], - 'CUBEKPIMEMBER' => [ - 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'CUBEMEMBER' => [ - 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'CUBEMEMBERPROPERTY' => [ - 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'CUBERANKEDMEMBER' => [ - 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'CUBESET' => [ - 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'CUBESETCOUNT' => [ - 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'CUBEVALUE' => [ - 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'CUMIPMT' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic\Cumulative::class, 'interest'], - 'argumentCount' => '6', - ], - 'CUMPRINC' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic\Cumulative::class, 'principal'], - 'argumentCount' => '6', - ], - 'DATE' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Date::class, 'fromYMD'], - 'argumentCount' => '3', - ], - 'DATEDIF' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Difference::class, 'interval'], - 'argumentCount' => '2,3', - ], - 'DATESTRING' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'DATEVALUE' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\DateValue::class, 'fromString'], - 'argumentCount' => '1', - ], - 'DAVERAGE' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DAverage::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DAY' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\DateParts::class, 'day'], - 'argumentCount' => '1', - ], - 'DAYS' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Days::class, 'between'], - 'argumentCount' => '2', - ], - 'DAYS360' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Days360::class, 'between'], - 'argumentCount' => '2,3', - ], - 'DB' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Depreciation::class, 'DB'], - 'argumentCount' => '4,5', - ], - 'DBCS' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1', - ], - 'DCOUNT' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DCount::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DCOUNTA' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DCountA::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DDB' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Depreciation::class, 'DDB'], - 'argumentCount' => '4,5', - ], - 'DEC2BIN' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertDecimal::class, 'toBinary'], - 'argumentCount' => '1,2', - ], - 'DEC2HEX' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertDecimal::class, 'toHex'], - 'argumentCount' => '1,2', - ], - 'DEC2OCT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertDecimal::class, 'toOctal'], - 'argumentCount' => '1,2', - ], - 'DECIMAL' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'DEGREES' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Angle::class, 'toDegrees'], - 'argumentCount' => '1', - ], - 'DELTA' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Compare::class, 'DELTA'], - 'argumentCount' => '1,2', - ], - 'DEVSQ' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Deviations::class, 'sumSquares'], - 'argumentCount' => '1+', - ], - 'DGET' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DGet::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DISC' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\Rates::class, 'discount'], - 'argumentCount' => '4,5', - ], - 'DMAX' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DMax::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DMIN' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DMin::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DOLLAR' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'DOLLAR'], - 'argumentCount' => '1,2', - ], - 'DOLLARDE' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Dollar::class, 'decimal'], - 'argumentCount' => '2', - ], - 'DOLLARFR' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Dollar::class, 'fractional'], - 'argumentCount' => '2', - ], - 'DPRODUCT' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DProduct::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DROP' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\ChooseRowsEtc::class, 'drop'], - 'argumentCount' => '2-3', - ], - 'DSTDEV' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DStDev::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DSTDEVP' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DStDevP::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DSUM' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DSum::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DURATION' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '5,6', - ], - 'DVAR' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DVar::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'DVARP' => [ - 'category' => Category::CATEGORY_DATABASE, - 'functionCall' => [Database\DVarP::class, 'evaluate'], - 'argumentCount' => '3', - ], - 'ECMA.CEILING' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1,2', - ], - 'EDATE' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Month::class, 'adjust'], - 'argumentCount' => '2', - ], - 'EFFECT' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\InterestRate::class, 'effective'], - 'argumentCount' => '2', - ], - 'ENCODEURL' => [ - 'category' => Category::CATEGORY_WEB, - 'functionCall' => [Web\Service::class, 'urlEncode'], - 'argumentCount' => '1', - ], - 'EOMONTH' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Month::class, 'lastDay'], - 'argumentCount' => '2', - ], - 'ERF' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Erf::class, 'ERF'], - 'argumentCount' => '1,2', - ], - 'ERF.PRECISE' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Erf::class, 'ERFPRECISE'], - 'argumentCount' => '1', - ], - 'ERFC' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ErfC::class, 'ERFC'], - 'argumentCount' => '1', - ], - 'ERFC.PRECISE' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ErfC::class, 'ERFC'], - 'argumentCount' => '1', - ], - 'ERROR.TYPE' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [ExcelError::class, 'type'], - 'argumentCount' => '1', - ], - 'EVEN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Round::class, 'even'], - 'argumentCount' => '1', - ], - 'EXACT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Text::class, 'exact'], - 'argumentCount' => '2', - ], - 'EXP' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Exp::class, 'evaluate'], - 'argumentCount' => '1', - ], - 'EXPAND' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\ChooseRowsEtc::class, 'expand'], - 'argumentCount' => '2-4', - ], - 'EXPONDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Exponential::class, 'distribution'], - 'argumentCount' => '3', - ], - 'EXPON.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Exponential::class, 'distribution'], - 'argumentCount' => '3', - ], - 'FACT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Factorial::class, 'fact'], - 'argumentCount' => '1', - ], - 'FACTDOUBLE' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Factorial::class, 'factDouble'], - 'argumentCount' => '1', - ], - 'FALSE' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Boolean::class, 'FALSE'], - 'argumentCount' => '0', - ], - 'FDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3', - ], - 'F.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\F::class, 'distribution'], - 'argumentCount' => '4', - ], - 'F.DIST.RT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3', - ], - 'FILTER' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Filter::class, 'filter'], - 'argumentCount' => '2-3', - ], - 'FILTERXML' => [ - 'category' => Category::CATEGORY_WEB, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'FIND' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Search::class, 'sensitive'], - 'argumentCount' => '2,3', - ], - 'FINDB' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Search::class, 'sensitive'], - 'argumentCount' => '2,3', - ], - 'FINV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3', - ], - 'F.INV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3', - ], - 'F.INV.RT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3', - ], - 'FISHER' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Fisher::class, 'distribution'], - 'argumentCount' => '1', - ], - 'FISHERINV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Fisher::class, 'inverse'], - 'argumentCount' => '1', - ], - 'FIXED' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'FIXEDFORMAT'], - 'argumentCount' => '1-3', - ], - 'FLOOR' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Floor::class, 'floor'], - 'argumentCount' => '1-2', // Excel requries 2, Ods/Gnumeric 1-2 - ], - 'FLOOR.MATH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Floor::class, 'math'], - 'argumentCount' => '1-3', - ], - 'FLOOR.PRECISE' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Floor::class, 'precise'], - 'argumentCount' => '1-2', - ], - 'FORECAST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'FORECAST'], - 'argumentCount' => '3', - ], - 'FORECAST.ETS' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3-6', - ], - 'FORECAST.ETS.CONFINT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3-6', - ], - 'FORECAST.ETS.SEASONALITY' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2-4', - ], - 'FORECAST.ETS.STAT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3-6', - ], - 'FORECAST.LINEAR' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'FORECAST'], - 'argumentCount' => '3', - ], - 'FORMULATEXT' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Formula::class, 'text'], - 'argumentCount' => '1', - 'passCellReference' => true, - 'passByReference' => [true], - ], - 'FREQUENCY' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'FTEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'F.TEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'FV' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic::class, 'futureValue'], - 'argumentCount' => '3-5', - ], - 'FVSCHEDULE' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Single::class, 'futureValue'], - 'argumentCount' => '2', - ], - 'GAMMA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Gamma::class, 'gamma'], - 'argumentCount' => '1', - ], - 'GAMMADIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Gamma::class, 'distribution'], - 'argumentCount' => '4', - ], - 'GAMMA.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Gamma::class, 'distribution'], - 'argumentCount' => '4', - ], - 'GAMMAINV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Gamma::class, 'inverse'], - 'argumentCount' => '3', - ], - 'GAMMA.INV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Gamma::class, 'inverse'], - 'argumentCount' => '3', - ], - 'GAMMALN' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Gamma::class, 'ln'], - 'argumentCount' => '1', - ], - 'GAMMALN.PRECISE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Gamma::class, 'ln'], - 'argumentCount' => '1', - ], - 'GAUSS' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StandardNormal::class, 'gauss'], - 'argumentCount' => '1', - ], - 'GCD' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Gcd::class, 'evaluate'], - 'argumentCount' => '1+', - ], - 'GEOMEAN' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Averages\Mean::class, 'geometric'], - 'argumentCount' => '1+', - ], - 'GESTEP' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Compare::class, 'GESTEP'], - 'argumentCount' => '1,2', - ], - 'GETPIVOTDATA' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2+', - ], - 'GROUPBY' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3-7', - ], - 'GROWTH' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'GROWTH'], - 'argumentCount' => '1-4', - ], - 'HARMEAN' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Averages\Mean::class, 'harmonic'], - 'argumentCount' => '1+', - ], - 'HEX2BIN' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertHex::class, 'toBinary'], - 'argumentCount' => '1,2', - ], - 'HEX2DEC' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertHex::class, 'toDecimal'], - 'argumentCount' => '1', - ], - 'HEX2OCT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertHex::class, 'toOctal'], - 'argumentCount' => '1,2', - ], - 'HLOOKUP' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\HLookup::class, 'lookup'], - 'argumentCount' => '3,4', - ], - 'HOUR' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\TimeParts::class, 'hour'], - 'argumentCount' => '1', - ], - 'HSTACK' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1+', - ], - 'HYPERLINK' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Hyperlink::class, 'set'], - 'argumentCount' => '1,2', - 'passCellReference' => true, - ], - 'HYPGEOMDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\HyperGeometric::class, 'distribution'], - 'argumentCount' => '4', - ], - 'HYPGEOM.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '5', - ], - 'IF' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'statementIf'], - 'argumentCount' => '2-3', - ], - 'IFERROR' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'IFERROR'], - 'argumentCount' => '2', - ], - 'IFNA' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'IFNA'], - 'argumentCount' => '2', - ], - 'IFS' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'IFS'], - 'argumentCount' => '2+', - ], - 'IMABS' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMABS'], - 'argumentCount' => '1', - ], - 'IMAGINARY' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Complex::class, 'IMAGINARY'], - 'argumentCount' => '1', - ], - 'IMARGUMENT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMARGUMENT'], - 'argumentCount' => '1', - ], - 'IMCONJUGATE' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCONJUGATE'], - 'argumentCount' => '1', - ], - 'IMCOS' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCOS'], - 'argumentCount' => '1', - ], - 'IMCOSH' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCOSH'], - 'argumentCount' => '1', - ], - 'IMCOT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCOT'], - 'argumentCount' => '1', - ], - 'IMCSC' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCSC'], - 'argumentCount' => '1', - ], - 'IMCSCH' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCSCH'], - 'argumentCount' => '1', - ], - 'IMDIV' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexOperations::class, 'IMDIV'], - 'argumentCount' => '2', - ], - 'IMEXP' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMEXP'], - 'argumentCount' => '1', - ], - 'IMLN' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMLN'], - 'argumentCount' => '1', - ], - 'IMLOG10' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMLOG10'], - 'argumentCount' => '1', - ], - 'IMLOG2' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMLOG2'], - 'argumentCount' => '1', - ], - 'IMPOWER' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMPOWER'], - 'argumentCount' => '2', - ], - 'IMPRODUCT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexOperations::class, 'IMPRODUCT'], - 'argumentCount' => '1+', - ], - 'IMREAL' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Complex::class, 'IMREAL'], - 'argumentCount' => '1', - ], - 'IMSEC' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSEC'], - 'argumentCount' => '1', - ], - 'IMSECH' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSECH'], - 'argumentCount' => '1', - ], - 'IMSIN' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSIN'], - 'argumentCount' => '1', - ], - 'IMSINH' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSINH'], - 'argumentCount' => '1', - ], - 'IMSQRT' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSQRT'], - 'argumentCount' => '1', - ], - 'IMSUB' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexOperations::class, 'IMSUB'], - 'argumentCount' => '2', - ], - 'IMSUM' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexOperations::class, 'IMSUM'], - 'argumentCount' => '1+', - ], - 'IMTAN' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMTAN'], - 'argumentCount' => '1', - ], - 'INDEX' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Matrix::class, 'index'], - 'argumentCount' => '2-4', - ], - 'INDIRECT' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Indirect::class, 'INDIRECT'], - 'argumentCount' => '1,2', - 'passCellReference' => true, - ], - 'INFO' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1', - ], - 'INT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\IntClass::class, 'evaluate'], - 'argumentCount' => '1', - ], - 'INTERCEPT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'INTERCEPT'], - 'argumentCount' => '2', - ], - 'INTRATE' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\Rates::class, 'interest'], - 'argumentCount' => '4,5', - ], - 'IPMT' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic\Interest::class, 'payment'], - 'argumentCount' => '4-6', - ], - 'IRR' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Variable\Periodic::class, 'rate'], - 'argumentCount' => '1,2', - ], - 'ISBLANK' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isBlank'], - 'argumentCount' => '1', - ], - 'ISERR' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\ErrorValue::class, 'isErr'], - 'argumentCount' => '1', - ], - 'ISERROR' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\ErrorValue::class, 'isError'], - 'argumentCount' => '1', - ], - 'ISEVEN' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isEven'], - 'argumentCount' => '1', - ], - 'ISFORMULA' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isFormula'], - 'argumentCount' => '1', - 'passCellReference' => true, - 'passByReference' => [true], - ], - 'ISLOGICAL' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isLogical'], - 'argumentCount' => '1', - ], - 'ISNA' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\ErrorValue::class, 'isNa'], - 'argumentCount' => '1', - ], - 'ISNONTEXT' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isNonText'], - 'argumentCount' => '1', - ], - 'ISNUMBER' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isNumber'], - 'argumentCount' => '1', - ], - 'ISO.CEILING' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1,2', - ], - 'ISODD' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isOdd'], - 'argumentCount' => '1', - ], - 'ISOMITTED' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '*', - ], - 'ISOWEEKNUM' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Week::class, 'isoWeekNumber'], - 'argumentCount' => '1', - ], - 'ISPMT' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic\Interest::class, 'schedulePayment'], - 'argumentCount' => '4', - ], - 'ISREF' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isRef'], - 'argumentCount' => '1', - 'passCellReference' => true, - 'passByReference' => [true], - ], - 'ISTEXT' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isText'], - 'argumentCount' => '1', - ], - 'ISTHAIDIGIT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'JIS' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1', - ], - 'KURT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Deviations::class, 'kurtosis'], - 'argumentCount' => '1+', - ], - 'LAMBDA' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '*', - ], - 'LARGE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Size::class, 'large'], - 'argumentCount' => '2', - ], - 'LCM' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Lcm::class, 'evaluate'], - 'argumentCount' => '1+', - ], - 'LEFT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Extract::class, 'left'], - 'argumentCount' => '1,2', - ], - 'LEFTB' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Extract::class, 'left'], - 'argumentCount' => '1,2', - ], - 'LEN' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Text::class, 'length'], - 'argumentCount' => '1', - ], - 'LENB' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Text::class, 'length'], - 'argumentCount' => '1', - ], - 'LET' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '*', - ], - 'LINEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'LINEST'], - 'argumentCount' => '1-4', - ], - 'LN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Logarithms::class, 'natural'], - 'argumentCount' => '1', - ], - 'LOG' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Logarithms::class, 'withBase'], - 'argumentCount' => '1,2', - ], - 'LOG10' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Logarithms::class, 'base10'], - 'argumentCount' => '1', - ], - 'LOGEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'LOGEST'], - 'argumentCount' => '1-4', - ], - 'LOGINV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\LogNormal::class, 'inverse'], - 'argumentCount' => '3', - ], - 'LOGNORMDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\LogNormal::class, 'cumulative'], - 'argumentCount' => '3', - ], - 'LOGNORM.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\LogNormal::class, 'distribution'], - 'argumentCount' => '4', - ], - 'LOGNORM.INV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\LogNormal::class, 'inverse'], - 'argumentCount' => '3', - ], - 'LOOKUP' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Lookup::class, 'lookup'], - 'argumentCount' => '2,3', - ], - 'LOWER' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\CaseConvert::class, 'lower'], - 'argumentCount' => '1', - ], - 'MAKEARRAY' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '*', - ], - 'MAP' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '*', - ], - 'MATCH' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\ExcelMatch::class, 'MATCH'], - 'argumentCount' => '2,3', - ], - 'MAX' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Maximum::class, 'max'], - 'argumentCount' => '1+', - ], - 'MAXA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Maximum::class, 'maxA'], - 'argumentCount' => '1+', - ], - 'MAXIFS' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'MAXIFS'], - 'argumentCount' => '3+', - ], - 'MDETERM' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\MatrixFunctions::class, 'determinant'], - 'argumentCount' => '1', - ], - 'MDURATION' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '5,6', - ], - 'MEDIAN' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Averages::class, 'median'], - 'argumentCount' => '1+', - ], - 'MEDIANIF' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2+', - ], - 'MID' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Extract::class, 'mid'], - 'argumentCount' => '3', - ], - 'MIDB' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Extract::class, 'mid'], - 'argumentCount' => '3', - ], - 'MIN' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Minimum::class, 'min'], - 'argumentCount' => '1+', - ], - 'MINA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Minimum::class, 'minA'], - 'argumentCount' => '1+', - ], - 'MINIFS' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'MINIFS'], - 'argumentCount' => '3+', - ], - 'MINUTE' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\TimeParts::class, 'minute'], - 'argumentCount' => '1', - ], - 'MINVERSE' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\MatrixFunctions::class, 'inverse'], - 'argumentCount' => '1', - ], - 'MIRR' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Variable\Periodic::class, 'modifiedRate'], - 'argumentCount' => '3', - ], - 'MMULT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\MatrixFunctions::class, 'multiply'], - 'argumentCount' => '2', - ], - 'MOD' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Operations::class, 'mod'], - 'argumentCount' => '2', - ], - 'MODE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Averages::class, 'mode'], - 'argumentCount' => '1+', - ], - 'MODE.MULT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1+', - ], - 'MODE.SNGL' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Averages::class, 'mode'], - 'argumentCount' => '1+', - ], - 'MONTH' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\DateParts::class, 'month'], - 'argumentCount' => '1', - ], - 'MROUND' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Round::class, 'multiple'], - 'argumentCount' => '2', - ], - 'MULTINOMIAL' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Factorial::class, 'multinomial'], - 'argumentCount' => '1+', - ], - 'MUNIT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\MatrixFunctions::class, 'identity'], - 'argumentCount' => '1', - ], - 'N' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'asNumber'], - 'argumentCount' => '1', - ], - 'NA' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [ExcelError::class, 'NA'], - 'argumentCount' => '0', - ], - 'NEGBINOMDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Binomial::class, 'negative'], - 'argumentCount' => '3', - ], - 'NEGBINOM.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '4', - ], - 'NETWORKDAYS' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\NetworkDays::class, 'count'], - 'argumentCount' => '2-3', - ], - 'NETWORKDAYS.INTL' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2-4', - ], - 'NOMINAL' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\InterestRate::class, 'nominal'], - 'argumentCount' => '2', - ], - 'NORMDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Normal::class, 'distribution'], - 'argumentCount' => '4', - ], - 'NORM.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Normal::class, 'distribution'], - 'argumentCount' => '4', - ], - 'NORMINV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Normal::class, 'inverse'], - 'argumentCount' => '3', - ], - 'NORM.INV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Normal::class, 'inverse'], - 'argumentCount' => '3', - ], - 'NORMSDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StandardNormal::class, 'cumulative'], - 'argumentCount' => '1', - ], - 'NORM.S.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StandardNormal::class, 'distribution'], - 'argumentCount' => '1,2', - ], - 'NORMSINV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StandardNormal::class, 'inverse'], - 'argumentCount' => '1', - ], - 'NORM.S.INV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StandardNormal::class, 'inverse'], - 'argumentCount' => '1', - ], - 'NOT' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Operations::class, 'NOT'], - 'argumentCount' => '1', - ], - 'NOW' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Current::class, 'now'], - 'argumentCount' => '0', - ], - 'NPER' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic::class, 'periods'], - 'argumentCount' => '3-5', - ], - 'NPV' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Variable\Periodic::class, 'presentValue'], - 'argumentCount' => '2+', - ], - 'NUMBERSTRING' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'NUMBERVALUE' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'NUMBERVALUE'], - 'argumentCount' => '1+', - ], - 'OCT2BIN' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertOctal::class, 'toBinary'], - 'argumentCount' => '1,2', - ], - 'OCT2DEC' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertOctal::class, 'toDecimal'], - 'argumentCount' => '1', - ], - 'OCT2HEX' => [ - 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertOctal::class, 'toHex'], - 'argumentCount' => '1,2', - ], - 'ODD' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Round::class, 'odd'], - 'argumentCount' => '1', - ], - 'ODDFPRICE' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '8,9', - ], - 'ODDFYIELD' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '8,9', - ], - 'ODDLPRICE' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '7,8', - ], - 'ODDLYIELD' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '7,8', - ], - 'OFFSET' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Offset::class, 'OFFSET'], - 'argumentCount' => '3-5', - 'passCellReference' => true, - 'passByReference' => [true], - ], - 'OR' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Operations::class, 'logicalOr'], - 'argumentCount' => '1+', - ], - 'PDURATION' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Single::class, 'periods'], - 'argumentCount' => '3', - ], - 'PEARSON' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'CORREL'], - 'argumentCount' => '2', - ], - 'PERCENTILE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'PERCENTILE'], - 'argumentCount' => '2', - ], - 'PERCENTILE.EXC' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'PERCENTILE.INC' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'PERCENTILE'], - 'argumentCount' => '2', - ], - 'PERCENTRANK' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'PERCENTRANK'], - 'argumentCount' => '2,3', - ], - 'PERCENTRANK.EXC' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2,3', - ], - 'PERCENTRANK.INC' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'PERCENTRANK'], - 'argumentCount' => '2,3', - ], - 'PERMUT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Permutations::class, 'PERMUT'], - 'argumentCount' => '2', - ], - 'PERMUTATIONA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Permutations::class, 'PERMUTATIONA'], - 'argumentCount' => '2', - ], - 'PHONETIC' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1', - ], - 'PHI' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1', - ], - 'PI' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'pi', - 'argumentCount' => '0', - ], - 'PMT' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic\Payments::class, 'annuity'], - 'argumentCount' => '3-5', - ], - 'POISSON' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Poisson::class, 'distribution'], - 'argumentCount' => '3', - ], - 'POISSON.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Poisson::class, 'distribution'], - 'argumentCount' => '3', - ], - 'POWER' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Operations::class, 'power'], - 'argumentCount' => '2', - ], - 'PPMT' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic\Payments::class, 'interestPayment'], - 'argumentCount' => '4-6', - ], - 'PRICE' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\Price::class, 'price'], - 'argumentCount' => '6,7', - ], - 'PRICEDISC' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\Price::class, 'priceDiscounted'], - 'argumentCount' => '4,5', - ], - 'PRICEMAT' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\Price::class, 'priceAtMaturity'], - 'argumentCount' => '5,6', - ], - 'PROB' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3,4', - ], - 'PRODUCT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Operations::class, 'product'], - 'argumentCount' => '1+', - ], - 'PROPER' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\CaseConvert::class, 'proper'], - 'argumentCount' => '1', - ], - 'PV' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic::class, 'presentValue'], - 'argumentCount' => '3-5', - ], - 'QUARTILE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'QUARTILE'], - 'argumentCount' => '2', - ], - 'QUARTILE.EXC' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'QUARTILE.INC' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'QUARTILE'], - 'argumentCount' => '2', - ], - 'QUOTIENT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Operations::class, 'quotient'], - 'argumentCount' => '2', - ], - 'RADIANS' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Angle::class, 'toRadians'], - 'argumentCount' => '1', - ], - 'RAND' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Random::class, 'rand'], - 'argumentCount' => '0', - ], - 'RANDARRAY' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Random::class, 'randArray'], - 'argumentCount' => '0-5', - ], - 'RANDBETWEEN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Random::class, 'randBetween'], - 'argumentCount' => '2', - ], - 'RANK' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'RANK'], - 'argumentCount' => '2,3', - ], - 'RANK.AVG' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2,3', - ], - 'RANK.EQ' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'RANK'], - 'argumentCount' => '2,3', - ], - 'RATE' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Constant\Periodic\Interest::class, 'rate'], - 'argumentCount' => '3-6', - ], - 'RECEIVED' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\Price::class, 'received'], - 'argumentCount' => '4-5', - ], - 'REDUCE' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '*', - ], - 'REPLACE' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Replace::class, 'replace'], - 'argumentCount' => '4', - ], - 'REPLACEB' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Replace::class, 'replace'], - 'argumentCount' => '4', - ], - 'REPT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Concatenate::class, 'builtinREPT'], - 'argumentCount' => '2', - ], - 'RIGHT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Extract::class, 'right'], - 'argumentCount' => '1,2', - ], - 'RIGHTB' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Extract::class, 'right'], - 'argumentCount' => '1,2', - ], - 'ROMAN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Roman::class, 'evaluate'], - 'argumentCount' => '1,2', - ], - 'ROUND' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Round::class, 'round'], - 'argumentCount' => '2', - ], - 'ROUNDBAHTDOWN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'ROUNDBAHTUP' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'ROUNDDOWN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Round::class, 'down'], - 'argumentCount' => '2', - ], - 'ROUNDUP' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Round::class, 'up'], - 'argumentCount' => '2', - ], - 'ROW' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\RowColumnInformation::class, 'ROW'], - 'argumentCount' => '-1', - 'passCellReference' => true, - 'passByReference' => [true], - ], - 'ROWS' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\RowColumnInformation::class, 'ROWS'], - 'argumentCount' => '1', - ], - 'RRI' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Single::class, 'interestRate'], - 'argumentCount' => '3', - ], - 'RSQ' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'RSQ'], - 'argumentCount' => '2', - ], - 'RTD' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1+', - ], - 'SEARCH' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Search::class, 'insensitive'], - 'argumentCount' => '2,3', - ], - 'SCAN' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '*', - ], - 'SEARCHB' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Search::class, 'insensitive'], - 'argumentCount' => '2,3', - ], - 'SEC' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Secant::class, 'sec'], - 'argumentCount' => '1', - ], - 'SECH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Secant::class, 'sech'], - 'argumentCount' => '1', - ], - 'SECOND' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\TimeParts::class, 'second'], - 'argumentCount' => '1', - ], - 'SEQUENCE' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\MatrixFunctions::class, 'sequence'], - 'argumentCount' => '1-4', - ], - 'SERIESSUM' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\SeriesSum::class, 'evaluate'], - 'argumentCount' => '4', - ], - 'SHEET' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '0,1', - ], - 'SHEETS' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '0,1', - ], - 'SIGN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Sign::class, 'evaluate'], - 'argumentCount' => '1', - ], - 'SIN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Sine::class, 'sin'], - 'argumentCount' => '1', - ], - 'SINGLE' => [ - 'category' => Category::CATEGORY_MICROSOFT_INTERNAL, - 'functionCall' => [Internal\ExcelArrayPseudoFunctions::class, 'single'], - 'argumentCount' => '1', - 'passCellReference' => true, - 'passByReference' => [true], - ], - 'SINH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Sine::class, 'sinh'], - 'argumentCount' => '1', - ], - 'SKEW' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Deviations::class, 'skew'], - 'argumentCount' => '1+', - ], - 'SKEW.P' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1+', - ], - 'SLN' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Depreciation::class, 'SLN'], - 'argumentCount' => '3', - ], - 'SLOPE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'SLOPE'], - 'argumentCount' => '2', - ], - 'SMALL' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Size::class, 'small'], - 'argumentCount' => '2', - ], - 'SORT' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Sort::class, 'sort'], - 'argumentCount' => '1-4', - ], - 'SORTBY' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Sort::class, 'sortBy'], - 'argumentCount' => '2+', - ], - 'SQRT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Sqrt::class, 'sqrt'], - 'argumentCount' => '1', - ], - 'SQRTPI' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Sqrt::class, 'pi'], - 'argumentCount' => '1', - ], - 'STANDARDIZE' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Standardize::class, 'execute'], - 'argumentCount' => '3', - ], - 'STDEV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'], - 'argumentCount' => '1+', - ], - 'STDEV.S' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'], - 'argumentCount' => '1+', - ], - 'STDEV.P' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVP'], - 'argumentCount' => '1+', - ], - 'STDEVA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVA'], - 'argumentCount' => '1+', - ], - 'STDEVP' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVP'], - 'argumentCount' => '1+', - ], - 'STDEVPA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVPA'], - 'argumentCount' => '1+', - ], - 'STEYX' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'STEYX'], - 'argumentCount' => '2', - ], - 'SUBSTITUTE' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Replace::class, 'substitute'], - 'argumentCount' => '3,4', - ], - 'SUBTOTAL' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Subtotal::class, 'evaluate'], - 'argumentCount' => '2+', - 'passCellReference' => true, - ], - 'SUM' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Sum::class, 'sumErroringStrings'], - 'argumentCount' => '1+', - ], - 'SUMIF' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Statistical\Conditional::class, 'SUMIF'], - 'argumentCount' => '2,3', - ], - 'SUMIFS' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Statistical\Conditional::class, 'SUMIFS'], - 'argumentCount' => '3+', - ], - 'SUMPRODUCT' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Sum::class, 'product'], - 'argumentCount' => '1+', - ], - 'SUMSQ' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\SumSquares::class, 'sumSquare'], - 'argumentCount' => '1+', - ], - 'SUMX2MY2' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\SumSquares::class, 'sumXSquaredMinusYSquared'], - 'argumentCount' => '2', - ], - 'SUMX2PY2' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\SumSquares::class, 'sumXSquaredPlusYSquared'], - 'argumentCount' => '2', - ], - 'SUMXMY2' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\SumSquares::class, 'sumXMinusYSquared'], - 'argumentCount' => '2', - ], - 'SWITCH' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'statementSwitch'], - 'argumentCount' => '3+', - ], - 'SYD' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Depreciation::class, 'SYD'], - 'argumentCount' => '4', - ], - 'T' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Text::class, 'test'], - 'argumentCount' => '1', - ], - 'TAKE' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\ChooseRowsEtc::class, 'take'], - 'argumentCount' => '2-3', - ], - 'TAN' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Tangent::class, 'tan'], - 'argumentCount' => '1', - ], - 'TANH' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trig\Tangent::class, 'tanh'], - 'argumentCount' => '1', - ], - 'TBILLEQ' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\TreasuryBill::class, 'bondEquivalentYield'], - 'argumentCount' => '3', - ], - 'TBILLPRICE' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\TreasuryBill::class, 'price'], - 'argumentCount' => '3', - ], - 'TBILLYIELD' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\TreasuryBill::class, 'yield'], - 'argumentCount' => '3', - ], - 'TDIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StudentT::class, 'distribution'], - 'argumentCount' => '3', - ], - 'T.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3', - ], - 'T.DIST.2T' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'T.DIST.RT' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'TEXT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'TEXTFORMAT'], - 'argumentCount' => '2', - ], - 'TEXTAFTER' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Extract::class, 'after'], - 'argumentCount' => '2-6', - ], - 'TEXTBEFORE' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Extract::class, 'before'], - 'argumentCount' => '2-6', - ], - 'TEXTJOIN' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Concatenate::class, 'TEXTJOIN'], - 'argumentCount' => '3+', - ], - 'TEXTSPLIT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Text::class, 'split'], - 'argumentCount' => '2-6', - ], - 'THAIDAYOFWEEK' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'THAIDIGIT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'THAIMONTHOFYEAR' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'THAINUMSOUND' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'THAINUMSTRING' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'THAISTRINGLENGTH' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'THAIYEAR' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', - ], - 'TIME' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Time::class, 'fromHMS'], - 'argumentCount' => '3', - ], - 'TIMEVALUE' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\TimeValue::class, 'fromString'], - 'argumentCount' => '1', - ], - 'TINV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StudentT::class, 'inverse'], - 'argumentCount' => '2', - ], - 'T.INV' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StudentT::class, 'inverse'], - 'argumentCount' => '2', - ], - 'T.INV.2T' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', - ], - 'TODAY' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Current::class, 'today'], - 'argumentCount' => '0', - ], - 'TOCOL' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1-3', - ], - 'TOROW' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1-3', - ], - 'TRANSPOSE' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Matrix::class, 'transpose'], - 'argumentCount' => '1', - ], - 'TREND' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'TREND'], - 'argumentCount' => '1-4', - ], - 'TRIM' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Trim::class, 'spaces'], - 'argumentCount' => '1', - ], - 'TRIMMEAN' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Averages\Mean::class, 'trim'], - 'argumentCount' => '2', - ], - 'TRUE' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Boolean::class, 'TRUE'], - 'argumentCount' => '0', - ], - 'TRUNC' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Trunc::class, 'evaluate'], - 'argumentCount' => '1,2', - ], - 'TTEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '4', - ], - 'T.TEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '4', - ], - 'TYPE' => [ - 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'type'], - 'argumentCount' => '1', - ], - 'UNICHAR' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\CharacterConvert::class, 'character'], - 'argumentCount' => '1', - ], - 'UNICODE' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\CharacterConvert::class, 'code'], - 'argumentCount' => '1', - ], - 'UNIQUE' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Unique::class, 'unique'], - 'argumentCount' => '1+', - ], - 'UPPER' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\CaseConvert::class, 'upper'], - 'argumentCount' => '1', - ], - 'USDOLLAR' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Dollar::class, 'format'], - 'argumentCount' => '2', - ], - 'VALUE' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'VALUE'], - 'argumentCount' => '1', - ], - 'VALUETOTEXT' => [ - 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'valueToText'], - 'argumentCount' => '1,2', - ], - 'VAR' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VAR'], - 'argumentCount' => '1+', - ], - 'VAR.P' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VARP'], - 'argumentCount' => '1+', - ], - 'VAR.S' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VAR'], - 'argumentCount' => '1+', - ], - 'VARA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VARA'], - 'argumentCount' => '1+', - ], - 'VARP' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VARP'], - 'argumentCount' => '1+', - ], - 'VARPA' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VARPA'], - 'argumentCount' => '1+', - ], - 'VDB' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '5-7', - ], - 'VLOOKUP' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\VLookup::class, 'lookup'], - 'argumentCount' => '3,4', - ], - 'VSTACK' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '1+', - ], - 'WEBSERVICE' => [ - 'category' => Category::CATEGORY_WEB, - 'functionCall' => [Web\Service::class, 'webService'], - 'argumentCount' => '1', - ], - 'WEEKDAY' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Week::class, 'day'], - 'argumentCount' => '1,2', - ], - 'WEEKNUM' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Week::class, 'number'], - 'argumentCount' => '1,2', - ], - 'WEIBULL' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Weibull::class, 'distribution'], - 'argumentCount' => '4', - ], - 'WEIBULL.DIST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\Weibull::class, 'distribution'], - 'argumentCount' => '4', - ], - 'WORKDAY' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\WorkDay::class, 'date'], - 'argumentCount' => '2-3', - ], - 'WORKDAY.INTL' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2-4', - ], - 'WRAPCOLS' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2-3', - ], - 'WRAPROWS' => [ - 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2-3', - ], - 'XIRR' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Variable\NonPeriodic::class, 'rate'], - 'argumentCount' => '2,3', - ], - 'XLOOKUP' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '3-6', - ], - 'XNPV' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\CashFlow\Variable\NonPeriodic::class, 'presentValue'], - 'argumentCount' => '3', - ], - 'XMATCH' => [ - 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2,3', - ], - 'XOR' => [ - 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Operations::class, 'logicalXor'], - 'argumentCount' => '1+', - ], - 'YEAR' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\DateParts::class, 'year'], - 'argumentCount' => '1', - ], - 'YEARFRAC' => [ - 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\YearFrac::class, 'fraction'], - 'argumentCount' => '2,3', - ], - 'YIELD' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '6,7', - ], - 'YIELDDISC' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\Yields::class, 'yieldDiscounted'], - 'argumentCount' => '4,5', - ], - 'YIELDMAT' => [ - 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Securities\Yields::class, 'yieldAtMaturity'], - 'argumentCount' => '5,6', - ], - 'ZTEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StandardNormal::class, 'zTest'], - 'argumentCount' => '2-3', - ], - 'Z.TEST' => [ - 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Distributions\StandardNormal::class, 'zTest'], - 'argumentCount' => '2-3', - ], - ]; - /** * Internal functions used for special control purposes. + * + * @var array|string>> */ private static array $controlFunctions = [ 'MKMATRIX' => [ @@ -2892,18 +198,6 @@ class Calculation $this->branchPruner = new BranchPruner($this->branchPruningEnabled); } - private static function loadLocales(): void - { - $localeFileDirectory = __DIR__ . '/locale/'; - $localeFileNames = glob($localeFileDirectory . '*', GLOB_ONLYDIR) ?: []; - foreach ($localeFileNames as $filename) { - $filename = substr($filename, strlen($localeFileDirectory)); - if ($filename != 'en') { - self::$validLocaleLanguages[] = $filename; - } - } - } - /** * Get an instance of this class. * @@ -2913,10 +207,7 @@ class Calculation public static function getInstance(?Spreadsheet $spreadsheet = null): self { if ($spreadsheet !== null) { - $instance = $spreadsheet->getCalculationEngine(); - if (isset($instance)) { - return $instance; - } + return $spreadsheet->getCalculationEngine(); } if (!self::$instance) { @@ -2926,6 +217,20 @@ class Calculation return self::$instance; } + /** + * Intended for use only via a destructor. + * + * @internal + */ + public static function getInstanceOrNull(?Spreadsheet $spreadsheet = null): ?self + { + if ($spreadsheet !== null) { + return $spreadsheet->getCalculationEngineOrNull(); + } + + return null; + } + /** * Flush the calculation cache for any existing instance of this class * but only if a Calculation instance exists. @@ -2952,26 +257,6 @@ class Calculation throw new Exception('Cloning the calculation engine is not allowed!'); } - /** - * Return the locale-specific translation of TRUE. - * - * @return string locale-specific translation of TRUE - */ - public static function getTRUE(): string - { - return self::$localeBoolean['TRUE']; - } - - /** - * Return the locale-specific translation of FALSE. - * - * @return string locale-specific translation of FALSE - */ - public static function getFALSE(): string - { - return self::$localeBoolean['FALSE']; - } - /** * Set the Array Return Type (Array or Value of first element in the array). * @@ -3047,10 +332,12 @@ class Calculation /** * Enable/disable calculation cache. */ - public function setCalculationCacheEnabled(bool $calculationCacheEnabled): void + public function setCalculationCacheEnabled(bool $calculationCacheEnabled): self { $this->calculationCacheEnabled = $calculationCacheEnabled; $this->clearCalculationCache(); + + return $this; } /** @@ -3098,13 +385,17 @@ class Calculation } } - /** - * Enable/disable calculation cache. - */ - public function setBranchPruningEnabled(mixed $enabled): void + public function getBranchPruningEnabled(): bool { - $this->branchPruningEnabled = $enabled; + return $this->branchPruningEnabled; + } + + public function setBranchPruningEnabled(mixed $enabled): self + { + $this->branchPruningEnabled = (bool) $enabled; $this->branchPruner = new BranchPruner($this->branchPruningEnabled); + + return $this; } public function enableBranchPruning(): void @@ -3117,331 +408,6 @@ class Calculation $this->setBranchPruningEnabled(false); } - /** - * Get the currently defined locale code. - */ - public function getLocale(): string - { - return self::$localeLanguage; - } - - private function getLocaleFile(string $localeDir, string $locale, string $language, string $file): string - { - $localeFileName = $localeDir . str_replace('_', DIRECTORY_SEPARATOR, $locale) - . DIRECTORY_SEPARATOR . $file; - if (!file_exists($localeFileName)) { - // If there isn't a locale specific file, look for a language specific file - $localeFileName = $localeDir . $language . DIRECTORY_SEPARATOR . $file; - if (!file_exists($localeFileName)) { - throw new Exception('Locale file not found'); - } - } - - return $localeFileName; - } - - /** @var array> */ - private static array $falseTrueArray = []; - - /** @return array> */ - public function getFalseTrueArray(): array - { - if (!empty(self::$falseTrueArray)) { - return self::$falseTrueArray; - } - if (count(self::$validLocaleLanguages) == 1) { - self::loadLocales(); - } - $falseTrueArray = [['FALSE'], ['TRUE']]; - foreach (self::$validLocaleLanguages as $language) { - if (str_starts_with($language, 'en')) { - continue; - } - $locale = $language; - if (str_contains($locale, '_')) { - [$language] = explode('_', $locale); - } - $localeDir = implode(DIRECTORY_SEPARATOR, [__DIR__, 'locale', null]); - - try { - $functionNamesFile = $this->getLocaleFile($localeDir, $locale, $language, 'functions'); - } catch (Exception $e) { - continue; - } - // Retrieve the list of locale or language specific function names - $localeFunctions = file($functionNamesFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; - foreach ($localeFunctions as $localeFunction) { - [$localeFunction] = explode('##', $localeFunction); // Strip out comments - if (str_contains($localeFunction, '=')) { - [$fName, $lfName] = array_map('trim', explode('=', $localeFunction)); - if ($fName === 'FALSE') { - $falseTrueArray[0][] = $lfName; - } elseif ($fName === 'TRUE') { - $falseTrueArray[1][] = $lfName; - } - } - } - } - self::$falseTrueArray = $falseTrueArray; - - return $falseTrueArray; - } - - /** - * Set the locale code. - * - * @param string $locale The locale to use for formula translation, eg: 'en_us' - */ - public function setLocale(string $locale): bool - { - // Identify our locale and language - $language = $locale = strtolower($locale); - if (str_contains($locale, '_')) { - [$language] = explode('_', $locale); - } - if (count(self::$validLocaleLanguages) == 1) { - self::loadLocales(); - } - - // Test whether we have any language data for this language (any locale) - if (in_array($language, self::$validLocaleLanguages, true)) { - // initialise language/locale settings - self::$localeFunctions = []; - self::$localeArgumentSeparator = ','; - self::$localeBoolean = ['TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL']; - - // Default is US English, if user isn't requesting US english, then read the necessary data from the locale files - if ($locale !== 'en_us') { - $localeDir = implode(DIRECTORY_SEPARATOR, [__DIR__, 'locale', null]); - - // Search for a file with a list of function names for locale - try { - $functionNamesFile = $this->getLocaleFile($localeDir, $locale, $language, 'functions'); - } catch (Exception $e) { - return false; - } - - // Retrieve the list of locale or language specific function names - $localeFunctions = file($functionNamesFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; - foreach ($localeFunctions as $localeFunction) { - [$localeFunction] = explode('##', $localeFunction); // Strip out comments - if (str_contains($localeFunction, '=')) { - [$fName, $lfName] = array_map('trim', explode('=', $localeFunction)); - if ((str_starts_with($fName, '*') || isset(self::$phpSpreadsheetFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { - self::$localeFunctions[$fName] = $lfName; - } - } - } - // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions - if (isset(self::$localeFunctions['TRUE'])) { - self::$localeBoolean['TRUE'] = self::$localeFunctions['TRUE']; - } - if (isset(self::$localeFunctions['FALSE'])) { - self::$localeBoolean['FALSE'] = self::$localeFunctions['FALSE']; - } - - try { - $configFile = $this->getLocaleFile($localeDir, $locale, $language, 'config'); - } catch (Exception) { - return false; - } - - $localeSettings = file($configFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; - foreach ($localeSettings as $localeSetting) { - [$localeSetting] = explode('##', $localeSetting); // Strip out comments - if (str_contains($localeSetting, '=')) { - [$settingName, $settingValue] = array_map('trim', explode('=', $localeSetting)); - $settingName = strtoupper($settingName); - if ($settingValue !== '') { - switch ($settingName) { - case 'ARGUMENTSEPARATOR': - self::$localeArgumentSeparator = $settingValue; - - break; - } - } - } - } - } - - self::$functionReplaceFromExcel = self::$functionReplaceToExcel - = self::$functionReplaceFromLocale = self::$functionReplaceToLocale = null; - self::$localeLanguage = $locale; - - return true; - } - - return false; - } - - public static function translateSeparator( - string $fromSeparator, - string $toSeparator, - string $formula, - int &$inBracesLevel, - string $openBrace = self::FORMULA_OPEN_FUNCTION_BRACE, - string $closeBrace = self::FORMULA_CLOSE_FUNCTION_BRACE - ): string { - $strlen = mb_strlen($formula); - for ($i = 0; $i < $strlen; ++$i) { - $chr = mb_substr($formula, $i, 1); - switch ($chr) { - case $openBrace: - ++$inBracesLevel; - - break; - case $closeBrace: - --$inBracesLevel; - - break; - case $fromSeparator: - if ($inBracesLevel > 0) { - $formula = mb_substr($formula, 0, $i) . $toSeparator . mb_substr($formula, $i + 1); - } - } - } - - return $formula; - } - - private static function translateFormulaBlock( - array $from, - array $to, - string $formula, - int &$inFunctionBracesLevel, - int &$inMatrixBracesLevel, - string $fromSeparator, - string $toSeparator - ): string { - // Function Names - $formula = (string) preg_replace($from, $to, $formula); - - // Temporarily adjust matrix separators so that they won't be confused with function arguments - $formula = self::translateSeparator(';', '|', $formula, $inMatrixBracesLevel, self::FORMULA_OPEN_MATRIX_BRACE, self::FORMULA_CLOSE_MATRIX_BRACE); - $formula = self::translateSeparator(',', '!', $formula, $inMatrixBracesLevel, self::FORMULA_OPEN_MATRIX_BRACE, self::FORMULA_CLOSE_MATRIX_BRACE); - // Function Argument Separators - $formula = self::translateSeparator($fromSeparator, $toSeparator, $formula, $inFunctionBracesLevel); - // Restore matrix separators - $formula = self::translateSeparator('|', ';', $formula, $inMatrixBracesLevel, self::FORMULA_OPEN_MATRIX_BRACE, self::FORMULA_CLOSE_MATRIX_BRACE); - $formula = self::translateSeparator('!', ',', $formula, $inMatrixBracesLevel, self::FORMULA_OPEN_MATRIX_BRACE, self::FORMULA_CLOSE_MATRIX_BRACE); - - return $formula; - } - - private static function translateFormula(array $from, array $to, string $formula, string $fromSeparator, string $toSeparator): string - { - // Convert any Excel function names and constant names to the required language; - // and adjust function argument separators - if (self::$localeLanguage !== 'en_us') { - $inFunctionBracesLevel = 0; - $inMatrixBracesLevel = 0; - // If there is the possibility of separators within a quoted string, then we treat them as literals - if (str_contains($formula, self::FORMULA_STRING_QUOTE)) { - // So instead we skip replacing in any quoted strings by only replacing in every other array element - // after we've exploded the formula - $temp = explode(self::FORMULA_STRING_QUOTE, $formula); - $notWithinQuotes = false; - foreach ($temp as &$value) { - // Only adjust in alternating array entries - $notWithinQuotes = $notWithinQuotes === false; - if ($notWithinQuotes === true) { - $value = self::translateFormulaBlock($from, $to, $value, $inFunctionBracesLevel, $inMatrixBracesLevel, $fromSeparator, $toSeparator); - } - } - unset($value); - // Then rebuild the formula string - $formula = implode(self::FORMULA_STRING_QUOTE, $temp); - } else { - // If there's no quoted strings, then we do a simple count/replace - $formula = self::translateFormulaBlock($from, $to, $formula, $inFunctionBracesLevel, $inMatrixBracesLevel, $fromSeparator, $toSeparator); - } - } - - return $formula; - } - - private static ?array $functionReplaceFromExcel; - - private static ?array $functionReplaceToLocale; - - public function translateFormulaToLocale(string $formula): string - { - $formula = preg_replace(self::CALCULATION_REGEXP_STRIP_XLFN_XLWS, '', $formula) ?? ''; - // Build list of function names and constants for translation - if (self::$functionReplaceFromExcel === null) { - self::$functionReplaceFromExcel = []; - foreach (array_keys(self::$localeFunctions) as $excelFunctionName) { - self::$functionReplaceFromExcel[] = '/(@?[^\w\.])' . preg_quote($excelFunctionName, '/') . '([\s]*\()/ui'; - } - foreach (array_keys(self::$localeBoolean) as $excelBoolean) { - self::$functionReplaceFromExcel[] = '/(@?[^\w\.])' . preg_quote($excelBoolean, '/') . '([^\w\.])/ui'; - } - } - - if (self::$functionReplaceToLocale === null) { - self::$functionReplaceToLocale = []; - foreach (self::$localeFunctions as $localeFunctionName) { - self::$functionReplaceToLocale[] = '$1' . trim($localeFunctionName) . '$2'; - } - foreach (self::$localeBoolean as $localeBoolean) { - self::$functionReplaceToLocale[] = '$1' . trim($localeBoolean) . '$2'; - } - } - - return self::translateFormula( - self::$functionReplaceFromExcel, - self::$functionReplaceToLocale, - $formula, - ',', - self::$localeArgumentSeparator - ); - } - - private static ?array $functionReplaceFromLocale; - - private static ?array $functionReplaceToExcel; - - public function translateFormulaToEnglish(string $formula): string - { - if (self::$functionReplaceFromLocale === null) { - self::$functionReplaceFromLocale = []; - foreach (self::$localeFunctions as $localeFunctionName) { - self::$functionReplaceFromLocale[] = '/(@?[^\w\.])' . preg_quote($localeFunctionName, '/') . '([\s]*\()/ui'; - } - foreach (self::$localeBoolean as $excelBoolean) { - self::$functionReplaceFromLocale[] = '/(@?[^\w\.])' . preg_quote($excelBoolean, '/') . '([^\w\.])/ui'; - } - } - - if (self::$functionReplaceToExcel === null) { - self::$functionReplaceToExcel = []; - foreach (array_keys(self::$localeFunctions) as $excelFunctionName) { - self::$functionReplaceToExcel[] = '$1' . trim($excelFunctionName) . '$2'; - } - foreach (array_keys(self::$localeBoolean) as $excelBoolean) { - self::$functionReplaceToExcel[] = '$1' . trim($excelBoolean) . '$2'; - } - } - - return self::translateFormula(self::$functionReplaceFromLocale, self::$functionReplaceToExcel, $formula, self::$localeArgumentSeparator, ','); - } - - public static function localeFunc(string $function): string - { - if (self::$localeLanguage !== 'en_us') { - $functionName = trim($function, '('); - if (isset(self::$localeFunctions[$functionName])) { - $brace = ($functionName != $function); - $function = self::$localeFunctions[$functionName]; - if ($brace) { - $function .= '('; - } - } - } - - return $function; - } - /** * Wrap string values in quotes. */ @@ -3527,14 +493,14 @@ class Calculation try { $value = $cell->getValue(); - if ($cell->getDataType() === DataType::TYPE_FORMULA) { + if (is_string($value) && $cell->getDataType() === DataType::TYPE_FORMULA) { $value = preg_replace_callback( self::CALCULATION_REGEXP_CELLREF_SPILL, fn (array $matches) => 'ANCHORARRAY(' . substr($matches[0], 0, -1) . ')', $value ); } - $result = self::unwrapResult($this->_calculateFormulaValue($value, $cell->getCoordinate(), $cell)); + $result = self::unwrapResult($this->_calculateFormulaValue($value, $cell->getCoordinate(), $cell)); //* @phpstan-ignore-line if ($this->spreadsheet === null) { throw new Exception('null spreadsheet in calculateCellValue'); } @@ -3543,6 +509,7 @@ class Calculation if ($cellAddress === null) { throw new Exception('null cellAddress in calculateCellValue'); } + /** @var array{sheet: string, cell: string} $cellAddress */ $testSheet = $this->spreadsheet->getSheetByName($cellAddress['sheet']); if ($testSheet === null) { throw new Exception('worksheet not found in calculateCellValue'); @@ -3553,8 +520,10 @@ class Calculation $cellAddress = array_pop($this->cellStack); } if ($this->spreadsheet !== null && is_array($cellAddress) && array_key_exists('sheet', $cellAddress)) { - $testSheet = $this->spreadsheet->getSheetByName($cellAddress['sheet']); + $sheetName = $cellAddress['sheet'] ?? null; + $testSheet = is_string($sheetName) ? $this->spreadsheet->getSheetByName($sheetName) : null; if ($testSheet !== null && array_key_exists('cell', $cellAddress)) { + /** @var array{cell: string} $cellAddress */ $testSheet->getCell($cellAddress['cell']); } } @@ -3583,6 +552,8 @@ class Calculation * Validate and parse a formula string. * * @param string $formula Formula to parse + * + * @return array|bool */ public function parseFormula(string $formula): array|bool { @@ -3750,22 +721,35 @@ class Calculation * Ensure that paired matrix operands are both matrices and of the same size. * * @param mixed $operand1 First matrix operand + * + * @param-out mixed[] $operand1 + * * @param mixed $operand2 Second matrix operand + * + * @param-out mixed[] $operand2 + * * @param int $resize Flag indicating whether the matrices should be resized to match * and (if so), whether the smaller dimension should grow or the * larger should shrink. * 0 = no resize * 1 = shrink to fit * 2 = extend to fit + * + * @return mixed[] */ public static function checkMatrixOperands(mixed &$operand1, mixed &$operand2, int $resize = 1): array { // Examine each of the two operands, and turn them into an array if they aren't one already // Note that this function should only be called if one or both of the operand is already an array if (!is_array($operand1)) { - [$matrixRows, $matrixColumns] = self::getMatrixDimensions($operand2); - $operand1 = array_fill(0, $matrixRows, array_fill(0, $matrixColumns, $operand1)); - $resize = 0; + if (is_array($operand2)) { + [$matrixRows, $matrixColumns] = self::getMatrixDimensions($operand2); + $operand1 = array_fill(0, $matrixRows, array_fill(0, $matrixColumns, $operand1)); + $resize = 0; + } else { + $operand1 = [$operand1]; + $operand2 = [$operand2]; + } } elseif (!is_array($operand2)) { [$matrixRows, $matrixColumns] = self::getMatrixDimensions($operand1); $operand2 = array_fill(0, $matrixRows, array_fill(0, $matrixColumns, $operand2)); @@ -3785,6 +769,8 @@ class Calculation self::resizeMatricesExtend($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } elseif ($resize == 1) { // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller + /** @var mixed[][] $operand1 */ + /** @var mixed[][] $operand2 */ self::resizeMatricesShrink($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } [$matrix1Rows, $matrix1Columns] = self::getMatrixDimensions($operand1); @@ -3796,7 +782,7 @@ class Calculation /** * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0. * - * @param array $matrix matrix operand + * @param mixed[] $matrix matrix operand * * @return int[] An array comprising the number of rows, and number of columns */ @@ -3821,8 +807,8 @@ class Calculation /** * Ensure that paired matrix operands are both matrices of the same size. * - * @param array $matrix1 First matrix operand - * @param array $matrix2 Second matrix operand + * @param mixed[][] $matrix1 First matrix operand + * @param mixed[][] $matrix2 Second matrix operand * @param int $matrix1Rows Row size of first matrix operand * @param int $matrix1Columns Column size of first matrix operand * @param int $matrix2Rows Row size of second matrix operand @@ -3864,8 +850,8 @@ class Calculation /** * Ensure that paired matrix operands are both matrices of the same size. * - * @param array $matrix1 First matrix operand - * @param array $matrix2 Second matrix operand + * @param mixed[] $matrix1 First matrix operand + * @param mixed[] $matrix2 Second matrix operand * @param int $matrix1Rows Row size of first matrix operand * @param int $matrix1Columns Column size of first matrix operand * @param int $matrix2Rows Row size of second matrix operand @@ -3876,15 +862,16 @@ class Calculation if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { if ($matrix2Columns < $matrix1Columns) { for ($i = 0; $i < $matrix2Rows; ++$i) { - $x = $matrix2[$i][$matrix2Columns - 1]; + /** @var mixed[][] $matrix2 */ + $x = ($matrix2Columns === 1) ? $matrix2[$i][0] : null; for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { $matrix2[$i][$j] = $x; } } } if ($matrix2Rows < $matrix1Rows) { - $x = $matrix2[$matrix2Rows - 1]; - for ($i = 0; $i < $matrix1Rows; ++$i) { + $x = ($matrix2Rows === 1) ? $matrix2[0] : array_fill(0, $matrix2Columns, null); + for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { $matrix2[$i] = $x; } } @@ -3893,15 +880,16 @@ class Calculation if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { if ($matrix1Columns < $matrix2Columns) { for ($i = 0; $i < $matrix1Rows; ++$i) { - $x = $matrix1[$i][$matrix1Columns - 1]; + /** @var mixed[][] $matrix1 */ + $x = ($matrix1Columns === 1) ? $matrix1[$i][0] : null; for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { $matrix1[$i][$j] = $x; } } } if ($matrix1Rows < $matrix2Rows) { - $x = $matrix1[$matrix1Rows - 1]; - for ($i = 0; $i < $matrix2Rows; ++$i) { + $x = ($matrix1Rows === 1) ? $matrix1[0] : array_fill(0, $matrix2Columns, null); + for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) { $matrix1[$i] = $x; } } @@ -3970,6 +958,7 @@ class Calculation } elseif (is_array($value)) { $typeString = 'a matrix'; } else { + /** @var string $value */ if ($value == '') { return 'an empty string'; } elseif ($value[0] == '#') { @@ -3978,20 +967,20 @@ class Calculation $typeString = 'a string'; } - return $typeString . ' with a value of ' . $this->showValue($value); + return $typeString . ' with a value of ' . StringHelper::convertToString($this->showValue($value)); } return null; } + private const MATRIX_REPLACE_FROM = [self::FORMULA_OPEN_MATRIX_BRACE, ';', self::FORMULA_CLOSE_MATRIX_BRACE]; + private const MATRIX_REPLACE_TO = ['MKMATRIX(MKMATRIX(', '),MKMATRIX(', '))']; + /** * @return false|string False indicates an error */ private function convertMatrixReferences(string $formula): false|string { - static $matrixReplaceFrom = [self::FORMULA_OPEN_MATRIX_BRACE, ';', self::FORMULA_CLOSE_MATRIX_BRACE]; - static $matrixReplaceTo = ['MKMATRIX(MKMATRIX(', '),MKMATRIX(', '))']; - // Convert any Excel matrix references to the MKMATRIX() function if (str_contains($formula, self::FORMULA_OPEN_MATRIX_BRACE)) { // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators @@ -4008,7 +997,7 @@ class Calculation if ($notWithinQuotes === true) { $openCount += substr_count($value, self::FORMULA_OPEN_MATRIX_BRACE); $closeCount += substr_count($value, self::FORMULA_CLOSE_MATRIX_BRACE); - $value = str_replace($matrixReplaceFrom, $matrixReplaceTo, $value); + $value = str_replace(self::MATRIX_REPLACE_FROM, self::MATRIX_REPLACE_TO, $value); } } unset($value); @@ -4018,7 +1007,7 @@ class Calculation // If there's no quoted strings, then we do a simple count/replace $openCount = substr_count($formula, self::FORMULA_OPEN_MATRIX_BRACE); $closeCount = substr_count($formula, self::FORMULA_CLOSE_MATRIX_BRACE); - $formula = str_replace($matrixReplaceFrom, $matrixReplaceTo, $formula); + $formula = str_replace(self::MATRIX_REPLACE_FROM, self::MATRIX_REPLACE_TO, $formula); } // Trap for mismatched braces and trigger an appropriate error if ($openCount < $closeCount) { @@ -4039,32 +1028,18 @@ class Calculation return $formula; } - /** - * Binary Operators. - * These operators always work on two values. - * Array key is the operator, the value indicates whether this is a left or right associative operator. - */ - private static array $operatorAssociativity = [ - '^' => 0, // Exponentiation - '*' => 0, '/' => 0, // Multiplication and Division - '+' => 0, '-' => 0, // Addition and Subtraction - '&' => 0, // Concatenation - '∪' => 0, '∩' => 0, ':' => 0, // Union, Intersect and Range - '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0, // Comparison - ]; - /** * Comparison (Boolean) Operators. * These operators work on two values, but always return a boolean result. */ - private static array $comparisonOperators = ['>' => true, '<' => true, '=' => true, '>=' => true, '<=' => true, '<>' => true]; + private const COMPARISON_OPERATORS = ['>' => true, '<' => true, '=' => true, '>=' => true, '<=' => true, '<>' => true]; /** * Operator Precedence. * This list includes all valid operators, whether binary (including boolean) or unary (such as %). * Array key is the operator, the value is its precedence. */ - private static array $operatorPrecedence = [ + private const OPERATOR_PRECEDENCE = [ ':' => 9, // Range '∩' => 8, // Intersect '∪' => 7, // Union @@ -4077,8 +1052,6 @@ class Calculation '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0, // Comparison ]; - // Convert infix to postfix notation - /** * @return array|false */ @@ -4087,6 +1060,7 @@ class Calculation if (($formula = $this->convertMatrixReferences(trim($formula))) === false) { return false; } + $phpSpreadsheetFunctions = &self::getFunctionsAddress(); // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), // so we store the parent worksheet so that we can re-attach it when necessary @@ -4121,9 +1095,13 @@ class Calculation $this->branchPruner->initialiseForLoop(); $opCharacter = $formula[$index]; // Get the first character of the value at the current index position + if ($opCharacter === "\xe2") { // intersection or union + $opCharacter .= $formula[++$index]; + $opCharacter .= $formula[++$index]; + } // Check for two-character operators (e.g. >=, <=, <>) - if ((isset(self::$comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && isset($formula[$index + 1], self::$comparisonOperators[$formula[$index + 1]])) { + if ((isset(self::COMPARISON_OPERATORS[$opCharacter])) && (strlen($formula) > $index) && isset($formula[$index + 1], self::COMPARISON_OPERATORS[$formula[$index + 1]])) { $opCharacter .= $formula[++$index]; } // Find out if we're currently at the beginning of a number, variable, cell/row/column reference, @@ -4141,16 +1119,11 @@ class Calculation ++$index; } elseif ($opCharacter === '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded? ++$index; // Drop the redundant plus symbol - } elseif ((($opCharacter === '~') || ($opCharacter === '∩') || ($opCharacter === '∪')) && (!$isOperandOrFunction)) { + } elseif ((($opCharacter === '~') /*|| ($opCharacter === '∩') || ($opCharacter === '∪')*/) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde, union or intersect because they are legal return $this->raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression } elseif ((isset(self::CALCULATION_OPERATORS[$opCharacter]) || $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? - while ( - $stack->count() > 0 - && ($o2 = $stack->last()) - && isset(self::CALCULATION_OPERATORS[$o2['value']]) - && @(self::$operatorAssociativity[$opCharacter] ? self::$operatorPrecedence[$opCharacter] < self::$operatorPrecedence[$o2['value']] : self::$operatorPrecedence[$opCharacter] <= self::$operatorPrecedence[$o2['value']]) - ) { + while (self::swapOperands($stack, $opCharacter)) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } @@ -4170,7 +1143,7 @@ class Calculation // call or a parenthesis $this->branchPruner->decrementDepth(); - if (is_array($d) && preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $d['value'], $matches)) { + if (is_array($d) && preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', StringHelper::convertToString($d['value']), $matches)) { // Did this parenthesis just close a function? try { $this->branchPruner->closingBrace($d['value']); @@ -4185,8 +1158,8 @@ class Calculation $output[] = $stack->pop(); // Pop the function and push onto the output if (isset(self::$controlFunctions[$functionName])) { $expectedArgumentCount = self::$controlFunctions[$functionName]['argumentCount']; - } elseif (isset(self::$phpSpreadsheetFunctions[$functionName])) { - $expectedArgumentCount = self::$phpSpreadsheetFunctions[$functionName]['argumentCount']; + } elseif (isset($phpSpreadsheetFunctions[$functionName])) { + $expectedArgumentCount = $phpSpreadsheetFunctions[$functionName]['argumentCount']; } else { // did we somehow push a non-function on the stack? this should never happen return $this->raiseFormulaError('Formula Error: Internal error, non-function on stack'); } @@ -4205,7 +1178,7 @@ class Calculation $expectedArgumentCountString = $expectedArgumentCount; } } - } elseif ($expectedArgumentCount != '*') { + } elseif (is_string($expectedArgumentCount) && $expectedArgumentCount !== '*') { if (1 !== preg_match('/(\d*)([-+,])(\d*)/', $expectedArgumentCount, $argMatch)) { $argMatch = ['', '', '', '']; } @@ -4234,6 +1207,7 @@ class Calculation } } if ($argumentCountError) { + /** @var int $argumentCount */ return $this->raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, " . $expectedArgumentCountString . ' expected'); } } @@ -4255,15 +1229,26 @@ class Calculation } // make sure there was a function $d = $stack->last(2); - if (!preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $d['value'] ?? '', $matches)) { + /** @var string */ + $temp = $d['value'] ?? ''; + if (!preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $temp, $matches)) { // Can we inject a dummy function at this point so that the braces at least have some context // because at least the braces are paired up (at this stage in the formula) // MS Excel allows this if the content is cell references; but doesn't allow actual values, // but at this point, we can't differentiate (so allow both) return $this->raiseFormulaError('Formula Error: Unexpected ,'); + /* The following code may be a better choice, but, with + the other changes for this PR, I can no longer come up + with a test case that gets here + $stack->push('Binary Operator', '∪'); + + ++$index; + $expectingOperator = false; + + continue;*/ } - /** @var array $d */ + /** @var array $d */ $d = $stack->pop(); ++$d['value']; // increment the argument count @@ -4287,7 +1272,7 @@ class Calculation if (preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $val, $matches)) { $val = (string) preg_replace('/\s/u', '', $val); - if (isset(self::$phpSpreadsheetFunctions[strtoupper($matches[1])]) || isset(self::$controlFunctions[strtoupper($matches[1])])) { // it's a function + if (isset($phpSpreadsheetFunctions[strtoupper($matches[1])]) || isset(self::$controlFunctions[strtoupper($matches[1])])) { // it's a function $valToUpper = strtoupper($val); } else { $valToUpper = 'NAME.ERROR('; @@ -4323,6 +1308,7 @@ class Calculation // Do we have chained range operators? $rangeStartCellRef = $output[count($output) - 2]['value'] ?? ''; } + /** @var string $rangeStartCellRef */ preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/miu', $rangeStartCellRef, $rangeStartMatches); if (array_key_exists(2, $rangeStartMatches)) { if ($rangeStartMatches[2] > '') { @@ -4337,6 +1323,7 @@ class Calculation // Do we have chained range operators? $rangeStartCellRef = $output[count($output) - 2]['value'] ?? ''; } + /** @var string $rangeStartCellRef */ preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/miu', $rangeStartCellRef, $rangeStartMatches); if (isset($rangeStartMatches[2]) && $rangeStartMatches[2] !== $matches[2]) { return $this->raiseFormulaError('3D Range references are not yet supported'); @@ -4439,15 +1426,15 @@ class Calculation } } elseif ($opCharacter === self::FORMULA_STRING_QUOTE) { // UnEscape any quotes within the string - $val = self::wrapResult(str_replace('""', self::FORMULA_STRING_QUOTE, self::unwrapResult($val))); - } elseif (isset(self::$excelConstants[trim(strtoupper($val))])) { + $val = self::wrapResult(str_replace('""', self::FORMULA_STRING_QUOTE, StringHelper::convertToString(self::unwrapResult($val)))); + } elseif (isset(self::EXCEL_CONSTANTS[trim(strtoupper($val))])) { $stackItemType = 'Constant'; $excelConstant = trim(strtoupper($val)); - $val = self::$excelConstants[$excelConstant]; + $val = self::EXCEL_CONSTANTS[$excelConstant]; $stackItemReference = $excelConstant; } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$localeBoolean)) !== false) { $stackItemType = 'Constant'; - $val = self::$excelConstants[$localeConstant]; + $val = self::EXCEL_CONSTANTS[$localeConstant]; $stackItemReference = $localeConstant; } elseif ( preg_match('/^' . self::CALCULATION_REGEXP_ROW_RANGE . '/miu', substr($formula, $index), $rowRangeReference) @@ -4547,12 +1534,7 @@ class Calculation && ($output[$countOutputMinus1]['type'] === Operands\StructuredReference::NAME || $output[$countOutputMinus1]['type'] === 'Value') ) ) { - while ( - $stack->count() > 0 - && ($o2 = $stack->last()) - && isset(self::CALCULATION_OPERATORS[$o2['value']]) - && @(self::$operatorAssociativity[$opCharacter] ? self::$operatorPrecedence[$opCharacter] < self::$operatorPrecedence[$o2['value']] : self::$operatorPrecedence[$opCharacter] <= self::$operatorPrecedence[$o2['value']]) - ) { + while (self::swapOperands($stack, $opCharacter)) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } $stack->push('Binary Operator', '∩'); // Put an Intersect Operator on the stack @@ -4572,6 +1554,7 @@ class Calculation return $output; } + /** @param mixed[] $operandData */ private static function dataTestReference(array &$operandData): mixed { $operand = $operandData['value']; @@ -4601,13 +1584,16 @@ class Calculation private static int $matchIndex10 = 10; /** + * @param array|false $tokens + * * @return array|false|string */ - private function processTokenStack(mixed $tokens, ?string $cellID = null, ?Cell $cell = null) + private function processTokenStack(false|array $tokens, ?string $cellID = null, ?Cell $cell = null) { if ($tokens === false) { return false; } + $phpSpreadsheetFunctions = &self::getFunctionsAddress(); // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection), // so we store the parent cell collection so that we can re-attach it when necessary @@ -4622,14 +1608,17 @@ class Calculation $branchStore = []; // Loop through each token in turn foreach ($tokens as $tokenIdx => $tokenData) { + /** @var mixed[] $tokenData */ $this->processingAnchorArray = false; - if ($tokenData['type'] === 'Cell Reference' && isset($tokens[$tokenIdx + 1]) && $tokens[$tokenIdx + 1]['type'] === 'Operand Count for Function ANCHORARRAY()') { + if ($tokenData['type'] === 'Cell Reference' && isset($tokens[$tokenIdx + 1]) && $tokens[$tokenIdx + 1]['type'] === 'Operand Count for Function ANCHORARRAY()') { //* @phpstan-ignore-line $this->processingAnchorArray = true; } $token = $tokenData['value']; // Branch pruning: skip useless resolutions + /** @var ?string */ $storeKey = $tokenData['storeKey'] ?? null; if ($this->branchPruningEnabled && isset($tokenData['onlyIf'])) { + /** @var string */ $onlyIfStoreKey = $tokenData['onlyIf']; $storeValue = $branchStore[$onlyIfStoreKey] ?? null; $storeValueAsBool = ($storeValue === null) @@ -4644,7 +1633,9 @@ class Calculation && (!$storeValueAsBool || Information\ErrorValue::isError($storeValue) || ($storeValue === 'Pruned branch')) ) { // If branching value is not true, we don't need to compute + /** @var string $onlyIfStoreKey */ if (!isset($fakedForBranchPruning['onlyIf-' . $onlyIfStoreKey])) { + /** @var string $token */ $stack->push('Value', 'Pruned branch (only if ' . $onlyIfStoreKey . ') ' . $token); $fakedForBranchPruning['onlyIf-' . $onlyIfStoreKey] = true; } @@ -4662,6 +1653,7 @@ class Calculation } if ($this->branchPruningEnabled && isset($tokenData['onlyIfNot'])) { + /** @var string */ $onlyIfNotStoreKey = $tokenData['onlyIfNot']; $storeValue = $branchStore[$onlyIfNotStoreKey] ?? null; $storeValueAsBool = ($storeValue === null) @@ -4677,6 +1669,7 @@ class Calculation ) { // If branching value is true, we don't need to compute if (!isset($fakedForBranchPruning['onlyIfNot-' . $onlyIfNotStoreKey])) { + /** @var string $token */ $stack->push('Value', 'Pruned branch (only if not ' . $onlyIfNotStoreKey . ') ' . $token); $fakedForBranchPruning['onlyIfNot-' . $onlyIfNotStoreKey] = true; } @@ -4719,7 +1712,7 @@ class Calculation return $this->raiseFormulaError($e->getMessage(), $e->getCode(), $e); } } - } elseif (!is_numeric($token) && !is_object($token) && isset(self::BINARY_OPERATORS[$token])) { + } elseif (!is_numeric($token) && !is_object($token) && isset($token, self::BINARY_OPERATORS[$token])) { //* @phpstan-ignore-line // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack // We must have two operands, error if we don't $operand2Data = $stack->pop(); @@ -4758,27 +1751,43 @@ class Calculation break; // Binary Operators case ':': // Range + if ($operand1Data['type'] === 'Error') { + $stack->push($operand1Data['type'], $operand1Data['value'], null); + + break; + } + if ($operand2Data['type'] === 'Error') { + $stack->push($operand2Data['type'], $operand2Data['value'], null); + + break; + } if ($operand1Data['type'] === 'Defined Name') { + /** @var array{reference: string} $operand1Data */ if (preg_match('/$' . self::CALCULATION_REGEXP_DEFINEDNAME . '^/mui', $operand1Data['reference']) !== false && $this->spreadsheet !== null) { + /** @var string[] $operand1Data */ $definedName = $this->spreadsheet->getNamedRange($operand1Data['reference']); if ($definedName !== null) { $operand1Data['reference'] = $operand1Data['value'] = str_replace('$', '', $definedName->getValue()); } } } + /** @var array{reference?: ?string} $operand1Data */ if (str_contains($operand1Data['reference'] ?? '', '!')) { [$sheet1, $operand1Data['reference']] = Worksheet::extractSheetTitle($operand1Data['reference'], true, true); } else { $sheet1 = ($pCellWorksheet !== null) ? $pCellWorksheet->getTitle() : ''; } - $sheet1 ??= ''; + //$sheet1 ??= ''; // phpstan level 10 says this is unneeded - [$sheet2, $operand2Data['reference']] = Worksheet::extractSheetTitle($operand2Data['reference'], true, true); + /** @var string */ + $op2ref = $operand2Data['reference']; + [$sheet2, $operand2Data['reference']] = Worksheet::extractSheetTitle($op2ref, true, true); if (empty($sheet2)) { $sheet2 = $sheet1; } if ($sheet1 === $sheet2) { + /** @var array{reference: ?string, value: string|string[]} $operand1Data */ if ($operand1Data['reference'] === null && $cell !== null) { if (is_array($operand1Data['value'])) { $operand1Data['reference'] = $cell->getCoordinate(); @@ -4790,6 +1799,7 @@ class Calculation $operand1Data['reference'] = $operand1Data['value'] . $cell->getRow(); } } + /** @var array{reference: ?string, value: string|string[]} $operand2Data */ if ($operand2Data['reference'] === null && $cell !== null) { if (is_array($operand2Data['value'])) { $operand2Data['reference'] = $cell->getCoordinate(); @@ -4864,15 +1874,19 @@ class Calculation for ($row = 0; $row < $rows; ++$row) { for ($column = 0; $column < $columns; ++$column) { + /** @var mixed[][] $operand1 */ $op1x = self::boolToString($operand1[$row][$column]); + /** @var mixed[][] $operand2 */ $op2x = self::boolToString($operand2[$row][$column]); if (Information\ErrorValue::isError($op1x)) { // no need to do anything } elseif (Information\ErrorValue::isError($op2x)) { $operand1[$row][$column] = $op2x; } else { + /** @var string $op1x */ + /** @var string $op2x */ $operand1[$row][$column] - = Shared\StringHelper::substring( + = StringHelper::substring( $op1x . $op2x, 0, DataType::MAX_STRING_LENGTH @@ -4887,8 +1901,8 @@ class Calculation } elseif (Information\ErrorValue::isError($operand2)) { $result = $operand2; } else { - $result = str_replace('""', self::FORMULA_STRING_QUOTE, self::unwrapResult($operand1) . self::unwrapResult($operand2)); - $result = Shared\StringHelper::substring( + $result = str_replace('""', self::FORMULA_STRING_QUOTE, self::unwrapResult($operand1) . self::unwrapResult($operand2)); //* @phpstan-ignore-line + $result = StringHelper::substring( $result, 0, DataType::MAX_STRING_LENGTH @@ -4905,6 +1919,8 @@ class Calculation break; case '∩': // Intersect + /** @var mixed[][] $operand1 */ + /** @var mixed[][] $operand2 */ $rowIntersect = array_intersect_key($operand1, $operand2); $cellIntersect = $oCol = $oRow = []; foreach (array_keys($rowIntersect) as $row) { @@ -4924,6 +1940,14 @@ class Calculation $stack->push('Value', $cellIntersect, $cellRef); } + break; + case '∪': // union + /** @var mixed[][] $operand1 */ + /** @var mixed[][] $operand2 */ + $cellUnion = array_merge($operand1, $operand2); + $this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails($cellUnion)); + $stack->push('Value', $cellUnion, 'A1'); + break; } } elseif (($token === '~') || ($token === '%')) { @@ -4945,8 +1969,11 @@ class Calculation [$rows, $columns] = self::checkMatrixOperands($result, $operand2, 0); for ($row = 0; $row < $rows; ++$row) { for ($column = 0; $column < $columns; ++$column) { + /** @var mixed[][] $result */ if (self::isNumericOrBool($result[$row][$column])) { - $result[$row][$column] *= $multiplier; + /** @var float|int|numeric-string */ + $temp = $result[$row][$column]; + $result[$row][$column] = $temp * $multiplier; } else { $result[$row][$column] = self::makeError($result[$row][$column]); } @@ -4961,7 +1988,7 @@ class Calculation } else { $this->executeNumericBinaryOperation($multiplier, $arg, '*', $stack); } - } elseif (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/i', $token ?? '', $matches)) { + } elseif (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/i', StringHelper::convertToString($token ?? ''), $matches)) { $cellRef = null; /* Phpstan says matches[8/9/10] is never set, @@ -5014,6 +2041,9 @@ class Calculation $this->debugLog->writeDebugLog('Evaluating Cell %s in worksheet %s', $cellRef, $matches[2]); if ($pCellParent !== null && $this->spreadsheet !== null) { $cellSheet = $this->spreadsheet->getSheetByName($matches[2]); + if ($cellSheet && !$cellSheet->cellExists($cellRef)) { + $cellSheet->setCellValue($cellRef, null); + } if ($cellSheet && $cellSheet->cellExists($cellRef)) { $cellValue = $this->extractCellRange($cellRef, $this->spreadsheet->getSheetByName($matches[2]), false); $cell->attach($pCellParent); @@ -5052,27 +2082,27 @@ class Calculation if (isset($storeKey)) { $branchStore[$storeKey] = $cellValue; } - } elseif (preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $token ?? '', $matches)) { + } elseif (preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', StringHelper::convertToString($token ?? ''), $matches)) { // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on if ($cell !== null && $pCellParent !== null) { $cell->attach($pCellParent); } $functionName = $matches[1]; - /** @var array $argCount */ + /** @var array $argCount */ $argCount = $stack->pop(); $argCount = $argCount['value']; if ($functionName !== 'MKMATRIX') { $this->debugLog->writeDebugLog('Evaluating Function %s() with %s argument%s', self::localeFunc($functionName), (($argCount == 0) ? 'no' : $argCount), (($argCount == 1) ? '' : 's')); } - if ((isset(self::$phpSpreadsheetFunctions[$functionName])) || (isset(self::$controlFunctions[$functionName]))) { // function + if ((isset($phpSpreadsheetFunctions[$functionName])) || (isset(self::$controlFunctions[$functionName]))) { // function $passByReference = false; $passCellReference = false; $functionCall = null; - if (isset(self::$phpSpreadsheetFunctions[$functionName])) { - $functionCall = self::$phpSpreadsheetFunctions[$functionName]['functionCall']; - $passByReference = isset(self::$phpSpreadsheetFunctions[$functionName]['passByReference']); - $passCellReference = isset(self::$phpSpreadsheetFunctions[$functionName]['passCellReference']); + if (isset($phpSpreadsheetFunctions[$functionName])) { + $functionCall = $phpSpreadsheetFunctions[$functionName]['functionCall']; + $passByReference = isset($phpSpreadsheetFunctions[$functionName]['passByReference']); + $passCellReference = isset($phpSpreadsheetFunctions[$functionName]['passCellReference']); } elseif (isset(self::$controlFunctions[$functionName])) { $functionCall = self::$controlFunctions[$functionName]['functionCall']; $passByReference = isset(self::$controlFunctions[$functionName]['passByReference']); @@ -5087,10 +2117,10 @@ class Calculation $a = $argCount - $i - 1; if ( ($passByReference) - && (isset(self::$phpSpreadsheetFunctions[$functionName]['passByReference'][$a])) - && (self::$phpSpreadsheetFunctions[$functionName]['passByReference'][$a]) + && (isset($phpSpreadsheetFunctions[$functionName]['passByReference'][$a])) //* @phpstan-ignore-line + && ($phpSpreadsheetFunctions[$functionName]['passByReference'][$a]) ) { - /** @var array $arg */ + /** @var mixed[] $arg */ if ($arg['reference'] === null) { $nextArg = $cellID; if ($functionName === 'ISREF' && ($arg['type'] ?? '') === 'Value') { @@ -5102,6 +2132,13 @@ class Calculation $nextArg = ''; } } + } elseif (($arg['type'] ?? '') === 'Error') { + $argValue = $arg['value']; + if (is_scalar($argValue)) { + $nextArg = $argValue; + } elseif (empty($argValue)) { + $nextArg = ''; + } } $args[] = $nextArg; if ($functionName !== 'MKMATRIX') { @@ -5114,7 +2151,7 @@ class Calculation } } } else { - /** @var array $arg */ + /** @var mixed[] $arg */ if ($arg['type'] === 'Empty Argument' && in_array($functionName, ['MIN', 'MINA', 'MAX', 'MAXA', 'IF'], true)) { $emptyArguments[] = false; $args[] = $arg['value'] = 0; @@ -5134,7 +2171,9 @@ class Calculation krsort($emptyArguments); if ($argCount > 0 && is_array($functionCall)) { - $args = $this->addDefaultArgumentValues($functionCall, $args, $emptyArguments); + /** @var string[] */ + $functionCallCopy = $functionCall; + $args = $this->addDefaultArgumentValues($functionCallCopy, $args, $emptyArguments); } if (($passByReference) && ($argCount == 0)) { @@ -5153,6 +2192,7 @@ class Calculation if ($pCellWorksheet !== null && $originalCoordinate !== null) { $pCellWorksheet->getCell($originalCoordinate); } + /** @var array|string $functionCall */ $args = $this->addCellReference($args, $passCellReference, $functionCall, $cell); if (!is_array($functionCall)) { @@ -5162,8 +2202,15 @@ class Calculation unset($arg); } - $result = call_user_func_array($functionCall, $args); - + /** @var callable $functionCall */ + try { + $result = call_user_func_array($functionCall, $args); + } catch (TypeError $e) { + if (!$this->suppressFormulaErrors) { + throw $e; + } + $result = false; + } if ($functionName !== 'MKMATRIX') { $this->debugLog->writeDebugLog('Evaluation Result for %s() function call is %s', self::localeFunc($functionName), $this->showTypeDetails($result)); } @@ -5174,14 +2221,16 @@ class Calculation } } else { // if the token is a number, boolean, string or an Excel error, push it onto the stack - if (isset(self::$excelConstants[strtoupper($token ?? '')])) { - $excelConstant = strtoupper($token); - $stack->push('Constant Value', self::$excelConstants[$excelConstant]); + /** @var ?string $token */ + if (isset(self::EXCEL_CONSTANTS[strtoupper($token ?? '')])) { + $excelConstant = strtoupper("$token"); + $stack->push('Constant Value', self::EXCEL_CONSTANTS[$excelConstant]); if (isset($storeKey)) { - $branchStore[$storeKey] = self::$excelConstants[$excelConstant]; + $branchStore[$storeKey] = self::EXCEL_CONSTANTS[$excelConstant]; } - $this->debugLog->writeDebugLog('Evaluating Constant %s as %s', $excelConstant, $this->showTypeDetails(self::$excelConstants[$excelConstant])); - } elseif ((is_numeric($token)) || ($token === null) || (is_bool($token)) || ($token == '') || ($token[0] == self::FORMULA_STRING_QUOTE) || ($token[0] == '#')) { + $this->debugLog->writeDebugLog('Evaluating Constant %s as %s', $excelConstant, $this->showTypeDetails(self::EXCEL_CONSTANTS[$excelConstant])); + } elseif ((is_numeric($token)) || ($token === null) || (is_bool($token)) || ($token == '') || ($token[0] == self::FORMULA_STRING_QUOTE) || ($token[0] == '#')) { //* @phpstan-ignore-line + /** @var array{type: string, reference: ?string} $tokenData */ $stack->push($tokenData['type'], $token, $tokenData['reference']); if (isset($storeKey)) { $branchStore[$storeKey] = $token; @@ -5220,11 +2269,13 @@ class Calculation } } if ($namedRange === null) { - return $this->raiseFormulaError("undefined name '$definedName'"); + $result = ExcelError::NAME(); + $stack->push('Error', $result, null); + $this->debugLog->writeDebugLog("Error $result"); + } else { + $result = $this->evaluateDefinedName($cell, $namedRange, $pCellWorksheet, $stack, $specifiedWorksheet !== ''); } - $result = $this->evaluateDefinedName($cell, $namedRange, $pCellWorksheet, $stack, $specifiedWorksheet !== ''); - if (isset($storeKey)) { $branchStore[$storeKey] = $result; } @@ -5237,14 +2288,14 @@ class Calculation if ($stack->count() != 1) { return $this->raiseFormulaError('internal error'); } - /** @var array $output */ + /** @var array|false|string> */ $output = $stack->pop(); $output = $output['value']; return $output; } - private function validateBinaryOperand(mixed &$operand, mixed &$stack): bool + private function validateBinaryOperand(mixed &$operand, Stack &$stack): bool { if (is_array($operand)) { if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { @@ -5258,7 +2309,7 @@ class Calculation // We only need special validations for the operand if it is a string // Start by stripping off the quotation marks we use to identify true excel string values internally if ($operand > '' && $operand[0] == self::FORMULA_STRING_QUOTE) { - $operand = self::unwrapResult($operand); + $operand = StringHelper::convertToString(self::unwrapResult($operand)); } // If the string is a numeric value, we treat it as a numeric, so no further testing if (!is_numeric($operand)) { @@ -5282,28 +2333,29 @@ class Calculation return true; } + /** @return mixed[] */ private function executeArrayComparison(mixed $operand1, mixed $operand2, string $operation, Stack &$stack, bool $recursingArrays): array { $result = []; - if (!is_array($operand2)) { + if (!is_array($operand2) && is_array($operand1)) { // Operand 1 is an array, Operand 2 is a scalar foreach ($operand1 as $x => $operandData) { $this->debugLog->writeDebugLog('Evaluating Comparison %s %s %s', $this->showValue($operandData), $operation, $this->showValue($operand2)); $this->executeBinaryComparisonOperation($operandData, $operand2, $operation, $stack); - /** @var array $r */ + /** @var array $r */ $r = $stack->pop(); $result[$x] = $r['value']; } - } elseif (!is_array($operand1)) { + } elseif (is_array($operand2) && !is_array($operand1)) { // Operand 1 is a scalar, Operand 2 is an array foreach ($operand2 as $x => $operandData) { $this->debugLog->writeDebugLog('Evaluating Comparison %s %s %s', $this->showValue($operand1), $operation, $this->showValue($operandData)); $this->executeBinaryComparisonOperation($operand1, $operandData, $operation, $stack); - /** @var array $r */ + /** @var array $r */ $r = $stack->pop(); $result[$x] = $r['value']; } - } else { + } elseif (is_array($operand2) && is_array($operand1)) { // Operand 1 and Operand 2 are both arrays if (!$recursingArrays) { self::checkMatrixOperands($operand1, $operand2, 2); @@ -5311,10 +2363,12 @@ class Calculation foreach ($operand1 as $x => $operandData) { $this->debugLog->writeDebugLog('Evaluating Comparison %s %s %s', $this->showValue($operandData), $operation, $this->showValue($operand2[$x])); $this->executeBinaryComparisonOperation($operandData, $operand2[$x], $operation, $stack, true); - /** @var array $r */ + /** @var array $r */ $r = $stack->pop(); $result[$x] = $r['value']; } + } else { + throw new Exception('Neither operand is an arra'); } // Log the result details $this->debugLog->writeDebugLog('Comparison Evaluation Result is %s', $this->showTypeDetails($result)); @@ -5324,6 +2378,7 @@ class Calculation return $result; } + /** @return bool|mixed[] */ private function executeBinaryComparisonOperation(mixed $operand1, mixed $operand2, string $operation, Stack &$stack, bool $recursingArrays = false): array|bool { // If we're dealing with matrix operations, we want a matrix result @@ -5373,43 +2428,49 @@ class Calculation for ($row = 0; $row < $rows; ++$row) { for ($column = 0; $column < $columns; ++$column) { - if ($operand1[$row][$column] === null) { + /** @var mixed[][] $operand1 */ + if (($operand1[$row][$column] ?? null) === null) { $operand1[$row][$column] = 0; } elseif (!self::isNumericOrBool($operand1[$row][$column])) { $operand1[$row][$column] = self::makeError($operand1[$row][$column]); continue; } - if ($operand2[$row][$column] === null) { + /** @var mixed[][] $operand2 */ + if (($operand2[$row][$column] ?? null) === null) { $operand2[$row][$column] = 0; } elseif (!self::isNumericOrBool($operand2[$row][$column])) { $operand1[$row][$column] = self::makeError($operand2[$row][$column]); continue; } + /** @var float|int */ + $operand1Val = $operand1[$row][$column]; + /** @var float|int */ + $operand2Val = $operand2[$row][$column]; switch ($operation) { case '+': - $operand1[$row][$column] += $operand2[$row][$column]; + $operand1[$row][$column] = $operand1Val + $operand2Val; break; case '-': - $operand1[$row][$column] -= $operand2[$row][$column]; + $operand1[$row][$column] = $operand1Val - $operand2Val; break; case '*': - $operand1[$row][$column] *= $operand2[$row][$column]; + $operand1[$row][$column] = $operand1Val * $operand2Val; break; case '/': - if ($operand2[$row][$column] == 0) { + if ($operand2Val == 0) { $operand1[$row][$column] = ExcelError::DIV0(); } else { - $operand1[$row][$column] /= $operand2[$row][$column]; + $operand1[$row][$column] = $operand1Val / $operand2Val; } break; case '^': - $operand1[$row][$column] = $operand1[$row][$column] ** $operand2[$row][$column]; + $operand1[$row][$column] = $operand1Val ** $operand2Val; break; @@ -5421,6 +2482,8 @@ class Calculation $result = $operand1; } else { // If we're dealing with non-matrix operations, execute the necessary operation + /** @var float|int $operand1 */ + /** @var float|int $operand2 */ switch ($operation) { // Addition case '+': @@ -5478,6 +2541,8 @@ class Calculation $this->formulaError = $errorMessage; $this->cyclicReferenceStack->clear(); $suppress = $this->suppressFormulaErrors; + $suppressed = $suppress ? ' $suppressed' : ''; + $this->debugLog->writeDebugLog("Raise Error$suppressed $errorMessage"); if (!$suppress) { throw new Exception($errorMessage, $code, $exception); } @@ -5492,11 +2557,12 @@ class Calculation * @param ?Worksheet $worksheet Worksheet * @param bool $resetLog Flag indicating whether calculation log should be reset or not * - * @return array Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @return mixed[] Array of values in range if range contains more than one element. Otherwise, a single value is returned. */ - public function extractCellRange(string &$range = 'A1', ?Worksheet $worksheet = null, bool $resetLog = true): array + public function extractCellRange(string &$range = 'A1', ?Worksheet $worksheet = null, bool $resetLog = true, bool $createCell = false): array { // Return value + /** @var mixed[][] */ $returnValue = []; if ($worksheet !== null) { @@ -5515,6 +2581,9 @@ class Calculation if (!isset($aReferences[1])) { // Single cell in range sscanf($aReferences[0], '%[A-Z]%d', $currentCol, $currentRow); + if ($createCell && $worksheet !== null && !$worksheet->cellExists($aReferences[0])) { + $worksheet->setCellValue($aReferences[0], null); + } if ($worksheet !== null && $worksheet->cellExists($aReferences[0])) { $temp = $worksheet->getCell($aReferences[0])->getCalculatedValue($resetLog); if ($this->getInstanceArrayReturnType() === self::RETURN_ARRAY_AS_ARRAY) { @@ -5531,6 +2600,9 @@ class Calculation foreach ($aReferences as $reference) { // Extract range sscanf($reference, '%[A-Z]%d', $currentCol, $currentRow); + if ($createCell && $worksheet !== null && !$worksheet->cellExists($reference)) { + $worksheet->setCellValue($reference, null); + } if ($worksheet !== null && $worksheet->cellExists($reference)) { $temp = $worksheet->getCell($reference)->getCalculatedValue($resetLog); if ($this->getInstanceArrayReturnType() === self::RETURN_ARRAY_AS_ARRAY) { @@ -5556,7 +2628,7 @@ class Calculation * @param null|Worksheet $worksheet Worksheet * @param bool $resetLog Flag indicating whether calculation log should be reset or not * - * @return array|string Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @return mixed[]|string Array of values in range if range contains more than one element. Otherwise, a single value is returned. */ public function extractNamedRange(string &$range = 'A1', ?Worksheet $worksheet = null, bool $resetLog = true): string|array { @@ -5590,6 +2662,7 @@ class Calculation if (!isset($aReferences[1])) { // Single cell (or single column or row) in range [$currentCol, $currentRow] = Coordinate::coordinateFromString($aReferences[0]); + /** @var mixed[][] $returnValue */ if ($worksheet !== null && $worksheet->cellExists($aReferences[0])) { $returnValue[$currentRow][$currentCol] = $worksheet->getCell($aReferences[0])->getCalculatedValue($resetLog); } else { @@ -5620,26 +2693,22 @@ class Calculation public function isImplemented(string $function): bool { $function = strtoupper($function); - $notImplemented = !isset(self::$phpSpreadsheetFunctions[$function]) || (is_array(self::$phpSpreadsheetFunctions[$function]['functionCall']) && self::$phpSpreadsheetFunctions[$function]['functionCall'][1] === 'DUMMY'); + $phpSpreadsheetFunctions = &self::getFunctionsAddress(); + $notImplemented = !isset($phpSpreadsheetFunctions[$function]) || (is_array($phpSpreadsheetFunctions[$function]['functionCall']) && $phpSpreadsheetFunctions[$function]['functionCall'][1] === 'DUMMY'); return !$notImplemented; } - /** - * Get a list of all implemented functions as an array of function objects. - */ - public static function getFunctions(): array - { - return self::$phpSpreadsheetFunctions; - } - /** * Get a list of implemented Excel function names. + * + * @return string[] */ public function getImplementedFunctionNames(): array { $returnValue = []; - foreach (self::$phpSpreadsheetFunctions as $functionName => $function) { + $phpSpreadsheetFunctions = &self::getFunctionsAddress(); + foreach ($phpSpreadsheetFunctions as $functionName => $function) { if ($this->isImplemented($functionName)) { $returnValue[] = $functionName; } @@ -5648,6 +2717,13 @@ class Calculation return $returnValue; } + /** + * @param string[] $functionCall + * @param mixed[] $args + * @param mixed[] $emptyArguments + * + * @return mixed[] + */ private function addDefaultArgumentValues(array $functionCall, array $args, array $emptyArguments): array { $reflector = new ReflectionMethod($functionCall[0], $functionCall[1]); @@ -5698,6 +2774,11 @@ class Calculation /** * Add cell reference if needed while making sure that it is the last argument. + * + * @param mixed[] $args + * @param string|string[] $functionCall + * + * @return mixed[] */ private function addCellReference(array $args, bool $passCellReference, array|string $functionCall, ?Cell $cell = null): array { @@ -5732,6 +2813,14 @@ class Calculation $definedNameValue = $namedRange->getValue(); $definedNameType = $namedRange->isFormula() ? 'Formula' : 'Range'; + if ($definedNameType === 'Range') { + if (preg_match('/^(.*!)?(.*)$/', $definedNameValue, $matches) === 1) { + $matches2 = trim($matches[2]); + $matches2 = preg_replace('/ +/', ' ∩ ', $matches2) ?? $matches2; + $matches2 = preg_replace('/,/', ' ∪ ', $matches2) ?? $matches2; + $definedNameValue = $matches[1] . $matches2; + } + } $definedNameWorksheet = $namedRange->getWorksheet(); if ($definedNameValue[0] !== '=') { @@ -5769,14 +2858,22 @@ class Calculation $this->debugLog->writeDebugLog('Evaluation Result for Named %s %s is %s', $definedNameType, $namedRange->getName(), $this->showTypeDetails($result)); } - $stack->push('Defined Name', $result, $namedRange->getName()); + $y = $namedRange->getWorksheet()?->getTitle(); + $x = $namedRange->getLocalOnly(); + if ($x && $y !== null) { + $stack->push('Defined Name', $result, "'$y'!" . $namedRange->getName()); + } else { + $stack->push('Defined Name', $result, $namedRange->getName()); + } return $result; } - public function setSuppressFormulaErrors(bool $suppressFormulaErrors): void + public function setSuppressFormulaErrors(bool $suppressFormulaErrors): self { $this->suppressFormulaErrors = $suppressFormulaErrors; + + return $this; } public function getSuppressFormulaErrors(): bool @@ -5802,6 +2899,27 @@ class Calculation private static function makeError(mixed $operand = ''): string { - return Information\ErrorValue::isError($operand) ? $operand : ExcelError::VALUE(); + return (is_string($operand) && Information\ErrorValue::isError($operand)) ? $operand : ExcelError::VALUE(); + } + + private static function swapOperands(Stack $stack, string $opCharacter): bool + { + $retVal = false; + if ($stack->count() > 0) { + $o2 = $stack->last(); + if ($o2) { + /** @var array{value: string} $o2 */ + if (isset(self::CALCULATION_OPERATORS[$o2['value']])) { + $retVal = (self::OPERATOR_PRECEDENCE[$opCharacter] ?? 0) <= self::OPERATOR_PRECEDENCE[$o2['value']]; + } + } + } + + return $retVal; + } + + public function getSpreadsheet(): ?Spreadsheet + { + return $this->spreadsheet; } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DAverage.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DAverage.php index e54f1bb..a85134e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DAverage.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DAverage.php @@ -19,12 +19,12 @@ class DAverage extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DCount.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DCount.php index fff7ab0..75b21dd 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DCount.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DCount.php @@ -20,12 +20,12 @@ class DCount extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DCountA.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DCountA.php index f1a68c1..23676bf 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DCountA.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DCountA.php @@ -19,12 +19,12 @@ class DCountA extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DGet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DGet.php index dd0f006..719beaa 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DGet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DGet.php @@ -19,12 +19,12 @@ class DGet extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the @@ -42,6 +42,7 @@ class DGet extends DatabaseAbstract return ExcelError::NAN(); } + /** @var array */ $row = array_pop($columnData); return array_pop($row); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DMax.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DMax.php index 23b95a7..a194288 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DMax.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DMax.php @@ -20,12 +20,12 @@ class DMax extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DMin.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DMin.php index 541803d..f94e09f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DMin.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DMin.php @@ -20,12 +20,12 @@ class DMin extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DProduct.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DProduct.php index b60aa0d..e7122d6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DProduct.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DProduct.php @@ -19,12 +19,12 @@ class DProduct extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DStDev.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DStDev.php index dc35405..a03ee2a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DStDev.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DStDev.php @@ -20,12 +20,12 @@ class DStDev extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DStDevP.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DStDevP.php index a05d596..54f1142 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DStDevP.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DStDevP.php @@ -20,12 +20,12 @@ class DStDevP extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DSum.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DSum.php index f9f926b..7396a0f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DSum.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DSum.php @@ -19,12 +19,12 @@ class DSum extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DVar.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DVar.php index 33b5b56..e056e9e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DVar.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DVar.php @@ -20,12 +20,12 @@ class DVar extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DVarP.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DVarP.php index 942a4a1..3bd571f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DVarP.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DVarP.php @@ -20,12 +20,12 @@ class DVarP extends DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * @param null|array|int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php index 7f0b57d..052b9f5 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php @@ -5,9 +5,26 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Database; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Internal\WildcardMatch; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; abstract class DatabaseAbstract { + /** + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param null|array|int|string $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + */ abstract public static function evaluate(array $database, array|null|int|string $field, array $criteria): null|float|int|string; /** @@ -27,12 +44,16 @@ abstract class DatabaseAbstract */ protected static function fieldExtract(array $database, mixed $field): ?int { - $field = strtoupper(Functions::flattenSingleValue($field) ?? ''); + /** @var ?string */ + $single = Functions::flattenSingleValue($field); + $field = strtoupper($single ?? ''); if ($field === '') { return null; } - $fieldNames = array_map('strtoupper', array_shift($database)); + /** @var callable */ + $callable = 'strtoupper'; + $fieldNames = array_map($callable, array_shift($database)); //* @phpstan-ignore-line if (is_numeric($field)) { $field = (int) $field - 1; if ($field < 0 || $field >= count($fieldNames)) { @@ -56,7 +77,7 @@ abstract class DatabaseAbstract * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * @param mixed[][] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the @@ -66,16 +87,25 @@ abstract class DatabaseAbstract */ protected static function filter(array $database, array $criteria): array { + /** @var mixed[] */ $fieldNames = array_shift($database); $criteriaNames = array_shift($criteria); // Convert the criteria into a set of AND/OR conditions with [:placeholders] + /** @var string[] $criteriaNames */ $query = self::buildQuery($criteriaNames, $criteria); // Loop through each row of the database + /** @var mixed[][] $criteriaNames */ return self::executeQuery($database, $query, $criteriaNames, $fieldNames); } + /** + * @param mixed[] $database The range of cells that makes up the list or database + * @param mixed[][] $criteria + * + * @return mixed[] + */ protected static function getFilteredColumn(array $database, ?int $field, array $criteria): array { // reduce the database to a set of rows that match all the criteria @@ -84,16 +114,21 @@ abstract class DatabaseAbstract // extract an array of values for the requested column $columnData = []; + /** @var mixed[] $row */ foreach ($database as $rowKey => $row) { $keys = array_keys($row); - $key = $keys[$field] ?? null; + $key = ($field === null) ? null : ($keys[$field] ?? null); $columnKey = $key ?? 'A'; - $columnData[$rowKey][$columnKey] = $row[$key] ?? $defaultReturnColumnValue; + $columnData[$rowKey][$columnKey] = ($key === null) ? $defaultReturnColumnValue : ($row[$key] ?? $defaultReturnColumnValue); } return $columnData; } + /** + * @param string[] $criteriaNames + * @param mixed[][] $criteria + */ private static function buildQuery(array $criteriaNames, array $criteria): string { $baseQuery = []; @@ -135,12 +170,21 @@ abstract class DatabaseAbstract return $condition; } + /** + * @param mixed[] $database + * @param mixed[][] $criteria + * @param array $fields + * + * @return mixed[] + */ private static function executeQuery(array $database, string $query, array $criteria, array $fields): array { foreach ($database as $dataRow => $dataValues) { // Substitute actual values from the database row for our [:placeholders] $conditions = $query; foreach ($criteria as $criterion) { + /** @var string $criterion */ + /** @var mixed[] $dataValues */ $conditions = self::processCondition($criterion, $fields, $dataValues, $conditions); } @@ -156,6 +200,10 @@ abstract class DatabaseAbstract return $database; } + /** + * @param array $fields + * @param array $dataValues + */ private static function processCondition(string $criterion, array $fields, array $dataValues, string $conditions): string { $key = array_search($criterion, $fields, true); @@ -169,7 +217,10 @@ abstract class DatabaseAbstract if (is_string($dataValue) && str_contains($dataValue, '"')) { $dataValue = str_replace('"', '""', $dataValue); } - $dataValue = (is_string($dataValue)) ? Calculation::wrapResult(strtoupper($dataValue)) : $dataValue; + if (is_string($dataValue)) { + $dataValue = Calculation::wrapResult(strtoupper($dataValue)); + } + $dataValue = StringHelper::convertToString($dataValue); } return str_replace('[:' . $criterion . ']', $dataValue, $conditions); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php index dd3bfc2..9a6faf3 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php @@ -28,7 +28,7 @@ class Date * A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted, * as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language. * - * @param array|float|int|string $year The value of the year argument can include one to four digits. + * @param array|float|int|string $year The value of the year argument can include one to four digits. * Excel interprets the year argument according to the configured * date system: 1900 or 1904. * If year is between 0 (zero) and 1899 (inclusive), Excel adds that @@ -39,7 +39,7 @@ class Date * 2008. * If year is less than 0 or is 10000 or greater, Excel returns the * #NUM! error value. - * @param array|float|int|string $month A positive or negative integer representing the month of the year + * @param array|float|int|string $month A positive or negative integer representing the month of the year * from 1 to 12 (January to December). * If month is greater than 12, month adds that number of months to * the first month in the year specified. For example, DATE(2008,14,2) @@ -48,7 +48,7 @@ class Date * number of months, plus 1, from the first month in the year * specified. For example, DATE(2008,-3,2) returns the serial number * representing September 2, 2007. - * @param array|float|int|string $day A positive or negative integer representing the day of the month + * @param array|float|int|string $day A positive or negative integer representing the day of the month * from 1 to 31. * If day is greater than the number of days in the month specified, * day adds that number of days to the first day in the month. For @@ -59,12 +59,12 @@ class Date * example, DATE(2008,1,-15) returns the serial number representing * December 16, 2007. * - * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ - public static function fromYMD(array|float|int|string $year, array|float|int|string $month, array|float|int|string $day): float|int|DateTime|string|array + public static function fromYMD(array|float|int|string $year, null|array|bool|float|int|string $month, array|float|int|string $day): float|int|DateTime|string|array { if (is_array($year) || is_array($month) || is_array($day)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $year, $month, $day); @@ -92,7 +92,11 @@ class Date */ private static function getYear(mixed $year, int $baseYear): int { - $year = ($year !== null) ? StringHelper::testStringAsNumeric((string) $year) : 0; + if ($year === null) { + $year = 0; + } elseif (is_scalar($year)) { + $year = StringHelper::testStringAsNumeric((string) $year); + } if (!is_numeric($year)) { throw new Exception(ExcelError::VALUE()); } @@ -117,11 +121,15 @@ class Date */ private static function getMonth(mixed $month): int { - if (($month !== null) && (!is_numeric($month))) { - $month = SharedDateHelper::monthStringToNumber($month); + if (is_string($month)) { + if (!is_numeric($month)) { + $month = SharedDateHelper::monthStringToNumber($month); + } + } elseif ($month === null) { + $month = 0; + } elseif (is_bool($month)) { + $month = (int) $month; } - - $month = ($month !== null) ? StringHelper::testStringAsNumeric((string) $month) : 0; if (!is_numeric($month)) { throw new Exception(ExcelError::VALUE()); } @@ -134,11 +142,15 @@ class Date */ private static function getDay(mixed $day): int { - if (($day !== null) && (!is_numeric($day))) { + if (is_string($day) && !is_numeric($day)) { $day = SharedDateHelper::dayStringToNumber($day); } - $day = ($day !== null) ? StringHelper::testStringAsNumeric((string) $day) : 0; + if ($day === null) { + $day = 0; + } elseif (is_scalar($day)) { + $day = StringHelper::testStringAsNumeric((string) $day); + } if (!is_numeric($day)) { throw new Exception(ExcelError::VALUE()); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateParts.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateParts.php index 60e4de1..fc23904 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateParts.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateParts.php @@ -24,7 +24,7 @@ class DateParts * PHP DateTime object, or a standard date string * Or can be an array of date values * - * @return array|int|string Day of the month + * @return array|int|string Day of the month * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -65,7 +65,7 @@ class DateParts * PHP DateTime object, or a standard date string * Or can be an array of date values * - * @return array|int|string Month of the year + * @return array|int|string Month of the year * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -104,7 +104,7 @@ class DateParts * PHP DateTime object, or a standard date string * Or can be an array of date values * - * @return array|int|string Year + * @return array|int|string Year * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php index b6411df..d29ed6b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php @@ -25,7 +25,7 @@ class DateValue * Excel Function: * DATEVALUE(dateValue) * - * @param null|array|bool|float|int|string $dateValue Text that represents a date in a Microsoft Excel date format. + * @param null|array|bool|float|int|string $dateValue Text that represents a date in a Microsoft Excel date format. * For example, "1/30/2008" or "30-Jan-2008" are text strings within * quotation marks that represent dates. Using the default date * system in Excel for Windows, date_text must represent a date from @@ -35,7 +35,7 @@ class DateValue * #VALUE! error value if date_text is out of this range. * Or can be an array of date values * - * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions @@ -86,6 +86,7 @@ class DateValue return self::finalResults($PHPDateArray, $dti, $baseYear); } + /** @param mixed[] $t1 */ private static function t1ToString(array $t1, DateTimeImmutable $dti, bool $yearFound): string { if (count($t1) == 2) { @@ -108,6 +109,8 @@ class DateValue /** * Parse date. + * + * @return mixed[] */ private static function setUpArray(string $dateValue, DateTimeImmutable $dti): array { @@ -132,6 +135,8 @@ class DateValue /** * Final results. * + * @param mixed[] $PHPDateArray + * * @return DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ @@ -139,6 +144,7 @@ class DateValue { $retValue = ExcelError::Value(); if (Helpers::dateParseSucceeded($PHPDateArray)) { + /** @var array{year: int, month: int, day: int, hour: int, minute: int, second: int} $PHPDateArray */ // Execute function Helpers::replaceIfEmpty($PHPDateArray['year'], $dti->format('Y')); if ($PHPDateArray['year'] < $baseYear) { @@ -146,12 +152,13 @@ class DateValue } Helpers::replaceIfEmpty($PHPDateArray['month'], $dti->format('m')); Helpers::replaceIfEmpty($PHPDateArray['day'], $dti->format('d')); + /** @var array{year: int, month: int, day: int, hour: int, minute: int, second: int} $PHPDateArray */ $PHPDateArray['hour'] = 0; $PHPDateArray['minute'] = 0; $PHPDateArray['second'] = 0; - $month = (int) $PHPDateArray['month']; - $day = (int) $PHPDateArray['day']; - $year = (int) $PHPDateArray['year']; + $month = self::getInt($PHPDateArray, 'month'); + $day = self::getInt($PHPDateArray, 'day'); + $year = self::getInt($PHPDateArray, 'year'); if (!checkdate($month, $day, $year)) { return ($year === 1900 && $month === 2 && $day === 29) ? Helpers::returnIn3FormatsFloat(60.0) : ExcelError::VALUE(); } @@ -160,4 +167,10 @@ class DateValue return $retValue; } + + /** @param mixed[] $array */ + private static function getInt(array $array, string $index): int + { + return (array_key_exists($index, $array) && is_numeric($array[$index])) ? (int) $array[$index] : 0; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php index b80e625..a3e5058 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php @@ -20,14 +20,14 @@ class Days * Excel Function: * DAYS(endDate, startDate) * - * @param array|DateTimeInterface|float|int|string $endDate Excel date serial value (float), + * @param array|DateTimeInterface|float|int|string $endDate Excel date serial value (float), * PHP date timestamp (integer), PHP DateTime object, or a standard date string * Or can be an array of date values - * @param array|DateTimeInterface|float|int|string $startDate Excel date serial value (float), + * @param array|DateTimeInterface|float|int|string $startDate Excel date serial value (float), * PHP date timestamp (integer), PHP DateTime object, or a standard date string * Or can be an array of date values * - * @return array|int|string Number of days between start date and end date or an error + * @return array|int|string Number of days between start date and end date or an error * If an array of values is passed for the $startDate or $endDays,arguments, then the returned result * will also be an array with matching dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php index c7e03fc..2ccadf5 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php @@ -40,7 +40,7 @@ class Days360 * same month. * Or can be an array of methods * - * @return array|int|string Number of days between start date and end date + * @return array|int|string Number of days between start date and end date * If an array of values is passed for the $startDate or $endDays,arguments, then the returned result * will also be an array with matching dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Difference.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Difference.php index 199d5d8..748586d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Difference.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Difference.php @@ -22,9 +22,9 @@ class Difference * @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object * or a standard date string * Or can be an array of date values - * @param array|string $unit Or can be an array of unit values + * @param array|string $unit Or can be an array of unit values * - * @return array|int|string Interval between the dates + * @return array|int|string Interval between the dates * If an array of values is passed for the $startDate or $endDays,arguments, then the returned result * will also be an array with matching dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php index 04d58a9..ee1d486 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php @@ -44,7 +44,9 @@ class Helpers if (!is_numeric($dateValue)) { $saveReturnDateType = Functions::getReturnDateType(); Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - $dateValue = DateValue::fromString($dateValue); + if (is_string($dateValue)) { + $dateValue = DateValue::fromString($dateValue); + } Functions::setReturnDateType($saveReturnDateType); if (!is_numeric($dateValue)) { throw new Exception(ExcelError::VALUE()); @@ -75,8 +77,10 @@ class Helpers /** * Adjust date by given months. + * + * @param float|int $dateValue date to be adjusted */ - public static function adjustDateByMonths(mixed $dateValue = 0, float $adjustmentMonths = 0): DateTime + public static function adjustDateByMonths($dateValue = 0, float $adjustmentMonths = 0): DateTime { // Execute function $PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue); @@ -127,6 +131,8 @@ class Helpers /** * Return result in one of three formats. + * + * @param array{year: int, month: int, day: int, hour: int, minute: int, second: int} $dateArray */ public static function returnIn3FormatsArray(array $dateArray, bool $noFrac = false): DateTime|float|int { @@ -264,11 +270,16 @@ class Helpers } } + /** @return array{year: int, month: int, day: int, hour: int, minute: int, second: int} */ public static function dateParse(string $string): array { - return self::forceArray(date_parse($string)); + /** @var array{year: int, month: int, day: int, hour: int, minute: int, second: int} */ + $temp = self::forceArray(date_parse($string)); + + return $temp; } + /** @param mixed[] $dateArray */ public static function dateParseSucceeded(array $dateArray): bool { return $dateArray['error_count'] === 0; @@ -278,10 +289,19 @@ class Helpers * Despite documentation, date_parse probably never returns false. * Just in case, this routine helps guarantee it. * - * @param array|false $dateArray + * @param array|false $dateArray + * + * @return mixed[] */ private static function forceArray(array|bool $dateArray): array { return is_array($dateArray) ? $dateArray : ['error_count' => 1]; } + + public static function floatOrInt(mixed $value): float|int + { + $result = Functions::scalar($value); + + return is_numeric($result) ? ($result + 0) : 0; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Month.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Month.php index a90c051..74fd50e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Month.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Month.php @@ -24,12 +24,12 @@ class Month * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * Or can be an array of date values - * @param array|int $adjustmentMonths The number of months before or after start_date. + * @param array|int $adjustmentMonths The number of months before or after start_date. * A positive value for months yields a future date; * a negative value yields a past date. * Or can be an array of adjustment values * - * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions @@ -68,12 +68,12 @@ class Month * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * Or can be an array of date values - * @param array|int $adjustmentMonths The number of months before or after start_date. + * @param array|int $adjustmentMonths The number of months before or after start_date. * A positive value for months yields a future date; * a negative value yields a past date. * Or can be an array of adjustment values * - * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php index 503e30e..2f1d96b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php @@ -29,7 +29,7 @@ class NetworkDays * Or can be an array of date values * @param mixed $dateArgs An array of dates (such as holidays) to exclude from the calculation * - * @return array|int|string Interval between the dates + * @return array|int|string Interval between the dates * If an array of values is passed for the $startDate or $endDate arguments, then the returned result * will also be an array with matching dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php index d1dc271..65c4d79 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php @@ -24,21 +24,21 @@ class Time * Excel Function: * TIME(hour,minute,second) * - * @param null|array|bool|float|int|string $hour A number from 0 (zero) to 32767 representing the hour. + * @param null|array|bool|float|int|string $hour A number from 0 (zero) to 32767 representing the hour. * Any value greater than 23 will be divided by 24 and the remainder * will be treated as the hour value. For example, TIME(27,0,0) = * TIME(3,0,0) = .125 or 3:00 AM. - * @param null|array|bool|float|int|string $minute A number from 0 to 32767 representing the minute. + * @param null|array|bool|float|int|string $minute A number from 0 to 32767 representing the minute. * Any value greater than 59 will be converted to hours and minutes. * For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM. - * @param null|array|bool|float|int|string $second A number from 0 to 32767 representing the second. + * @param null|array|bool|float|int|string $second A number from 0 to 32767 representing the second. * Any value greater than 59 will be converted to hours, minutes, * and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148 * or 12:33:20 AM * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions * - * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeParts.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeParts.php index de52269..a7f415d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeParts.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeParts.php @@ -23,7 +23,7 @@ class TimeParts * PHP DateTime object, or a standard time string * Or can be an array of date/time values * - * @return array|int|string Hour + * @return array|int|string Hour * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -35,7 +35,7 @@ class TimeParts try { Helpers::nullFalseTrueToNumber($timeValue); - if (!is_numeric($timeValue)) { + if (is_string($timeValue) && !is_numeric($timeValue)) { $timeValue = Helpers::getTimeValue($timeValue); } Helpers::validateNotNegative($timeValue); @@ -64,7 +64,7 @@ class TimeParts * PHP DateTime object, or a standard time string * Or can be an array of date/time values * - * @return array|int|string Minute + * @return array|int|string Minute * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -76,7 +76,7 @@ class TimeParts try { Helpers::nullFalseTrueToNumber($timeValue); - if (!is_numeric($timeValue)) { + if (is_string($timeValue) && !is_numeric($timeValue)) { $timeValue = Helpers::getTimeValue($timeValue); } Helpers::validateNotNegative($timeValue); @@ -105,7 +105,7 @@ class TimeParts * PHP DateTime object, or a standard time string * Or can be an array of date/time values * - * @return array|int|string Second + * @return array|int|string Second * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -117,7 +117,7 @@ class TimeParts try { Helpers::nullFalseTrueToNumber($timeValue); - if (!is_numeric($timeValue)) { + if (is_string($timeValue) && !is_numeric($timeValue)) { $timeValue = Helpers::getTimeValue($timeValue); } Helpers::validateNotNegative($timeValue); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php index 0f3218e..fc1f72c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php @@ -39,13 +39,13 @@ class TimeValue * Excel Function: * TIMEVALUE(timeValue) * - * @param null|array|bool|float|int|string $timeValue A text string that represents a time in any one of the Microsoft + * @param null|array|bool|float|int|string $timeValue A text string that represents a time in any one of the Microsoft * Excel time formats; for example, "6:45 PM" and "18:45" text strings * within quotation marks that represent time. * Date information in time_text is ignored. * Or can be an array of date/time values * - * @return array|Datetime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * @return array|Datetime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Week.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Week.php index e620b4c..080a57b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Week.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/Week.php @@ -28,7 +28,7 @@ class Week * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * Or can be an array of date values - * @param array|int $method Week begins on Sunday or Monday + * @param array|int $method Week begins on Sunday or Monday * 1 or omitted Week begins on Sunday. * 2 Week begins on Monday. * 11 Week begins on Monday. @@ -41,7 +41,7 @@ class Week * 21 ISO (Jan. 4 is week 1, begins on Monday). * Or can be an array of methods * - * @return array|int|string Week Number + * @return array|int|string Week Number * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -101,7 +101,7 @@ class Week * PHP DateTime object, or a standard date string * Or can be an array of date values * - * @return array|int|string Week Number + * @return array|int|string Week Number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -137,7 +137,7 @@ class Week * Excel Function: * WEEKDAY(dateValue[,style]) * - * @param null|array|bool|float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer), + * @param null|array|bool|float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * Or can be an array of date values * @param mixed $style A number that determines the type of return value @@ -146,7 +146,7 @@ class Week * 3 Numbers 0 (Monday) through 6 (Sunday). * Or can be an array of styles * - * @return array|int|string Day of the week value + * @return array|int|string Day of the week value * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php index 4e4ed3c..8465864 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php @@ -22,16 +22,16 @@ class WorkDay * Excel Function: * WORKDAY(startDate,endDays[,holidays[,holiday[,...]]]) * - * @param array|mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * @param array|mixed $startDate Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * Or can be an array of date values - * @param array|int $endDays The number of nonweekend and nonholiday days before or after + * @param array|int $endDays The number of nonweekend and nonholiday days before or after * startDate. A positive value for days yields a future date; a * negative value yields a past date. * Or can be an array of int values * @param null|mixed $dateArgs An array of dates (such as holidays) to exclude from the calculation * - * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * @return array|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag * If an array of values is passed for the $startDate or $endDays,arguments, then the returned result * will also be an array with matching dimensions @@ -72,6 +72,8 @@ class WorkDay /** * Use incrementing logic to determine Workday. + * + * @param array $holidayArray */ private static function incrementing(float $startDate, int $endDays, array $holidayArray): float|int|DateTime { @@ -103,10 +105,12 @@ class WorkDay return Helpers::returnIn3FormatsFloat($endDate); } + /** @param array $holidayArray */ private static function incrementingArray(float $startDate, float $endDate, array $holidayArray): float { $holidayCountedArray = $holidayDates = []; foreach ($holidayArray as $holidayDate) { + /** @var float $holidayDate */ if (self::getWeekDay($holidayDate, 3) < 5) { $holidayDates[] = $holidayDate; } @@ -131,6 +135,8 @@ class WorkDay /** * Use decrementing logic to determine Workday. + * + * @param array $holidayArray */ private static function decrementing(float $startDate, int $endDays, array $holidayArray): float|int|DateTime { @@ -162,10 +168,12 @@ class WorkDay return Helpers::returnIn3FormatsFloat($endDate); } + /** @param array $holidayArray */ private static function decrementingArray(float $startDate, float $endDate, array $holidayArray): float { $holidayCountedArray = $holidayDates = []; foreach ($holidayArray as $holidayDate) { + /** @var float $holidayDate */ if (self::getWeekDay($holidayDate, 3) < 5) { $holidayDates[] = $holidayDate; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php index 2713754..6b3d0f4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php @@ -31,7 +31,7 @@ class YearFrac * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * Or can be an array of methods - * @param array|int $method Method used for the calculation + * @param array|int $method Method used for the calculation * 0 or omitted US (NASD) 30/360 * 1 Actual/actual * 2 Actual/360 @@ -39,7 +39,7 @@ class YearFrac * 4 European 30/360 * Or can be an array of methods * - * @return array|float|int|string fraction of the year, or a string containing an error + * @return array|float|int|string fraction of the year, or a string containing an error * If an array of values is passed for the $startDate or $endDays,arguments, then the returned result * will also be an array with matching dimensions */ @@ -62,11 +62,11 @@ class YearFrac } return match ($method) { - 0 => Functions::scalar(Days360::between($startDate, $endDate)) / 360, + 0 => Helpers::floatOrInt(Days360::between($startDate, $endDate)) / 360, 1 => self::method1($startDate, $endDate), - 2 => Functions::scalar(Difference::interval($startDate, $endDate)) / 360, - 3 => Functions::scalar(Difference::interval($startDate, $endDate)) / 365, - 4 => Functions::scalar(Days360::between($startDate, $endDate, true)) / 360, + 2 => Helpers::floatOrInt(Difference::interval($startDate, $endDate)) / 360, + 3 => Helpers::floatOrInt(Difference::interval($startDate, $endDate)) / 365, + 4 => Helpers::floatOrInt(Days360::between($startDate, $endDate, true)) / 360, default => ExcelError::NAN(), }; } @@ -91,7 +91,7 @@ class YearFrac private static function method1(float $startDate, float $endDate): float { - $days = Functions::scalar(Difference::interval($startDate, $endDate)); + $days = Helpers::floatOrInt(Difference::interval($startDate, $endDate)); $startYear = (int) DateParts::year($startDate); $endYear = (int) DateParts::year($endDate); $years = $endYear - $startYear + 1; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php index aa2019e..9b4e6c0 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php @@ -8,14 +8,18 @@ class ArrayArgumentHelper { protected int $indexStart = 0; + /** @var mixed[] */ protected array $arguments; protected int $argumentCount; + /** @var int[] */ protected array $rows; + /** @var int[] */ protected array $columns; + /** @param mixed[] $arguments */ public function initialise(array $arguments): void { $keys = array_keys($arguments); @@ -34,6 +38,7 @@ class ArrayArgumentHelper } } + /** @return mixed[] */ public function arguments(): array { return $this->arguments; @@ -65,6 +70,7 @@ class ArrayArgumentHelper return count($rowVectors) === 1 ? array_pop($rowVectors) : null; } + /** @return int[] */ private function getRowVectors(): array { $rowVectors = []; @@ -84,6 +90,7 @@ class ArrayArgumentHelper return count($columnVectors) === 1 ? array_pop($columnVectors) : null; } + /** @return int[] */ private function getColumnVectors(): array { $columnVectors = []; @@ -96,6 +103,7 @@ class ArrayArgumentHelper return $columnVectors; } + /** @return int[] */ public function getMatrixPair(): array { for ($i = $this->indexStart; $i < ($this->indexStart + $this->argumentCount - 1); ++$i) { @@ -134,6 +142,11 @@ class ArrayArgumentHelper return $this->columns[$argument]; } + /** + * @param mixed[] $arguments + * + * @return int[] + */ private function rows(array $arguments): array { return array_map( @@ -142,6 +155,11 @@ class ArrayArgumentHelper ); } + /** + * @param mixed[] $arguments + * + * @return int[] + */ private function columns(array $arguments): array { return array_map( @@ -164,6 +182,13 @@ class ArrayArgumentHelper return $count; } + /** + * @param mixed[] $arguments + * @param int[] $rows + * @param int[] $columns + * + * @return mixed[] + */ private function flattenSingleCellArrays(array $arguments, array $rows, array $columns): array { foreach ($arguments as $index => $argument) { @@ -178,6 +203,11 @@ class ArrayArgumentHelper return $arguments; } + /** + * @param mixed[] $array + * + * @return mixed[] + */ private function filterArray(array $array): array { return array_filter( diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php index fb2c853..687ab1b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php @@ -2,12 +2,14 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Engine; +use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class ArrayArgumentProcessor { private static ArrayArgumentHelper $arrayArgumentHelper; + /** @return mixed[] */ public static function processArguments( ArrayArgumentHelper $arrayArgumentHelper, callable $method, @@ -54,23 +56,30 @@ class ArrayArgumentProcessor return ['#VALUE!']; } + /** + * @param int[] $matrixIndexes + * + * @return mixed[] + */ private static function evaluateVectorMatrixPair(callable $method, array $matrixIndexes, mixed ...$arguments): array { - $matrix2 = array_pop($matrixIndexes); - /** @var array $matrixValues2 */ + $matrix2 = array_pop($matrixIndexes) ?? throw new Exception('empty array 2'); + /** @var mixed[][] $matrixValues2 */ $matrixValues2 = $arguments[$matrix2]; - $matrix1 = array_pop($matrixIndexes); - /** @var array $matrixValues1 */ + $matrix1 = array_pop($matrixIndexes) ?? throw new Exception('empty array 1'); + /** @var mixed[][] $matrixValues1 */ $matrixValues1 = $arguments[$matrix1]; - $rows = min(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2])); - $columns = min(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2])); + /** @var non-empty-array */ + $matrix12 = [$matrix1, $matrix2]; + $rows = min(array_map(self::$arrayArgumentHelper->rowCount(...), $matrix12)); + $columns = min(array_map(self::$arrayArgumentHelper->columnCount(...), $matrix12)); if ($rows === 1) { - $rows = max(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2])); + $rows = max(array_map(self::$arrayArgumentHelper->rowCount(...), $matrix12)); } if ($columns === 1) { - $columns = max(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2])); + $columns = max(array_map(self::$arrayArgumentHelper->columnCount(...), $matrix12)); } $result = []; @@ -92,13 +101,18 @@ class ArrayArgumentProcessor return $result; } + /** + * @param array $matrixIndexes + * + * @return mixed[] + */ private static function evaluateMatrixPair(callable $method, array $matrixIndexes, mixed ...$arguments): array { $matrix2 = array_pop($matrixIndexes); - /** @var array $matrixValues2 */ + /** @var mixed[][] $matrixValues2 */ $matrixValues2 = $arguments[$matrix2]; $matrix1 = array_pop($matrixIndexes); - /** @var array $matrixValues1 */ + /** @var mixed[][] $matrixValues1 */ $matrixValues1 = $arguments[$matrix1]; $result = []; @@ -119,6 +133,7 @@ class ArrayArgumentProcessor return $result; } + /** @return mixed[] */ private static function evaluateVectorPair(callable $method, int $rowIndex, int $columnIndex, mixed ...$arguments): array { $rowVector = Functions::flattenArray($arguments[$rowIndex]); @@ -141,11 +156,13 @@ class ArrayArgumentProcessor /** * Note, offset is from 1 (for the first argument) rather than from 0. + * + * @return mixed[] */ private static function evaluateNthArgumentAsArray(callable $method, int $nthArgument, mixed ...$arguments): array { $values = array_slice($arguments, $nthArgument - 1, 1); - /** @var array $values */ + /** @var mixed[] $values */ $values = array_pop($values); $result = []; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/BranchPruner.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/BranchPruner.php index e6dbbcb..97e4c95 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/BranchPruner.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/BranchPruner.php @@ -78,7 +78,7 @@ class BranchPruner private function initialiseCondition(): void { - if (isset($this->conditionMap[$this->pendingStoreKey]) && $this->conditionMap[$this->pendingStoreKey]) { + if (isset($this->pendingStoreKey, $this->conditionMap[$this->pendingStoreKey]) && $this->conditionMap[$this->pendingStoreKey]) { $this->currentCondition = $this->pendingStoreKey; $stackDepth = count($this->storeKeysStack); if ($stackDepth > 1) { @@ -90,7 +90,7 @@ class BranchPruner private function initialiseThen(): void { - if (isset($this->thenMap[$this->pendingStoreKey]) && $this->thenMap[$this->pendingStoreKey]) { + if (isset($this->pendingStoreKey, $this->thenMap[$this->pendingStoreKey]) && $this->thenMap[$this->pendingStoreKey]) { $this->currentOnlyIf = $this->pendingStoreKey; } elseif ( isset($this->previousStoreKey, $this->thenMap[$this->previousStoreKey]) @@ -102,7 +102,7 @@ class BranchPruner private function initialiseElse(): void { - if (isset($this->elseMap[$this->pendingStoreKey]) && $this->elseMap[$this->pendingStoreKey]) { + if (isset($this->pendingStoreKey, $this->elseMap[$this->pendingStoreKey]) && $this->elseMap[$this->pendingStoreKey]) { $this->currentOnlyIfNot = $this->pendingStoreKey; } elseif ( isset($this->previousStoreKey, $this->elseMap[$this->previousStoreKey]) diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/CyclicReferenceStack.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/CyclicReferenceStack.php index f4806b4..c50fad6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/CyclicReferenceStack.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/CyclicReferenceStack.php @@ -21,8 +21,10 @@ class CyclicReferenceStack /** * Push a new entry onto the stack. + * + * @param int|string $value The value to test */ - public function push(mixed $value): void + public function push($value): void { $this->stack[$value] = $value; } @@ -38,9 +40,9 @@ class CyclicReferenceStack /** * Test to see if a specified entry exists on the stack. * - * @param mixed $value The value to test + * @param int|string $value The value to test */ - public function onStack(mixed $value): bool + public function onStack($value): bool { return isset($this->stack[$value]); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/FormattedNumber.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/FormattedNumber.php index ee1f2ae..c64c8d2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/FormattedNumber.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/FormattedNumber.php @@ -16,28 +16,18 @@ class FormattedNumber // preg_quoted string for major currency symbols, with a %s for locale currency private const CURRENCY_CONVERSION_LIST = '\$€£¥%s'; - private const STRING_CONVERSION_LIST = [ - [self::class, 'convertToNumberIfNumeric'], - [self::class, 'convertToNumberIfFraction'], - [self::class, 'convertToNumberIfPercent'], - [self::class, 'convertToNumberIfCurrency'], - ]; - /** * Identify whether a string contains a formatted numeric value, * and convert it to a numeric if it is. * - * @param string $operand string value to test + * @param float|string $operand string value to test */ - public static function convertToNumberIfFormatted(string &$operand): bool + public static function convertToNumberIfFormatted(float|string &$operand): bool { - foreach (self::STRING_CONVERSION_LIST as $conversionMethod) { - if ($conversionMethod($operand) === true) { - return true; - } - } - - return false; + return self::convertToNumberIfNumeric($operand) + || self::convertToNumberIfFraction($operand) + || self::convertToNumberIfPercent($operand) + || self::convertToNumberIfCurrency($operand); } /** @@ -68,13 +58,15 @@ class FormattedNumber * * @param string $operand string value to test */ - public static function convertToNumberIfFraction(string &$operand): bool + public static function convertToNumberIfFraction(float|string &$operand): bool { - if (preg_match(self::STRING_REGEXP_FRACTION, $operand, $match)) { + if (is_string($operand) && preg_match(self::STRING_REGEXP_FRACTION, $operand, $match)) { $sign = ($match[1] === '-') ? '-' : '+'; $wholePart = ($match[3] === '') ? '' : ($sign . $match[3]); $fractionFormula = '=' . $wholePart . $sign . $match[4]; - $operand = Calculation::getInstance()->_calculateFormulaValue($fractionFormula); + /** @var string */ + $operandx = Calculation::getInstance()->_calculateFormulaValue($fractionFormula); + $operand = $operandx; return true; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Logger.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Logger.php index 9adcd55..e82faf5 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Logger.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Logger.php @@ -78,7 +78,7 @@ class Logger { // Only write the debug log if logging is enabled if ($this->writeDebugLog) { - $message = sprintf($message, ...$args); + $message = sprintf($message, ...$args); //* @phpstan-ignore-line $cellReference = implode(' -> ', $this->cellStack->showStack()); if ($this->echoDebugLog) { echo $cellReference, diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/Operand.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/Operand.php index 05264c3..87a733f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/Operand.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/Operand.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Engine\Operands; interface Operand { + /** @param string[] $matches */ public static function fromParser(string $formula, int $index, array $matches): self; public function value(): string; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/StructuredReference.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/StructuredReference.php index 15c8762..9c4cf72 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/StructuredReference.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Operands/StructuredReference.php @@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Worksheet\Table; use Stringable; @@ -47,6 +48,7 @@ final class StructuredReference implements Operand, Stringable private ?int $totalsRow; + /** @var mixed[] */ private array $columns; public function __construct(string $structuredReference) @@ -54,6 +56,7 @@ final class StructuredReference implements Operand, Stringable $this->value = $structuredReference; } + /** @param string[] $matches */ public static function fromParser(string $formula, int $index, array $matches): self { $val = $matches[0]; @@ -171,14 +174,20 @@ final class StructuredReference implements Operand, Stringable return $table; } + /** + * @param array{array{string, int}, array{string, int}} $tableRange + * + * @return mixed[] + */ private function getColumns(Cell $cell, array $tableRange): array { $worksheet = $cell->getWorksheet(); $cellReference = $cell->getCoordinate(); $columns = []; - $lastColumn = ++$tableRange[1][0]; - for ($column = $tableRange[0][0]; $column !== $lastColumn; ++$column) { + $lastColumn = StringHelper::stringIncrement($tableRange[1][0]); + for ($column = $tableRange[0][0]; $column !== $lastColumn; StringHelper::stringIncrement($column)) { + /** @var string $column */ $columns[$column] = $worksheet ->getCell($column . ($this->headersRow ?? ($this->firstDataRow - 1))) ->getCalculatedValue(); @@ -196,7 +205,7 @@ final class StructuredReference implements Operand, Stringable $reference = str_replace('[' . self::ITEM_SPECIFIER_THIS_ROW . '],', '', $reference); foreach ($this->columns as $columnId => $columnName) { - $columnName = str_replace("\u{a0}", ' ', $columnName); + $columnName = str_replace("\u{a0}", ' ', $columnName); //* @phpstan-ignore-line $reference = $this->adjustRowReference($columnName, $reference, $cell, $columnId); } @@ -330,7 +339,7 @@ final class StructuredReference implements Operand, Stringable { $columnsSelected = false; foreach ($this->columns as $columnId => $columnName) { - $columnName = str_replace("\u{a0}", ' ', $columnName ?? ''); + $columnName = str_replace("\u{a0}", ' ', $columnName ?? ''); //* @phpstan-ignore-line $cellFrom = "{$columnId}{$startRow}"; $cellTo = "{$columnId}{$endRow}"; $cellReference = ($cellFrom === $cellTo) ? $cellFrom : "{$cellFrom}:{$cellTo}"; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselI.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselI.php index 5d564a0..7f67806 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselI.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselI.php @@ -31,7 +31,7 @@ class BesselI * If $ord < 0, BESSELI returns the #NUM! error value. * Or can be an array of values * - * @return array|float|string Result, or a string containing an error + * @return array|float|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php index 4a9d9ff..58ae258 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php @@ -30,7 +30,7 @@ class BesselJ * If $ord < 0, BESSELJ returns the #NUM! error value. * Or can be an array of values * - * @return array|float|string Result, or a string containing an error + * @return array|float|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselK.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselK.php index 5a9bd54..13e85cb 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselK.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselK.php @@ -28,7 +28,7 @@ class BesselK * If $ord < 0, BESSELKI returns the #NUM! error value. * Or can be an array of values * - * @return array|float|string Result, or a string containing an error + * @return array|float|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselY.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselY.php index 5d99638..c65a01b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselY.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BesselY.php @@ -27,7 +27,7 @@ class BesselY * If $ord < 0, BESSELY returns the #NUM! error value. * Or can be an array of values * - * @return array|float|string Result, or a string containing an error + * @return array|float|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BitWise.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BitWise.php index 47d94ec..65192bf 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BitWise.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/BitWise.php @@ -30,10 +30,10 @@ class BitWise * Excel Function: * BITAND(number1, number2) * - * @param null|array|bool|float|int|string $number1 Or can be an array of values - * @param null|array|bool|float|int|string $number2 Or can be an array of values + * @param null|array|bool|float|int|string $number1 Or can be an array of values + * @param null|array|bool|float|int|string $number2 Or can be an array of values * - * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITAND(null|array|bool|float|int|string $number1, null|array|bool|float|int|string $number2): array|string|int|float @@ -62,10 +62,10 @@ class BitWise * Excel Function: * BITOR(number1, number2) * - * @param null|array|bool|float|int|string $number1 Or can be an array of values - * @param null|array|bool|float|int|string $number2 Or can be an array of values + * @param null|array|bool|float|int|string $number1 Or can be an array of values + * @param null|array|bool|float|int|string $number2 Or can be an array of values * - * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITOR(null|array|bool|float|int|string $number1, null|array|bool|float|int|string $number2): array|string|int|float @@ -95,10 +95,10 @@ class BitWise * Excel Function: * BITXOR(number1, number2) * - * @param null|array|bool|float|int|string $number1 Or can be an array of values - * @param null|array|bool|float|int|string $number2 Or can be an array of values + * @param null|array|bool|float|int|string $number1 Or can be an array of values + * @param null|array|bool|float|int|string $number2 Or can be an array of values * - * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITXOR(null|array|bool|float|int|string $number1, null|array|bool|float|int|string $number2): array|string|int|float @@ -128,10 +128,10 @@ class BitWise * Excel Function: * BITLSHIFT(number, shift_amount) * - * @param null|array|bool|float|int|string $number Or can be an array of values - * @param null|array|bool|float|int|string $shiftAmount Or can be an array of values + * @param null|array|bool|float|int|string $number Or can be an array of values + * @param null|array|bool|float|int|string $shiftAmount Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITLSHIFT(null|array|bool|float|int|string $number, null|array|bool|float|int|string $shiftAmount): array|string|float @@ -163,10 +163,10 @@ class BitWise * Excel Function: * BITRSHIFT(number, shift_amount) * - * @param null|array|bool|float|int|string $number Or can be an array of values - * @param null|array|bool|float|int|string $shiftAmount Or can be an array of values + * @param null|array|bool|float|int|string $number Or can be an array of values + * @param null|array|bool|float|int|string $shiftAmount Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function BITRSHIFT(null|array|bool|float|int|string $number, null|array|bool|float|int|string $shiftAmount): array|string|float diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Compare.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Compare.php index 9e3275f..ac7ef51 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Compare.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Compare.php @@ -20,12 +20,12 @@ class Compare * functions you calculate the count of equal pairs. This function is also known as the * Kronecker Delta function. * - * @param array|bool|float|int|string $a the first number + * @param array|bool|float|int|string $a the first number * Or can be an array of values - * @param array|bool|float|int|string $b The second number. If omitted, b is assumed to be zero. + * @param array|bool|float|int|string $b The second number. If omitted, b is assumed to be zero. * Or can be an array of values * - * @return array|int|string (string in the event of an error) + * @return array|int|string (string in the event of an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -55,12 +55,12 @@ class Compare * Use this function to filter a set of values. For example, by summing several GESTEP * functions you calculate the count of values that exceed a threshold. * - * @param array|bool|float|int|string $number the value to test against step + * @param array|bool|float|int|string $number the value to test against step * Or can be an array of values - * @param null|array|bool|float|int|string $step The threshold value. If you omit a value for step, GESTEP uses zero. + * @param null|array|bool|float|int|string $step The threshold value. If you omit a value for step, GESTEP uses zero. * Or can be an array of values * - * @return array|int|string (string in the event of an error) + * @return array|int|string (string in the event of an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Complex.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Complex.php index 3e41371..83d110c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Complex.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Complex.php @@ -28,7 +28,7 @@ class Complex * If omitted, the suffix is assumed to be "i". * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function COMPLEX(mixed $realNumber = 0.0, mixed $imaginary = 0.0, mixed $suffix = 'i'): array|string @@ -65,11 +65,11 @@ class Complex * Excel Function: * IMAGINARY(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the imaginary + * @param array|string $complexNumber the complex number for which you want the imaginary * coefficient * Or can be an array of values * - * @return array|float|string (string if an error) + * @return array|float|string (string if an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -96,10 +96,10 @@ class Complex * Excel Function: * IMREAL(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the real coefficient + * @param array|string $complexNumber the complex number for which you want the real coefficient * Or can be an array of values * - * @return array|float|string (string if an error) + * @return array|float|string (string if an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php index d1b7764..5dd51be 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php @@ -19,10 +19,10 @@ class ComplexFunctions * Excel Function: * IMABS(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the absolute value + * @param array|string $complexNumber the complex number for which you want the absolute value * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMABS(array|string $complexNumber): array|float|string @@ -49,10 +49,10 @@ class ComplexFunctions * Excel Function: * IMARGUMENT(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the argument theta + * @param array|string $complexNumber the complex number for which you want the argument theta * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMARGUMENT(array|string $complexNumber): array|float|string @@ -82,10 +82,10 @@ class ComplexFunctions * Excel Function: * IMCONJUGATE(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the conjugate + * @param array|string $complexNumber the complex number for which you want the conjugate * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCONJUGATE(array|string $complexNumber): array|string @@ -111,10 +111,10 @@ class ComplexFunctions * Excel Function: * IMCOS(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the cosine + * @param array|string $complexNumber the complex number for which you want the cosine * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCOS(array|string $complexNumber): array|string @@ -140,10 +140,10 @@ class ComplexFunctions * Excel Function: * IMCOSH(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the hyperbolic cosine + * @param array|string $complexNumber the complex number for which you want the hyperbolic cosine * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCOSH(array|string $complexNumber): array|string @@ -169,10 +169,10 @@ class ComplexFunctions * Excel Function: * IMCOT(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the cotangent + * @param array|string $complexNumber the complex number for which you want the cotangent * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCOT(array|string $complexNumber): array|string @@ -198,10 +198,10 @@ class ComplexFunctions * Excel Function: * IMCSC(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the cosecant + * @param array|string $complexNumber the complex number for which you want the cosecant * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCSC(array|string $complexNumber): array|string @@ -227,10 +227,10 @@ class ComplexFunctions * Excel Function: * IMCSCH(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the hyperbolic cosecant + * @param array|string $complexNumber the complex number for which you want the hyperbolic cosecant * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMCSCH(array|string $complexNumber): array|string @@ -256,10 +256,10 @@ class ComplexFunctions * Excel Function: * IMSIN(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the sine + * @param array|string $complexNumber the complex number for which you want the sine * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSIN(array|string $complexNumber): array|string @@ -285,10 +285,10 @@ class ComplexFunctions * Excel Function: * IMSINH(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the hyperbolic sine + * @param array|string $complexNumber the complex number for which you want the hyperbolic sine * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSINH(array|string $complexNumber): array|string @@ -314,10 +314,10 @@ class ComplexFunctions * Excel Function: * IMSEC(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the secant + * @param array|string $complexNumber the complex number for which you want the secant * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSEC(array|string $complexNumber): array|string @@ -343,10 +343,10 @@ class ComplexFunctions * Excel Function: * IMSECH(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the hyperbolic secant + * @param array|string $complexNumber the complex number for which you want the hyperbolic secant * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSECH(array|string $complexNumber): array|string @@ -372,10 +372,10 @@ class ComplexFunctions * Excel Function: * IMTAN(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the tangent + * @param array|string $complexNumber the complex number for which you want the tangent * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMTAN(array|string $complexNumber): array|string @@ -401,10 +401,10 @@ class ComplexFunctions * Excel Function: * IMSQRT(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the square root + * @param array|string $complexNumber the complex number for which you want the square root * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSQRT(array|string $complexNumber): array|string @@ -435,10 +435,10 @@ class ComplexFunctions * Excel Function: * IMLN(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the natural logarithm + * @param array|string $complexNumber the complex number for which you want the natural logarithm * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMLN(array|string $complexNumber): array|string @@ -468,10 +468,10 @@ class ComplexFunctions * Excel Function: * IMLOG10(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the common logarithm + * @param array|string $complexNumber the complex number for which you want the common logarithm * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMLOG10(array|string $complexNumber): array|string @@ -501,10 +501,10 @@ class ComplexFunctions * Excel Function: * IMLOG2(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the base-2 logarithm + * @param array|string $complexNumber the complex number for which you want the base-2 logarithm * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMLOG2(array|string $complexNumber): array|string @@ -534,10 +534,10 @@ class ComplexFunctions * Excel Function: * IMEXP(complexNumber) * - * @param array|string $complexNumber the complex number for which you want the exponential + * @param array|string $complexNumber the complex number for which you want the exponential * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMEXP(array|string $complexNumber): array|string @@ -563,12 +563,12 @@ class ComplexFunctions * Excel Function: * IMPOWER(complexNumber,realNumber) * - * @param array|string $complexNumber the complex number you want to raise to a power + * @param array|string $complexNumber the complex number you want to raise to a power * Or can be an array of values - * @param array|float|int|string $realNumber the power to which you want to raise the complex number + * @param array|float|int|string $realNumber the power to which you want to raise the complex number * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMPOWER(array|string $complexNumber, array|float|int|string $realNumber): array|string diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexOperations.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexOperations.php index 61efa84..ed66bea 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexOperations.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ComplexOperations.php @@ -20,12 +20,12 @@ class ComplexOperations * Excel Function: * IMDIV(complexDividend,complexDivisor) * - * @param array|string $complexDividend the complex numerator or dividend + * @param array|string $complexDividend the complex numerator or dividend * Or can be an array of values - * @param array|string $complexDivisor the complex denominator or divisor + * @param array|string $complexDivisor the complex denominator or divisor * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMDIV(array|string $complexDividend, array|string $complexDivisor): array|string @@ -49,12 +49,12 @@ class ComplexOperations * Excel Function: * IMSUB(complexNumber1,complexNumber2) * - * @param array|string $complexNumber1 the complex number from which to subtract complexNumber2 + * @param array|string $complexNumber1 the complex number from which to subtract complexNumber2 * Or can be an array of values - * @param array|string $complexNumber2 the complex number to subtract from complexNumber1 + * @param array|string $complexNumber2 the complex number to subtract from complexNumber1 * Or can be an array of values * - * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function IMSUB(array|string $complexNumber1, array|string $complexNumber2): array|string diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBase.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBase.php index 1222831..6aa631a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBase.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBase.php @@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; abstract class ConvertBase { @@ -26,7 +27,7 @@ abstract class ConvertBase } } - return strtoupper((string) $value); + return strtoupper(StringHelper::convertToString($value)); } protected static function validatePlaces(mixed $places = null): ?int diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBinary.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBinary.php index 9c00dcb..3b84ce3 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBinary.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertBinary.php @@ -15,7 +15,7 @@ class ConvertBinary extends ConvertBase * Excel Function: * BIN2DEC(x) * - * @param array|bool|float|int|string $value The binary number (as a string) that you want to convert. The number + * @param array|bool|float|int|string $value The binary number (as a string) that you want to convert. The number * cannot contain more than 10 characters (10 bits). The most significant * bit of number is the sign bit. The remaining 9 bits are magnitude bits. * Negative numbers are represented using two's-complement notation. @@ -23,7 +23,7 @@ class ConvertBinary extends ConvertBase * 10 characters (10 bits), BIN2DEC returns the #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|float|int|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -44,10 +44,10 @@ class ConvertBinary extends ConvertBase // Two's Complement $value = substr($value, -9); - return '-' . (512 - bindec($value)); + return -(512 - bindec($value)); } - return (string) bindec($value); + return bindec($value); } /** @@ -58,14 +58,14 @@ class ConvertBinary extends ConvertBase * Excel Function: * BIN2HEX(x[,places]) * - * @param array|bool|float|int|string $value The binary number (as a string) that you want to convert. The number + * @param array|bool|float|int|string $value The binary number (as a string) that you want to convert. The number * cannot contain more than 10 characters (10 bits). The most significant * bit of number is the sign bit. The remaining 9 bits are magnitude bits. * Negative numbers are represented using two's-complement notation. * If number is not a valid binary number, or if number contains more than * 10 characters (10 bits), BIN2HEX returns the #NUM! error value. * Or can be an array of values - * @param null|array|float|int|string $places The number of characters to use. If places is omitted, BIN2HEX uses the + * @param null|array|float|int|string $places The number of characters to use. If places is omitted, BIN2HEX uses the * minimum number of characters necessary. Places is useful for padding the * return value with leading 0s (zeros). * If places is not an integer, it is truncated. @@ -73,7 +73,7 @@ class ConvertBinary extends ConvertBase * If places is negative, BIN2HEX returns the #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -111,14 +111,14 @@ class ConvertBinary extends ConvertBase * Excel Function: * BIN2OCT(x[,places]) * - * @param array|bool|float|int|string $value The binary number (as a string) that you want to convert. The number + * @param array|bool|float|int|string $value The binary number (as a string) that you want to convert. The number * cannot contain more than 10 characters (10 bits). The most significant * bit of number is the sign bit. The remaining 9 bits are magnitude bits. * Negative numbers are represented using two's-complement notation. * If number is not a valid binary number, or if number contains more than * 10 characters (10 bits), BIN2OCT returns the #NUM! error value. * Or can be an array of values - * @param null|array|float|int|string $places The number of characters to use. If places is omitted, BIN2OCT uses the + * @param null|array|float|int|string $places The number of characters to use. If places is omitted, BIN2OCT uses the * minimum number of characters necessary. Places is useful for padding the * return value with leading 0s (zeros). * If places is not an integer, it is truncated. @@ -126,7 +126,7 @@ class ConvertBinary extends ConvertBase * If places is negative, BIN2OCT returns the #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertDecimal.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertDecimal.php index 923caa9..9834bcc 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertDecimal.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertDecimal.php @@ -22,7 +22,7 @@ class ConvertDecimal extends ConvertBase * Excel Function: * DEC2BIN(x[,places]) * - * @param array|bool|float|int|string $value The decimal integer you want to convert. If number is negative, + * @param array|bool|float|int|string $value The decimal integer you want to convert. If number is negative, * valid place values are ignored and DEC2BIN returns a 10-character * (10-bit) binary number in which the most significant bit is the sign * bit. The remaining 9 bits are magnitude bits. Negative numbers are @@ -33,7 +33,7 @@ class ConvertDecimal extends ConvertBase * If DEC2BIN requires more than places characters, it returns the #NUM! * error value. * Or can be an array of values - * @param null|array|float|int|string $places The number of characters to use. If places is omitted, DEC2BIN uses + * @param null|array|float|int|string $places The number of characters to use. If places is omitted, DEC2BIN uses * the minimum number of characters necessary. Places is useful for * padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. @@ -41,7 +41,7 @@ class ConvertDecimal extends ConvertBase * If places is zero or negative, DEC2BIN returns the #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -79,7 +79,7 @@ class ConvertDecimal extends ConvertBase * Excel Function: * DEC2HEX(x[,places]) * - * @param array|bool|float|int|string $value The decimal integer you want to convert. If number is negative, + * @param array|bool|float|int|string $value The decimal integer you want to convert. If number is negative, * places is ignored and DEC2HEX returns a 10-character (40-bit) * hexadecimal number in which the most significant bit is the sign * bit. The remaining 39 bits are magnitude bits. Negative numbers @@ -90,7 +90,7 @@ class ConvertDecimal extends ConvertBase * If DEC2HEX requires more than places characters, it returns the * #NUM! error value. * Or can be an array of values - * @param null|array|float|int|string $places The number of characters to use. If places is omitted, DEC2HEX uses + * @param null|array|float|int|string $places The number of characters to use. If places is omitted, DEC2HEX uses * the minimum number of characters necessary. Places is useful for * padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. @@ -98,7 +98,7 @@ class ConvertDecimal extends ConvertBase * If places is zero or negative, DEC2HEX returns the #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -155,7 +155,7 @@ class ConvertDecimal extends ConvertBase * Excel Function: * DEC2OCT(x[,places]) * - * @param array|bool|float|int|string $value The decimal integer you want to convert. If number is negative, + * @param array|bool|float|int|string $value The decimal integer you want to convert. If number is negative, * places is ignored and DEC2OCT returns a 10-character (30-bit) * octal number in which the most significant bit is the sign bit. * The remaining 29 bits are magnitude bits. Negative numbers are @@ -166,7 +166,7 @@ class ConvertDecimal extends ConvertBase * If DEC2OCT requires more than places characters, it returns the * #NUM! error value. * Or can be an array of values - * @param array|int $places The number of characters to use. If places is omitted, DEC2OCT uses + * @param array|int $places The number of characters to use. If places is omitted, DEC2OCT uses * the minimum number of characters necessary. Places is useful for * padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. @@ -174,7 +174,7 @@ class ConvertDecimal extends ConvertBase * If places is zero or negative, DEC2OCT returns the #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertHex.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertHex.php index 40eacf1..be8ed39 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertHex.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertHex.php @@ -15,7 +15,7 @@ class ConvertHex extends ConvertBase * Excel Function: * HEX2BIN(x[,places]) * - * @param array|bool|float|string $value The hexadecimal number you want to convert. + * @param array|bool|float|string $value The hexadecimal number you want to convert. * Number cannot contain more than 10 characters. * The most significant bit of number is the sign bit (40th bit from the right). * The remaining 9 bits are magnitude bits. @@ -26,7 +26,7 @@ class ConvertHex extends ConvertBase * If number is not a valid hexadecimal number, HEX2BIN returns the #NUM! error value. * If HEX2BIN requires more than places characters, it returns the #NUM! error value. * Or can be an array of values - * @param array|int $places The number of characters to use. If places is omitted, + * @param array|int $places The number of characters to use. If places is omitted, * HEX2BIN uses the minimum number of characters necessary. Places * is useful for padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. @@ -34,7 +34,7 @@ class ConvertHex extends ConvertBase * If places is negative, HEX2BIN returns the #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -65,7 +65,7 @@ class ConvertHex extends ConvertBase * Excel Function: * HEX2DEC(x) * - * @param array|bool|float|int|string $value The hexadecimal number you want to convert. This number cannot + * @param array|bool|float|int|string $value The hexadecimal number you want to convert. This number cannot * contain more than 10 characters (40 bits). The most significant * bit of number is the sign bit. The remaining 39 bits are magnitude * bits. Negative numbers are represented using two's-complement @@ -74,7 +74,7 @@ class ConvertHex extends ConvertBase * #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|float|int|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -104,10 +104,10 @@ class ConvertHex extends ConvertBase $binX[$i] = ($binX[$i] == '1' ? '0' : '1'); } - return (string) ((bindec($binX) + 1) * -1); + return (bindec($binX) + 1) * -1; } - return (string) bindec($binX); + return bindec($binX); } /** @@ -118,7 +118,7 @@ class ConvertHex extends ConvertBase * Excel Function: * HEX2OCT(x[,places]) * - * @param array|bool|float|int|string $value The hexadecimal number you want to convert. Number cannot + * @param array|bool|float|int|string $value The hexadecimal number you want to convert. Number cannot * contain more than 10 characters. The most significant bit of * number is the sign bit. The remaining 39 bits are magnitude * bits. Negative numbers are represented using two's-complement @@ -132,7 +132,7 @@ class ConvertHex extends ConvertBase * If HEX2OCT requires more than places characters, it returns * the #NUM! error value. * Or can be an array of values - * @param array|int $places The number of characters to use. If places is omitted, HEX2OCT + * @param array|int $places The number of characters to use. If places is omitted, HEX2OCT * uses the minimum number of characters necessary. Places is * useful for padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. @@ -141,7 +141,7 @@ class ConvertHex extends ConvertBase * If places is negative, HEX2OCT returns the #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertOctal.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertOctal.php index d6ef56c..03a906d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertOctal.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertOctal.php @@ -15,7 +15,7 @@ class ConvertOctal extends ConvertBase * Excel Function: * OCT2BIN(x[,places]) * - * @param array|bool|float|int|string $value The octal number you want to convert. Number may not + * @param array|bool|float|int|string $value The octal number you want to convert. Number may not * contain more than 10 characters. The most significant * bit of number is the sign bit. The remaining 29 bits * are magnitude bits. Negative numbers are represented @@ -29,7 +29,7 @@ class ConvertOctal extends ConvertBase * If OCT2BIN requires more than places characters, it * returns the #NUM! error value. * Or can be an array of values - * @param array|int $places The number of characters to use. If places is omitted, + * @param array|int $places The number of characters to use. If places is omitted, * OCT2BIN uses the minimum number of characters necessary. * Places is useful for padding the return value with * leading 0s (zeros). @@ -40,7 +40,7 @@ class ConvertOctal extends ConvertBase * value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -69,7 +69,7 @@ class ConvertOctal extends ConvertBase * Excel Function: * OCT2DEC(x) * - * @param array|bool|float|int|string $value The octal number you want to convert. Number may not contain + * @param array|bool|float|int|string $value The octal number you want to convert. Number may not contain * more than 10 octal characters (30 bits). The most significant * bit of number is the sign bit. The remaining 29 bits are * magnitude bits. Negative numbers are represented using @@ -78,7 +78,7 @@ class ConvertOctal extends ConvertBase * #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|float|int|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -104,10 +104,10 @@ class ConvertOctal extends ConvertBase $binX[$i] = ($binX[$i] == '1' ? '0' : '1'); } - return (string) ((bindec($binX) + 1) * -1); + return (bindec($binX) + 1) * -1; } - return (string) bindec($binX); + return bindec($binX); } /** @@ -118,7 +118,7 @@ class ConvertOctal extends ConvertBase * Excel Function: * OCT2HEX(x[,places]) * - * @param array|bool|float|int|string $value The octal number you want to convert. Number may not contain + * @param array|bool|float|int|string $value The octal number you want to convert. Number may not contain * more than 10 octal characters (30 bits). The most significant * bit of number is the sign bit. The remaining 29 bits are * magnitude bits. Negative numbers are represented using @@ -130,7 +130,7 @@ class ConvertOctal extends ConvertBase * If OCT2HEX requires more than places characters, it returns * the #NUM! error value. * Or can be an array of values - * @param array|int $places The number of characters to use. If places is omitted, OCT2HEX + * @param array|int $places The number of characters to use. If places is omitted, OCT2HEX * uses the minimum number of characters necessary. Places is useful * for padding the return value with leading 0s (zeros). * If places is not an integer, it is truncated. @@ -138,7 +138,7 @@ class ConvertOctal extends ConvertBase * If places is negative, OCT2HEX returns the #NUM! error value. * Or can be an array of values * - * @return array|string Result, or an error + * @return array|string Result, or an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php index 969c270..db1161c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php @@ -230,7 +230,7 @@ class ConvertUOM /** * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM(). * - ** @var array + * @var array */ private static array $binaryConversionMultipliers = [ 'Yi' => ['multiplier' => 2 ** 80, 'name' => 'yobi'], @@ -435,6 +435,8 @@ class ConvertUOM /** * getConversionGroups * Returns a list of the different conversion groups for UOM conversions. + * + * @return string[] */ public static function getConversionCategories(): array { @@ -451,6 +453,8 @@ class ConvertUOM * Returns an array of units of measure, for a specified conversion group, or for all groups. * * @param ?string $category The group whose units of measure you want to retrieve + * + * @return string[][] */ public static function getConversionCategoryUnits(?string $category = null): array { @@ -468,6 +472,8 @@ class ConvertUOM * getConversionGroupUnitDetails. * * @param ?string $category The group whose units of measure you want to retrieve + * + * @return array>> */ public static function getConversionCategoryUnitDetails(?string $category = null): array { @@ -488,7 +494,7 @@ class ConvertUOM * getConversionMultipliers * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM(). * - * @return mixed[] + * @return array */ public static function getConversionMultipliers(): array { @@ -499,7 +505,7 @@ class ConvertUOM * getBinaryConversionMultipliers * Returns an array of the additional Multiplier prefixes that can be used with Information Units of Measure in CONVERTUOM(). * - * @return mixed[] + * @return array */ public static function getBinaryConversionMultipliers(): array { @@ -516,14 +522,14 @@ class ConvertUOM * Excel Function: * CONVERT(value,fromUOM,toUOM) * - * @param array|float|int|string $value the value in fromUOM to convert + * @param array|float|int|string $value the value in fromUOM to convert * Or can be an array of values - * @param array|string $fromUOM the units for value + * @param string|string[] $fromUOM the units for value * Or can be an array of values - * @param array|string $toUOM the units for the result + * @param string|string[] $toUOM the units for the result * Or can be an array of values * - * @return array|float|string Result, or a string containing an error + * @return float|mixed[]|string Result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -566,6 +572,7 @@ class ConvertUOM return ($baseValue * self::$unitConversions[$fromCategory][$toUOM]) / $toMultiplier; } + /** @return array{0: string, 1: string, 2: float} */ private static function getUOMDetails(string $uom): array { if (isset(self::$conversionUnits[$uom])) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Erf.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Erf.php index aee7e31..7f599dd 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Erf.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Erf.php @@ -31,7 +31,7 @@ class Erf * If omitted, ERF integrates between zero and lower_limit * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function ERF(mixed $lower, mixed $upper = null): array|float|string @@ -63,7 +63,7 @@ class Erf * @param mixed $limit Float bound for integrating ERF, other bound is zero * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function ERFPRECISE(mixed $limit) diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ErfC.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ErfC.php index 4365fec..4cca2d6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ErfC.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ErfC.php @@ -26,7 +26,7 @@ class ErfC * @param mixed $value The float lower bound for integrating ERFC * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function ERFC(mixed $value) diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Amortization.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Amortization.php index b53829b..4344244 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Amortization.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Amortization.php @@ -54,9 +54,7 @@ class Amortization $salvage = Functions::flattenSingleValue($salvage); $period = Functions::flattenSingleValue($period); $rate = Functions::flattenSingleValue($rate); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $cost = FinancialValidations::validateFloat($cost); @@ -141,9 +139,7 @@ class Amortization $salvage = Functions::flattenSingleValue($salvage); $period = Functions::flattenSingleValue($period); $rate = Functions::flattenSingleValue($rate); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $cost = FinancialValidations::validateFloat($cost); @@ -171,9 +167,13 @@ class Amortization if ( $basis == FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL && $yearFrac < 1 - && DateTimeExcel\Helpers::isLeapYear(Functions::scalar($purchasedYear)) ) { - $yearFrac *= 365 / 366; + $temp = Functions::scalar($purchasedYear); + if (is_int($temp) || is_string($temp)) { + if (DateTimeExcel\Helpers::isLeapYear($temp)) { + $yearFrac *= 365 / 366; + } + } } $f0Rate = $yearFrac * $rate * $cost; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic.php index 6138fb1..2744c55 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic.php @@ -38,9 +38,9 @@ class Periodic ): string|float { $rate = Functions::flattenSingleValue($rate); $numberOfPeriods = Functions::flattenSingleValue($numberOfPeriods); - $payment = ($payment === null) ? 0.0 : Functions::flattenSingleValue($payment); - $presentValue = ($presentValue === null) ? 0.0 : Functions::flattenSingleValue($presentValue); - $type = ($type === null) ? FinancialConstants::PAYMENT_END_OF_PERIOD : Functions::flattenSingleValue($type); + $payment = Functions::flattenSingleValue($payment) ?? 0.0; + $presentValue = Functions::flattenSingleValue($presentValue) ?? 0.0; + $type = Functions::flattenSingleValue($type) ?? FinancialConstants::PAYMENT_END_OF_PERIOD; try { $rate = CashFlowValidations::validateRate($rate); @@ -77,9 +77,9 @@ class Periodic ): string|float { $rate = Functions::flattenSingleValue($rate); $numberOfPeriods = Functions::flattenSingleValue($numberOfPeriods); - $payment = ($payment === null) ? 0.0 : Functions::flattenSingleValue($payment); - $futureValue = ($futureValue === null) ? 0.0 : Functions::flattenSingleValue($futureValue); - $type = ($type === null) ? FinancialConstants::PAYMENT_END_OF_PERIOD : Functions::flattenSingleValue($type); + $payment = Functions::flattenSingleValue($payment) ?? 0.0; + $futureValue = Functions::flattenSingleValue($futureValue) ?? 0.0; + $type = Functions::flattenSingleValue($type) ?? FinancialConstants::PAYMENT_END_OF_PERIOD; try { $rate = CashFlowValidations::validateRate($rate); @@ -122,8 +122,8 @@ class Periodic $rate = Functions::flattenSingleValue($rate); $payment = Functions::flattenSingleValue($payment); $presentValue = Functions::flattenSingleValue($presentValue); - $futureValue = ($futureValue === null) ? 0.0 : Functions::flattenSingleValue($futureValue); - $type = ($type === null) ? FinancialConstants::PAYMENT_END_OF_PERIOD : Functions::flattenSingleValue($type); + $futureValue = Functions::flattenSingleValue($futureValue) ?? 0.0; + $type = Functions::flattenSingleValue($type) ?? FinancialConstants::PAYMENT_END_OF_PERIOD; try { $rate = CashFlowValidations::validateRate($rate); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Cumulative.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Cumulative.php index 9435909..a19a61b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Cumulative.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Cumulative.php @@ -41,7 +41,7 @@ class Cumulative $presentValue = Functions::flattenSingleValue($presentValue); $start = Functions::flattenSingleValue($start); $end = Functions::flattenSingleValue($end); - $type = ($type === null) ? FinancialConstants::PAYMENT_END_OF_PERIOD : Functions::flattenSingleValue($type); + $type = Functions::flattenSingleValue($type) ?? FinancialConstants::PAYMENT_END_OF_PERIOD; try { $rate = CashFlowValidations::validateRate($rate); @@ -104,7 +104,7 @@ class Cumulative $presentValue = Functions::flattenSingleValue($presentValue); $start = Functions::flattenSingleValue($start); $end = Functions::flattenSingleValue($end); - $type = ($type === null) ? FinancialConstants::PAYMENT_END_OF_PERIOD : Functions::flattenSingleValue($type); + $type = Functions::flattenSingleValue($type) ?? FinancialConstants::PAYMENT_END_OF_PERIOD; try { $rate = CashFlowValidations::validateRate($rate); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php index ad68ec1..68ac57b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php @@ -43,7 +43,7 @@ class Interest $numberOfPeriods = Functions::flattenSingleValue($numberOfPeriods); $presentValue = Functions::flattenSingleValue($presentValue); $futureValue = ($futureValue === null) ? 0.0 : Functions::flattenSingleValue($futureValue); - $type = ($type === null) ? FinancialConstants::PAYMENT_END_OF_PERIOD : Functions::flattenSingleValue($type); + $type = Functions::flattenSingleValue($type) ?? FinancialConstants::PAYMENT_END_OF_PERIOD; try { $interestRate = CashFlowValidations::validateRate($interestRate); @@ -160,9 +160,9 @@ class Interest $numberOfPeriods = Functions::flattenSingleValue($numberOfPeriods); $payment = Functions::flattenSingleValue($payment); $presentValue = Functions::flattenSingleValue($presentValue); - $futureValue = ($futureValue === null) ? 0.0 : Functions::flattenSingleValue($futureValue); - $type = ($type === null) ? FinancialConstants::PAYMENT_END_OF_PERIOD : Functions::flattenSingleValue($type); - $guess = ($guess === null) ? 0.1 : Functions::flattenSingleValue($guess); + $futureValue = Functions::flattenSingleValue($futureValue) ?? 0.0; + $type = Functions::flattenSingleValue($type) ?? FinancialConstants::PAYMENT_END_OF_PERIOD; + $guess = Functions::flattenSingleValue($guess) ?? 0.1; try { $numberOfPeriods = CashFlowValidations::validateFloat($numberOfPeriods); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Payments.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Payments.php index 41e88f9..d16be44 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Payments.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Payments.php @@ -27,14 +27,14 @@ class Payments mixed $interestRate, mixed $numberOfPeriods, mixed $presentValue, - mixed $futureValue = 0, + mixed $futureValue = 0.0, mixed $type = FinancialConstants::PAYMENT_END_OF_PERIOD ): string|float { $interestRate = Functions::flattenSingleValue($interestRate); $numberOfPeriods = Functions::flattenSingleValue($numberOfPeriods); $presentValue = Functions::flattenSingleValue($presentValue); - $futureValue = ($futureValue === null) ? 0.0 : Functions::flattenSingleValue($futureValue); - $type = ($type === null) ? FinancialConstants::PAYMENT_END_OF_PERIOD : Functions::flattenSingleValue($type); + $futureValue = Functions::flattenSingleValue($futureValue) ?? 0.0; + $type = Functions::flattenSingleValue($type) ?? FinancialConstants::PAYMENT_END_OF_PERIOD; try { $interestRate = CashFlowValidations::validateRate($interestRate); @@ -83,7 +83,7 @@ class Payments $numberOfPeriods = Functions::flattenSingleValue($numberOfPeriods); $presentValue = Functions::flattenSingleValue($presentValue); $futureValue = ($futureValue === null) ? 0.0 : Functions::flattenSingleValue($futureValue); - $type = ($type === null) ? FinancialConstants::PAYMENT_END_OF_PERIOD : Functions::flattenSingleValue($type); + $type = Functions::flattenSingleValue($type) ?? FinancialConstants::PAYMENT_END_OF_PERIOD; try { $interestRate = CashFlowValidations::validateRate($interestRate); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php index e503f72..53668d1 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php @@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class NonPeriodic { @@ -23,16 +24,17 @@ class NonPeriodic * Excel Function: * =XIRR(values,dates,guess) * - * @param mixed $values A series of cash flow payments, expecting float[] + * @param array $values A series of cash flow payments, expecting float[] * The series of values must contain at least one positive value & one negative value - * @param mixed[] $dates A series of payment dates + * @param array $dates A series of payment dates * The first payment date indicates the beginning of the schedule of payments * All other dates must be later than this date, but they may occur in any order * @param mixed $guess An optional guess at the expected answer */ - public static function rate(mixed $values, mixed $dates, mixed $guess = self::DEFAULT_GUESS): float|string + public static function rate(mixed $values, $dates, mixed $guess = self::DEFAULT_GUESS): float|string { $rslt = self::xirrPart1($values, $dates); + /** @var array $dates */ if ($rslt !== '') { return $rslt; } @@ -91,6 +93,7 @@ class NonPeriodic $x2 += 0.5; } if ($found) { + /** @var array $dates */ return self::xirrBisection($values, $dates, $x1, $x2); } @@ -107,7 +110,7 @@ class NonPeriodic * =XNPV(rate,values,dates) * * @param mixed $rate the discount rate to apply to the cash flows, expect array|float - * @param mixed $values A series of cash flows that corresponds to a schedule of payments in dates, expecting floag[]. + * @param array $values A series of cash flows that corresponds to a schedule of payments in dates, expecting float[]. * The first payment is optional and corresponds to a cost or payment that occurs * at the beginning of the investment. * If the first value is a cost or payment, it must be a negative value. @@ -127,9 +130,12 @@ class NonPeriodic return $neg && $pos; } + /** @param array $values */ private static function xirrPart1(mixed &$values, mixed &$dates): string { - $values = Functions::flattenArray($values); + /** @var array */ + $temp = Functions::flattenArray($values); + $values = $temp; $dates = Functions::flattenArray($dates); $valuesIsArray = count($values) > 1; $datesIsArray = count($dates) > 1; @@ -152,6 +158,7 @@ class NonPeriodic return self::xirrPart2($values); } + /** @param array $values */ private static function xirrPart2(array &$values): string { $valCount = count($values); @@ -159,7 +166,7 @@ class NonPeriodic $foundneg = false; for ($i = 0; $i < $valCount; ++$i) { $fld = $values[$i]; - if (!is_numeric($fld)) { + if (!is_numeric($fld)) { //* @phpstan-ignore-line return ExcelError::VALUE(); } elseif ($fld > 0) { $foundpos = true; @@ -174,6 +181,10 @@ class NonPeriodic return ''; } + /** + * @param array $values + * @param array $dates + */ private static function xirrPart3(array $values, array $dates, float $x1, float $x2): float|string { $f = self::xnpvOrdered($x1, $values, $dates, false); @@ -203,6 +214,10 @@ class NonPeriodic return $rslt; } + /** + * @param array $values + * @param array $dates + */ private static function xirrBisection(array $values, array $dates, float $x1, float $x2): string|float { $rslt = ExcelError::NAN(); @@ -243,6 +258,9 @@ class NonPeriodic private static function xnpvOrdered(mixed $rate, mixed $values, mixed $dates, bool $ordered = true, bool $capAtNegative1 = false): float|string { $rate = Functions::flattenSingleValue($rate); + if (!is_numeric($rate)) { + return ExcelError::VALUE(); + } $values = Functions::flattenArray($values); $dates = Functions::flattenArray($dates); $valCount = count($values); @@ -274,7 +292,7 @@ class NonPeriodic $dif = Functions::scalar(DateTimeExcel\Difference::interval($date0, $datei, 'd')); } if (!is_numeric($dif)) { - return $dif; + return StringHelper::convertToString($dif); } if ($rate <= -1.0) { $xnpv += -abs($values[$i] + 0) / (-1 - $rate) ** ($dif / 365); @@ -286,6 +304,10 @@ class NonPeriodic return is_finite($xnpv) ? $xnpv : ExcelError::VALUE(); } + /** + * @param mixed[] $values + * @param mixed[] $dates + */ private static function validateXnpv(mixed $rate, array $values, array $dates): void { if (!is_numeric($rate)) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/Periodic.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/Periodic.php index 21e537b..c5c3bcb 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/Periodic.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/Periodic.php @@ -36,6 +36,9 @@ class Periodic } $values = Functions::flattenArray($values); $guess = Functions::flattenSingleValue($guess); + if (!is_numeric($guess)) { + return ExcelError::VALUE(); + } // create an initial range, with a root somewhere between 0 and guess $x1 = 0.0; @@ -103,7 +106,9 @@ class Periodic return ExcelError::DIV0(); } $values = Functions::flattenArray($values); + /** @var float */ $financeRate = Functions::flattenSingleValue($financeRate); + /** @var float */ $reinvestmentRate = Functions::flattenSingleValue($reinvestmentRate); $n = count($values); @@ -112,6 +117,7 @@ class Periodic $npvPos = $npvNeg = 0.0; foreach ($values as $i => $v) { + /** @var float $v */ if ($v >= 0) { $npvPos += $v / $rr ** $i; } else { @@ -134,12 +140,13 @@ class Periodic * * Returns the Net Present Value of a cash flow series given a discount rate. * - * @param array $args + * @param array $args */ public static function presentValue(mixed $rate, ...$args): int|float { $returnValue = 0; + /** @var float */ $rate = Functions::flattenSingleValue($rate); $aArgs = Functions::flattenArray($args); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Coupons.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Coupons.php index c2fcab3..e6c9c85 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Coupons.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Coupons.php @@ -49,9 +49,7 @@ class Coupons $settlement = Functions::flattenSingleValue($settlement); $maturity = Functions::flattenSingleValue($maturity); $frequency = Functions::flattenSingleValue($frequency); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = FinancialValidations::validateSettlementDate($settlement); @@ -110,9 +108,7 @@ class Coupons $settlement = Functions::flattenSingleValue($settlement); $maturity = Functions::flattenSingleValue($maturity); $frequency = Functions::flattenSingleValue($frequency); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = FinancialValidations::validateSettlementDate($settlement); @@ -179,9 +175,7 @@ class Coupons $settlement = Functions::flattenSingleValue($settlement); $maturity = Functions::flattenSingleValue($maturity); $frequency = Functions::flattenSingleValue($frequency); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = FinancialValidations::validateSettlementDate($settlement); @@ -244,9 +238,7 @@ class Coupons $settlement = Functions::flattenSingleValue($settlement); $maturity = Functions::flattenSingleValue($maturity); $frequency = Functions::flattenSingleValue($frequency); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = FinancialValidations::validateSettlementDate($settlement); @@ -296,9 +288,7 @@ class Coupons $settlement = Functions::flattenSingleValue($settlement); $maturity = Functions::flattenSingleValue($maturity); $frequency = Functions::flattenSingleValue($frequency); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = FinancialValidations::validateSettlementDate($settlement); @@ -355,9 +345,7 @@ class Coupons $settlement = Functions::flattenSingleValue($settlement); $maturity = Functions::flattenSingleValue($maturity); $frequency = Functions::flattenSingleValue($frequency); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = FinancialValidations::validateSettlementDate($settlement); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Dollar.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Dollar.php index b0581f6..3fc64b6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Dollar.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Dollar.php @@ -25,7 +25,7 @@ class Dollar * If you omit precision, it is assumed to be 2 * Or can be an array of precision values * - * @return array|string If an array of values is passed for either of the arguments, then the returned result + * @return array|string If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function format(mixed $number, mixed $precision = 2) @@ -47,6 +47,8 @@ class Dollar * Or can be an array of values * @param mixed $fraction Fraction * Or can be an array of values + * + * @return array|float|string */ public static function decimal(mixed $fractionalDollar = null, mixed $fraction = 0): array|string|float { @@ -93,6 +95,8 @@ class Dollar * Or can be an array of values * @param mixed $fraction Fraction * Or can be an array of values + * + * @return array|float|string */ public static function fractional(mixed $decimalDollar = null, mixed $fraction = 0): array|string|float { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Helpers.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Helpers.php index aa28712..c983ecf 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Helpers.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Helpers.php @@ -14,7 +14,7 @@ class Helpers * * Returns the number of days in a specified year, as defined by the "basis" value * - * @param int|string $year The year against which we're testing + * @param mixed $year The year against which we're testing, expect int|string * @param int|string $basis The type of day count: * 0 or omitted US (NASD) 360 * 1 Actual (365 or 366 in a leap year) @@ -24,8 +24,11 @@ class Helpers * * @return int|string Result, or a string containing an error */ - public static function daysPerYear($year, $basis = 0): string|int + public static function daysPerYear(mixed $year, $basis = 0): string|int { + if (!is_int($year) && !is_string($year)) { + return ExcelError::VALUE(); + } if (!is_numeric($basis)) { return ExcelError::NAN(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/AccruedInterest.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/AccruedInterest.php index eb57abf..5f4379d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/AccruedInterest.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/AccruedInterest.php @@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\YearFrac; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Financial\Constants as FinancialConstants; use PhpOffice\PhpSpreadsheet\Calculation\Functions; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class AccruedInterest { @@ -59,12 +60,8 @@ class AccruedInterest $settlement = Functions::flattenSingleValue($settlement); $rate = Functions::flattenSingleValue($rate); $parValue = ($parValue === null) ? 1000 : Functions::flattenSingleValue($parValue); - $frequency = ($frequency === null) - ? FinancialConstants::FREQUENCY_ANNUAL - : Functions::flattenSingleValue($frequency); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $frequency = Functions::flattenSingleValue($frequency) ?? FinancialConstants::FREQUENCY_ANNUAL; + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $issue = SecurityValidations::validateIssueDate($issue); @@ -81,12 +78,12 @@ class AccruedInterest $daysBetweenIssueAndSettlement = Functions::scalar(YearFrac::fraction($issue, $settlement, $basis)); if (!is_numeric($daysBetweenIssueAndSettlement)) { // return date error - return $daysBetweenIssueAndSettlement; + return StringHelper::convertToString($daysBetweenIssueAndSettlement); } $daysBetweenFirstInterestAndSettlement = Functions::scalar(YearFrac::fraction($firstInterest, $settlement, $basis)); if (!is_numeric($daysBetweenFirstInterestAndSettlement)) { // return date error - return $daysBetweenFirstInterestAndSettlement; + return StringHelper::convertToString($daysBetweenFirstInterestAndSettlement); } return $parValue * $rate * $daysBetweenIssueAndSettlement; @@ -125,9 +122,7 @@ class AccruedInterest $settlement = Functions::flattenSingleValue($settlement); $rate = Functions::flattenSingleValue($rate); $parValue = ($parValue === null) ? 1000 : Functions::flattenSingleValue($parValue); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $issue = SecurityValidations::validateIssueDate($issue); @@ -143,7 +138,7 @@ class AccruedInterest $daysBetweenIssueAndSettlement = Functions::scalar(YearFrac::fraction($issue, $settlement, $basis)); if (!is_numeric($daysBetweenIssueAndSettlement)) { // return date error - return $daysBetweenIssueAndSettlement; + return StringHelper::convertToString($daysBetweenIssueAndSettlement); } return $parValue * $rate * $daysBetweenIssueAndSettlement; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php index b07b2c9..12c26c2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php @@ -9,6 +9,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Financial\Coupons; use PhpOffice\PhpSpreadsheet\Calculation\Financial\Helpers; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Price { @@ -52,9 +53,7 @@ class Price $yield = Functions::flattenSingleValue($yield); $redemption = Functions::flattenSingleValue($redemption); $frequency = Functions::flattenSingleValue($frequency); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = SecurityValidations::validateSettlementDate($settlement); @@ -119,9 +118,7 @@ class Price $maturity = Functions::flattenSingleValue($maturity); $discount = Functions::flattenSingleValue($discount); $redemption = Functions::flattenSingleValue($redemption); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = SecurityValidations::validateSettlementDate($settlement); @@ -137,7 +134,7 @@ class Price $daysBetweenSettlementAndMaturity = Functions::scalar(DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis)); if (!is_numeric($daysBetweenSettlementAndMaturity)) { // return date error - return $daysBetweenSettlementAndMaturity; + return StringHelper::convertToString($daysBetweenSettlementAndMaturity); } return $redemption * (1 - $discount * $daysBetweenSettlementAndMaturity); @@ -178,9 +175,7 @@ class Price $issue = Functions::flattenSingleValue($issue); $rate = Functions::flattenSingleValue($rate); $yield = Functions::flattenSingleValue($yield); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = SecurityValidations::validateSettlementDate($settlement); @@ -201,19 +196,19 @@ class Price $daysBetweenIssueAndSettlement = Functions::scalar(DateTimeExcel\YearFrac::fraction($issue, $settlement, $basis)); if (!is_numeric($daysBetweenIssueAndSettlement)) { // return date error - return $daysBetweenIssueAndSettlement; + return StringHelper::convertToString($daysBetweenIssueAndSettlement); } $daysBetweenIssueAndSettlement *= $daysPerYear; $daysBetweenIssueAndMaturity = Functions::scalar(DateTimeExcel\YearFrac::fraction($issue, $maturity, $basis)); if (!is_numeric($daysBetweenIssueAndMaturity)) { // return date error - return $daysBetweenIssueAndMaturity; + return StringHelper::convertToString($daysBetweenIssueAndMaturity); } $daysBetweenIssueAndMaturity *= $daysPerYear; $daysBetweenSettlementAndMaturity = Functions::scalar(DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis)); if (!is_numeric($daysBetweenSettlementAndMaturity)) { // return date error - return $daysBetweenSettlementAndMaturity; + return StringHelper::convertToString($daysBetweenSettlementAndMaturity); } $daysBetweenSettlementAndMaturity *= $daysPerYear; @@ -254,9 +249,7 @@ class Price $maturity = Functions::flattenSingleValue($maturity); $investment = Functions::flattenSingleValue($investment); $discount = Functions::flattenSingleValue($discount); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = SecurityValidations::validateSettlementDate($settlement); @@ -275,7 +268,7 @@ class Price $daysBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis); if (!is_numeric($daysBetweenSettlementAndMaturity)) { // return date error - return Functions::scalar($daysBetweenSettlementAndMaturity); + return StringHelper::convertToString(Functions::scalar($daysBetweenSettlementAndMaturity)); } return $investment / (1 - ($discount * $daysBetweenSettlementAndMaturity)); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Rates.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Rates.php index 2989a29..4a120e2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Rates.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Rates.php @@ -7,6 +7,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Financial\Constants as FinancialConstants; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Rates { @@ -43,9 +44,7 @@ class Rates $maturity = Functions::flattenSingleValue($maturity); $price = Functions::flattenSingleValue($price); $redemption = Functions::flattenSingleValue($redemption); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = SecurityValidations::validateSettlementDate($settlement); @@ -65,7 +64,7 @@ class Rates $daysBetweenSettlementAndMaturity = Functions::scalar(DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis)); if (!is_numeric($daysBetweenSettlementAndMaturity)) { // return date error - return $daysBetweenSettlementAndMaturity; + return StringHelper::convertToString($daysBetweenSettlementAndMaturity); } return (1 - $price / $redemption) / $daysBetweenSettlementAndMaturity; @@ -104,9 +103,7 @@ class Rates $maturity = Functions::flattenSingleValue($maturity); $investment = Functions::flattenSingleValue($investment); $redemption = Functions::flattenSingleValue($redemption); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = SecurityValidations::validateSettlementDate($settlement); @@ -126,7 +123,7 @@ class Rates $daysBetweenSettlementAndMaturity = Functions::scalar(DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis)); if (!is_numeric($daysBetweenSettlementAndMaturity)) { // return date error - return $daysBetweenSettlementAndMaturity; + return StringHelper::convertToString($daysBetweenSettlementAndMaturity); } return (($redemption / $investment) - 1) / ($daysBetweenSettlementAndMaturity); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Yields.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Yields.php index a4c5a48..7ccb132 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Yields.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial/Securities/Yields.php @@ -7,6 +7,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Financial\Constants as FinancialConstants; use PhpOffice\PhpSpreadsheet\Calculation\Financial\Helpers; use PhpOffice\PhpSpreadsheet\Calculation\Functions; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Yields { @@ -42,9 +43,7 @@ class Yields $maturity = Functions::flattenSingleValue($maturity); $price = Functions::flattenSingleValue($price); $redemption = Functions::flattenSingleValue($redemption); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = SecurityValidations::validateSettlementDate($settlement); @@ -64,7 +63,7 @@ class Yields $daysBetweenSettlementAndMaturity = Functions::scalar(DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis)); if (!is_numeric($daysBetweenSettlementAndMaturity)) { // return date error - return $daysBetweenSettlementAndMaturity; + return StringHelper::convertToString($daysBetweenSettlementAndMaturity); } $daysBetweenSettlementAndMaturity *= $daysPerYear; @@ -106,9 +105,7 @@ class Yields $issue = Functions::flattenSingleValue($issue); $rate = Functions::flattenSingleValue($rate); $price = Functions::flattenSingleValue($price); - $basis = ($basis === null) - ? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD - : Functions::flattenSingleValue($basis); + $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; try { $settlement = SecurityValidations::validateSettlementDate($settlement); @@ -129,19 +126,19 @@ class Yields $daysBetweenIssueAndSettlement = Functions::scalar(DateTimeExcel\YearFrac::fraction($issue, $settlement, $basis)); if (!is_numeric($daysBetweenIssueAndSettlement)) { // return date error - return $daysBetweenIssueAndSettlement; + return StringHelper::convertToString($daysBetweenIssueAndSettlement); } $daysBetweenIssueAndSettlement *= $daysPerYear; $daysBetweenIssueAndMaturity = Functions::scalar(DateTimeExcel\YearFrac::fraction($issue, $maturity, $basis)); if (!is_numeric($daysBetweenIssueAndMaturity)) { // return date error - return $daysBetweenIssueAndMaturity; + return StringHelper::convertToString($daysBetweenIssueAndMaturity); } $daysBetweenIssueAndMaturity *= $daysPerYear; $daysBetweenSettlementAndMaturity = Functions::scalar(DateTimeExcel\YearFrac::fraction($settlement, $maturity, $basis)); if (!is_numeric($daysBetweenSettlementAndMaturity)) { // return date error - return $daysBetweenSettlementAndMaturity; + return StringHelper::convertToString($daysBetweenSettlementAndMaturity); } $daysBetweenSettlementAndMaturity *= $daysPerYear; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php index 3e62422..16f6a3d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Shared\Date; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Functions { @@ -130,16 +131,22 @@ class Functions public static function isMatrixValue(mixed $idx): bool { + $idx = StringHelper::convertToString($idx); + return (substr_count($idx, '.') <= 1) || (preg_match('/\.[A-Z]/', $idx) > 0); } public static function isValue(mixed $idx): bool { + $idx = StringHelper::convertToString($idx); + return substr_count($idx, '.') === 0; } public static function isCellValue(mixed $idx): bool { + $idx = StringHelper::convertToString($idx); + return substr_count($idx, '.') > 1; } @@ -154,7 +161,8 @@ class Functions $condition = self::operandSpecialHandling($condition); if (is_bool($condition)) { return '=' . ($condition ? 'TRUE' : 'FALSE'); - } elseif (!is_numeric($condition)) { + } + if (!is_numeric($condition)) { if ($condition !== '""') { // Not an empty string // Escape any quotes in the string value $condition = (string) preg_replace('/"/ui', '""', $condition); @@ -162,29 +170,32 @@ class Functions $condition = Calculation::wrapResult(strtoupper($condition)); } - return str_replace('""""', '""', '=' . $condition); + return str_replace('""""', '""', '=' . StringHelper::convertToString($condition)); } $operator = $operand = ''; if (1 === preg_match('/(=|<[>=]?|>=?)(.*)/', $condition, $matches)) { [, $operator, $operand] = $matches; } - $operand = self::operandSpecialHandling($operand); + $operand = (string) self::operandSpecialHandling($operand); if (is_numeric(trim($operand, '"'))) { $operand = trim($operand, '"'); } elseif (!is_numeric($operand) && $operand !== 'FALSE' && $operand !== 'TRUE') { $operand = str_replace('"', '""', $operand); $operand = Calculation::wrapResult(strtoupper($operand)); + $operand = StringHelper::convertToString($operand); } return str_replace('""""', '""', $operator . $operand); } - private static function operandSpecialHandling(mixed $operand): mixed + private static function operandSpecialHandling(mixed $operand): bool|float|int|string { if (is_numeric($operand) || is_bool($operand)) { return $operand; - } elseif (strtoupper($operand) === Calculation::getTRUE() || strtoupper($operand) === Calculation::getFALSE()) { + } + $operand = StringHelper::convertToString($operand); + if (strtoupper($operand) === Calculation::getTRUE() || strtoupper($operand) === Calculation::getFALSE()) { return strtoupper($operand); } @@ -206,7 +217,7 @@ class Functions * * @param mixed $array Array to be flattened * - * @return array Flattened array + * @return array Flattened array */ public static function flattenArray(mixed $array): array { @@ -236,7 +247,7 @@ class Functions * * @param mixed $array Array to be flattened * - * @return array Flattened array + * @return array Flattened array */ public static function flattenArray2(mixed ...$array): array { @@ -274,7 +285,7 @@ class Functions * * @param array|mixed $array Array to be flattened * - * @return array Flattened array + * @return array Flattened array */ public static function flattenArrayIndexed($array): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php index f3a7462..00a5d65 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php @@ -15,7 +15,7 @@ class ErrorValue * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isErr(mixed $value = ''): array|bool @@ -33,7 +33,7 @@ class ErrorValue * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isError(mixed $value = '', bool $tryNotImplemented = false): array|bool @@ -58,7 +58,7 @@ class ErrorValue * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isNa(mixed $value = ''): array|bool diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ExcelError.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ExcelError.php index f4ea42d..94a4a7c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ExcelError.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ExcelError.php @@ -39,6 +39,8 @@ class ExcelError * ERROR_TYPE. * * @param mixed $value Value to check + * + * @return array|int|string */ public static function type(mixed $value = ''): array|int|string { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/Value.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/Value.php index 6f04df8..57a6704 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/Value.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/Value.php @@ -7,7 +7,9 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; use PhpOffice\PhpSpreadsheet\NamedRange; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Value @@ -20,7 +22,7 @@ class Value * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isBlank(mixed $value = null): array|bool @@ -43,6 +45,7 @@ class Value return false; } + $value = StringHelper::convertToString($value); $cellValue = Functions::trimTrailingRange($value); if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/ui', $cellValue) === 1) { [$worksheet, $cellValue] = Worksheet::extractSheetTitle($cellValue, true, true); @@ -68,7 +71,7 @@ class Value * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isEven(mixed $value = null): array|string|bool @@ -79,11 +82,12 @@ class Value if ($value === null) { return ExcelError::NAME(); - } elseif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) { + } + if (!is_numeric($value)) { return ExcelError::VALUE(); } - return ((int) fmod($value, 2)) === 0; + return ((int) fmod($value + 0, 2)) === 0; } /** @@ -92,7 +96,7 @@ class Value * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isOdd(mixed $value = null): array|string|bool @@ -103,11 +107,12 @@ class Value if ($value === null) { return ExcelError::NAME(); - } elseif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) { + } + if (!is_numeric($value)) { return ExcelError::VALUE(); } - return ((int) fmod($value, 2)) !== 0; + return ((int) fmod($value + 0, 2)) !== 0; } /** @@ -116,7 +121,7 @@ class Value * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isNumber(mixed $value = null): array|bool @@ -138,7 +143,7 @@ class Value * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isLogical(mixed $value = null): array|bool @@ -156,7 +161,7 @@ class Value * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isText(mixed $value = null): array|bool @@ -174,7 +179,7 @@ class Value * @param mixed $value Value to check * Or can be an array of values * - * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function isNonText(mixed $value = null): array|bool @@ -191,14 +196,17 @@ class Value * * @param mixed $cellReference The cell to check * @param ?Cell $cell The current cell (containing this formula) + * + * @return array|bool|string */ public static function isFormula(mixed $cellReference = '', ?Cell $cell = null): array|bool|string { if ($cell === null) { return ExcelError::REF(); } + $cellReference = StringHelper::convertToString($cellReference); - $fullCellReference = Functions::expandDefinedName((string) $cellReference, $cell); + $fullCellReference = Functions::expandDefinedName($cellReference, $cell); if (str_contains($cellReference, '!')) { $cellReference = Functions::trimSheetFromCellReference($cellReference); @@ -219,8 +227,15 @@ class Value $worksheet = (!empty($worksheetName)) ? $cell->getWorksheet()->getParentOrThrow()->getSheetByName($worksheetName) : $cell->getWorksheet(); + if ($worksheet === null) { + return ExcelError::REF(); + } - return ($worksheet !== null) ? $worksheet->getCell($fullCellReference)->isFormula() : ExcelError::REF(); + try { + return $worksheet->getCell($fullCellReference)->isFormula(); + } catch (SpreadsheetException) { + return true; + } } /** @@ -244,21 +259,14 @@ class Value while (is_array($value)) { $value = array_shift($value); } - - switch (gettype($value)) { - case 'double': - case 'float': - case 'integer': - return $value; - case 'boolean': - return (int) $value; - case 'string': - // Errors - if (($value !== '') && ($value[0] == '#')) { - return $value; - } - - break; + if (is_float($value) || is_int($value)) { + return $value; + } + if (is_bool($value)) { + return (int) $value; + } + if (is_string($value) && substr($value, 0, 1) === '#') { + return $value; } return 0; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php index 83ea458..8cce0b2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php @@ -39,6 +39,7 @@ class ExcelArrayPseudoFunctions return $result; } + /** @return array|string */ public static function anchorArray(string $cellReference, Cell $cell): array|string { //$coordinate = $cell->getCoordinate(); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Internal/MakeMatrix.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Internal/MakeMatrix.php index 22c95e8..f289c3f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Internal/MakeMatrix.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Internal/MakeMatrix.php @@ -4,7 +4,11 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Internal; class MakeMatrix { - /** @param array $args */ + /** + * @param mixed[] $args + * + * @return mixed[] + */ public static function make(...$args): array { return $args; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Logical/Operations.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Logical/Operations.php index 16bb5dd..f0a5476 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Logical/Operations.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Logical/Operations.php @@ -106,7 +106,7 @@ class Operations * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE * Or can be an array of values * - * @return array|bool|string the boolean inverse of the argument + * @return array|bool|string the boolean inverse of the argument * If an array of values is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -130,6 +130,10 @@ class Operations return !$logical; } + /** + * @param mixed[] $args + * @param callable(int, int): bool $func + */ private static function countTrueValues(array $args, callable $func): bool|string { $trueValueCount = 0; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Address.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Address.php index 0a5347b..a17e554 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Address.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Address.php @@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\AddressHelper; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Address { @@ -44,7 +45,7 @@ class Address * @param mixed $sheetName Optional Name of worksheet to use * Or can be an array of values * - * @return array|string If an array of values is passed as the $testValue argument, then the returned result will also be + * @return mixed[]|string If an array of values is passed as the $testValue argument, then the returned result will also be * an array with the same dimensions */ public static function cell(mixed $row, mixed $column, mixed $relativity = 1, mixed $referenceStyle = true, mixed $sheetName = ''): array|string @@ -63,14 +64,16 @@ class Address ); } - $relativity = $relativity ?? 1; + $relativity = ($relativity === null) ? 1 : (int) StringHelper::convertToString($relativity); $referenceStyle = $referenceStyle ?? true; + $row = (int) StringHelper::convertToString($row); + $column = (int) StringHelper::convertToString($column); if (($row < 1) || ($column < 1)) { return ExcelError::VALUE(); } - $sheetName = self::sheetName($sheetName); + $sheetName = self::sheetName(StringHelper::convertToString($sheetName)); if (is_int($referenceStyle)) { $referenceStyle = (bool) $referenceStyle; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/ChooseRowsEtc.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/ChooseRowsEtc.php index 97303e7..944675e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/ChooseRowsEtc.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/ChooseRowsEtc.php @@ -80,6 +80,11 @@ class ChooseRowsEtc return $outputArray; } + /** + * @param mixed[] $array + * + * @return mixed[]|string + */ private static function dropRows(array $array, mixed $offset): array|string { if ($offset === null) { @@ -134,6 +139,11 @@ class ChooseRowsEtc return self::transpose($outputArray3); } + /** + * @param mixed[] $array + * + * @return mixed[]|string + */ private static function takeRows(array $array, mixed $offset): array|string { if ($offset === null) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php index 43e89c9..3a1a6c4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php @@ -30,7 +30,7 @@ class ExcelMatch * @param mixed $matchType The number -1, 0, or 1. -1 means above, 0 means exact match, 1 means below. * If match_type is 1 or -1, the list has to be ordered. * - * @return array|float|int|string The relative position of the found item + * @return array|float|int|string The relative position of the found item */ public static function MATCH(mixed $lookupValue, mixed $lookupArray, mixed $matchType = self::MATCHTYPE_LARGEST_VALUE): array|string|int|float { @@ -70,13 +70,14 @@ class ExcelMatch }; if ($valueKey !== null) { - return ++$valueKey; + return ++$valueKey; //* @phpstan-ignore-line } // Unsuccessful in finding a match, return #N/A error value return ExcelError::NA(); } + /** @param mixed[] $lookupArray */ private static function matchFirstValue(array $lookupArray, mixed $lookupValue): int|string|null { if (is_string($lookupValue)) { @@ -113,6 +114,10 @@ class ExcelMatch return null; } + /** + * @param mixed[] $lookupArray + * @param mixed[] $keySet + */ private static function matchLargestValue(array $lookupArray, mixed $lookupValue, array $keySet): mixed { if (is_string($lookupValue)) { @@ -147,6 +152,7 @@ class ExcelMatch return null; } + /** @param mixed[] $lookupArray */ private static function matchSmallestValue(array $lookupArray, mixed $lookupValue): int|string|null { $valueKey = null; @@ -215,6 +221,7 @@ class ExcelMatch return self::MATCHTYPE_FIRST_VALUE; } + /** @param mixed[] $lookupArray */ private static function validateLookupArray(array $lookupArray): void { // Lookup_array should not be empty @@ -224,6 +231,11 @@ class ExcelMatch } } + /** + * @param mixed[] $lookupArray + * + * @return mixed[] + */ private static function prepareLookupArray(array $lookupArray, mixed $matchType): array { // Lookup_array should contain only number, text, or logical values, or empty (null) cells diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Filter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Filter.php index daedcd0..486194e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Filter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Filter.php @@ -6,8 +6,12 @@ use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class Filter { - public static function filter(array $lookupArray, mixed $matchArray, mixed $ifEmpty = null): mixed + public static function filter(mixed $lookupArray, mixed $matchArray, mixed $ifEmpty = null): mixed { + if (!is_array($lookupArray)) { + return ExcelError::VALUE(); + } + /** @var mixed[] $lookupArray */ if (!is_array($matchArray)) { return ExcelError::VALUE(); } @@ -21,10 +25,17 @@ class Filter if (empty($result)) { return $ifEmpty ?? ExcelError::CALC(); } + /** @var callable(mixed): mixed */ + $func = 'array_values'; - return array_values(array_map('array_values', $result)); + return array_values(array_map($func, $result)); } + /** + * @param mixed[] $sortArray + * + * @return mixed[] + */ private static function enumerateArrayKeys(array $sortArray): array { array_walk( @@ -39,17 +50,29 @@ class Filter return array_values($sortArray); } + /** + * @param mixed[] $lookupArray + * @param mixed[] $matchArray + * + * @return mixed[] + */ private static function filterByRow(array $lookupArray, array $matchArray): array { $matchArray = array_values(array_column($matchArray, 0)); // @phpstan-ignore-line return array_filter( array_values($lookupArray), - fn ($index): bool => (bool) $matchArray[$index], + fn ($index): bool => (bool) ($matchArray[$index] ?? null), ARRAY_FILTER_USE_KEY ); } + /** + * @param mixed[] $lookupArray + * @param mixed[] $matchArray + * + * @return mixed[] + */ private static function filterByColumn(array $lookupArray, array $matchArray): array { $lookupArray = Matrix::transpose($lookupArray); @@ -57,7 +80,7 @@ class Filter if (count($matchArray) === 1) { $matchArray = array_pop($matchArray); } - + /** @var mixed[] $matchArray */ array_walk( $matchArray, function (&$value): void { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php index 55a2a8f..f4982a0 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\Cell; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Formula { @@ -21,6 +22,7 @@ class Formula } $worksheet = null; + $cellReference = StringHelper::convertToString($cellReference); if (1 === preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellReference, $matches)) { $cellReference = $matches[6] . $matches[7]; $worksheetName = trim($matches[3], "'"); @@ -37,6 +39,6 @@ class Formula return ExcelError::NA(); } - return $worksheet->getCell($cellReference)->getValue(); + return $worksheet->getCell($cellReference)->getValueString(); } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php index fd83700..30c021b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php @@ -18,14 +18,14 @@ class HLookup extends LookupBase * in the same column based on the index_number. * * @param mixed $lookupValue The value that you want to match in lookup_array - * @param mixed $lookupArray The range of cells being searched - * @param mixed $indexNumber The row number in table_array from which the matching value must be returned. + * @param mixed[][] $lookupArray The range of cells being searched + * @param array|float|int|string $indexNumber The row number in table_array from which the matching value must be returned. * The first row is 1. * @param mixed $notExactMatch determines if you are looking for an exact match based on lookup_value * * @return mixed The value of the found cell */ - public static function lookup(mixed $lookupValue, mixed $lookupArray, mixed $indexNumber, mixed $notExactMatch = true): mixed + public static function lookup(mixed $lookupValue, $lookupArray, $indexNumber, mixed $notExactMatch = true): mixed { if (is_array($lookupValue) || is_array($indexNumber)) { return self::evaluateArrayArgumentsIgnore([self::class, __FUNCTION__], 1, $lookupValue, $lookupArray, $indexNumber, $notExactMatch); @@ -49,6 +49,7 @@ class HLookup extends LookupBase $firstkey = $f[0] - 1; $returnColumn = $firstkey + $indexNumber; + /** @var mixed[][] $lookupArray */ $firstColumn = array_shift($f) ?? 1; $rowNumber = self::hLookupSearch($lookupValue, $lookupArray, $firstColumn, $notExactMatch); @@ -62,17 +63,20 @@ class HLookup extends LookupBase /** * @param mixed $lookupValue The value that you want to match in lookup_array + * @param mixed[][] $lookupArray * @param int|string $column */ private static function hLookupSearch(mixed $lookupValue, array $lookupArray, $column, bool $notExactMatch): ?int { - $lookupLower = StringHelper::strToLower((string) $lookupValue); + $lookupLower = StringHelper::strToLower(StringHelper::convertToString($lookupValue)); $rowNumber = null; foreach ($lookupArray[$column] as $rowKey => $rowData) { // break if we have passed possible keys + /** @var string $rowKey */ $bothNumeric = is_numeric($lookupValue) && is_numeric($rowData); $bothNotNumeric = !is_numeric($lookupValue) && !is_numeric($rowData); + /** @var scalar $rowData */ $cellDataLower = StringHelper::strToLower((string) $rowData); if ( @@ -96,6 +100,11 @@ class HLookup extends LookupBase return $rowNumber; } + /** + * @param mixed[] $lookupArray + * + * @return mixed[] + */ private static function convertLiteralArray(array $lookupArray): array { if (array_key_exists(0, $lookupArray)) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php index 21c2030..5f94ffa 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php @@ -35,6 +35,7 @@ class Helpers } } + /** @return array{string, ?string, string} */ public static function extractCellAddresses(string $cellAddress, bool $a1, Worksheet $sheet, string $sheetName = '', ?int $baseRow = null, ?int $baseCol = null): array { $cellAddress1 = $cellAddress; @@ -57,6 +58,7 @@ class Helpers return [$cellAddress1, $cellAddress2, $cellAddress]; } + /** @return array{string, ?Worksheet, string} */ public static function extractWorksheet(string $cellAddress, Cell $cell): array { $sheetName = ''; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Hyperlink.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Hyperlink.php index 455442a..e7752aa 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Hyperlink.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Hyperlink.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\Cell; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Hyperlink { @@ -22,18 +23,23 @@ class Hyperlink */ public static function set(mixed $linkURL = '', mixed $displayName = null, ?Cell $cell = null): string { - $linkURL = ($linkURL === null) ? '' : Functions::flattenSingleValue($linkURL); + $linkURL = ($linkURL === null) ? '' : StringHelper::convertToString(Functions::flattenSingleValue($linkURL)); $displayName = ($displayName === null) ? '' : Functions::flattenSingleValue($displayName); if ((!is_object($cell)) || (trim($linkURL) == '')) { return ExcelError::REF(); } - if ((is_object($displayName)) || trim($displayName) == '') { + if (is_object($displayName)) { + $displayName = $linkURL; + } + $displayName = StringHelper::convertToString($displayName); + if (trim($displayName) === '') { $displayName = $linkURL; } - $cell->getHyperlink()->setUrl($linkURL); + $cell->getHyperlink() + ->setUrl($linkURL); $cell->getHyperlink()->setTooltip($displayName); return $displayName; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php index d53900d..756478c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php @@ -34,6 +34,8 @@ class Indirect /** * Convert cellAddress to string, verify not null string. + * + * @param null|mixed[]|string $cellAddress */ private static function validateAddress(array|string|null $cellAddress): string { @@ -54,12 +56,12 @@ class Indirect * Excel Function: * =INDIRECT(cellAddress, bool) where the bool argument is optional * - * @param array|string $cellAddress $cellAddress The cell address of the current cell (containing this formula) + * @param mixed[]|string $cellAddress $cellAddress The cell address of the current cell (containing this formula) * @param mixed $a1fmt Expect bool Helpers::CELLADDRESS_USE_A1 or CELLADDRESS_USE_R1C1, * but can be provided as numeric which is cast to bool * @param Cell $cell The current cell (containing this formula) * - * @return array|string An array containing a cell or range of cells, or a string on error + * @return mixed[]|string An array containing a cell or range of cells, or a string on error */ public static function INDIRECT($cellAddress, mixed $a1fmt, Cell $cell): string|array { @@ -99,13 +101,13 @@ class Indirect /** * Extract range values. * - * @return array Array of values in range if range contains more than one element. + * @return mixed[] Array of values in range if range contains more than one element. * Otherwise, a single value is returned. */ private static function extractRequiredCells(?Worksheet $worksheet, string $cellAddress): array { return Calculation::getInstance($worksheet !== null ? $worksheet->getParent() : null) - ->extractCellRange($cellAddress, $worksheet, false); + ->extractCellRange($cellAddress, $worksheet, false, createCell: true); } private static function handleRowColumnRanges(?Worksheet $worksheet, string $start, string $end): string diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Lookup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Lookup.php index b187620..9d3eea4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Lookup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Lookup.php @@ -28,6 +28,7 @@ class Lookup if (!is_array($lookupVector)) { return ExcelError::NA(); } + /** @var mixed[][] $lookupVector */ $hasResultVector = isset($resultVector); $lookupRows = self::rowCount($lookupVector); $lookupColumns = self::columnCount($lookupVector); @@ -35,16 +36,19 @@ class Lookup if (($lookupRows === 1 && $lookupColumns > 1) || (!$hasResultVector && $lookupRows === 2 && $lookupColumns !== 2)) { $lookupVector = Matrix::transpose($lookupVector); $lookupRows = self::rowCount($lookupVector); + /** @var mixed[][] $lookupVector */ $lookupColumns = self::columnCount($lookupVector); } - $resultVector = self::verifyResultVector($resultVector ?? $lookupVector); + $resultVector = self::verifyResultVector($resultVector ?? $lookupVector); //* @phpstan-ignore-line if ($lookupRows === 2 && !$hasResultVector) { $resultVector = array_pop($lookupVector); $lookupVector = array_shift($lookupVector); } + /** @var mixed[] $lookupVector */ + /** @var mixed[] $resultVector */ if ($lookupColumns !== 2) { $lookupVector = self::verifyLookupValues($lookupVector, $resultVector); } @@ -52,6 +56,12 @@ class Lookup return VLookup::lookup($lookupValue, $lookupVector, 2); } + /** + * @param mixed[] $lookupVector + * @param mixed[] $resultVector + * + * @return mixed[] + */ private static function verifyLookupValues(array $lookupVector, array $resultVector): array { foreach ($lookupVector as &$value) { @@ -77,6 +87,11 @@ class Lookup return $lookupVector; } + /** + * @param mixed[][] $resultVector + * + * @return mixed[] + */ private static function verifyResultVector(array $resultVector): array { $resultRows = self::rowCount($resultVector); @@ -90,11 +105,13 @@ class Lookup return $resultVector; } + /** @param mixed[] $dataArray */ private static function rowCount(array $dataArray): int { return count($dataArray); } + /** @param mixed[][] $dataArray */ private static function columnCount(array $dataArray): int { $rowKeys = array_keys($dataArray); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php index 7d21cce..39c498f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php @@ -7,15 +7,18 @@ use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; abstract class LookupBase { - protected static function validateLookupArray(mixed $lookup_array): void + protected static function validateLookupArray(mixed $lookupArray): void { - if (!is_array($lookup_array)) { + if (!is_array($lookupArray)) { throw new Exception(ExcelError::REF()); } } - /** @param float|int|string $index_number */ - protected static function validateIndexLookup(array $lookup_array, $index_number): int + /** + * @param mixed[] $lookupArray + * @param float|int|string $index_number number >= 1 + */ + protected static function validateIndexLookup(array $lookupArray, $index_number): int { // index_number must be a number greater than or equal to 1. // Excel results are inconsistent when index is non-numeric. @@ -30,8 +33,8 @@ abstract class LookupBase throw new Exception(ExcelError::VALUE()); } - // index_number must be less than or equal to the number of columns in lookup_array - if (empty($lookup_array)) { + // index_number must be less than or equal to the number of columns in lookupArray + if (empty($lookupArray)) { throw new Exception(ExcelError::REF()); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupRefValidations.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupRefValidations.php index 74c313c..620705e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupRefValidations.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupRefValidations.php @@ -11,7 +11,7 @@ class LookupRefValidations public static function validateInt(mixed $value): int { if (!is_numeric($value)) { - if (ErrorValue::isError($value)) { + if (is_string($value) && ErrorValue::isError($value)) { throw new Exception($value); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php index b8e84a6..287e841 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php @@ -12,6 +12,8 @@ class Matrix /** * Helper function; NOT an implementation of any Excel Function. + * + * @param mixed[] $values */ public static function isColumnVector(array $values): bool { @@ -20,6 +22,8 @@ class Matrix /** * Helper function; NOT an implementation of any Excel Function. + * + * @param mixed[] $values */ public static function isRowVector(array $values): bool { @@ -30,7 +34,9 @@ class Matrix /** * TRANSPOSE. * - * @param array|mixed $matrixData A matrix of values + * @param mixed $matrixData A matrix of values + * + * @return mixed[] */ public static function transpose($matrixData): array { @@ -38,8 +44,12 @@ class Matrix if (!is_array($matrixData)) { $matrixData = [[$matrixData]]; } + if (!is_array(end($matrixData))) { + $matrixData = [$matrixData]; + } $column = 0; + /** @var mixed[][] $matrixData */ foreach ($matrixData as $matrixRow) { $row = 0; foreach ($matrixRow as $matrixCell) { @@ -115,7 +125,7 @@ class Matrix } $rowKeys = array_keys($matrix); - $columnKeys = @array_keys($matrix[$rowKeys[0]]); + $columnKeys = @array_keys($matrix[$rowKeys[0]]); //* @phpstan-ignore-line if ($columnNum > count($columnKeys)) { return ExcelError::REF(); @@ -125,18 +135,23 @@ class Matrix return self::extractRowValue($matrix, $rowKeys, $rowNum); } - $columnNum = $columnKeys[--$columnNum]; + $columnNum = $columnKeys[--$columnNum]; //* @phpstan-ignore-line if ($rowNum === 0) { return array_map( fn ($value): array => [$value], array_column($matrix, $columnNum) ); } - $rowNum = $rowKeys[--$rowNum]; + $rowNum = $rowKeys[--$rowNum]; //* @phpstan-ignore-line + /** @var mixed[][] $matrix */ return $matrix[$rowNum][$columnNum]; } + /** + * @param mixed[] $matrix + * @param mixed[] $rowKeys + */ private static function extractRowValue(array $matrix, array $rowKeys, int $rowNum): mixed { if ($rowNum === 0) { @@ -144,7 +159,7 @@ class Matrix } $rowNum = $rowKeys[--$rowNum]; - $row = $matrix[$rowNum]; + $row = $matrix[$rowNum]; //* @phpstan-ignore-line if (is_array($row)) { return [$rowNum => $row]; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php index 9d201ff..6b07262 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php @@ -25,28 +25,32 @@ class Offset * @param null|string $cellAddress The reference from which you want to base the offset. * Reference must refer to a cell or range of adjacent cells; * otherwise, OFFSET returns the #VALUE! error value. - * @param mixed $rows The number of rows, up or down, that you want the upper-left cell to refer to. + * @param int $rows The number of rows, up or down, that you want the upper-left cell to refer to. * Using 5 as the rows argument specifies that the upper-left cell in the * reference is five rows below reference. Rows can be positive (which means * below the starting reference) or negative (which means above the starting * reference). - * @param mixed $columns The number of columns, to the left or right, that you want the upper-left cell + * @param int $columns The number of columns, to the left or right, that you want the upper-left cell * of the result to refer to. Using 5 as the cols argument specifies that the * upper-left cell in the reference is five columns to the right of reference. * Cols can be positive (which means to the right of the starting reference) * or negative (which means to the left of the starting reference). - * @param mixed $height The height, in number of rows, that you want the returned reference to be. + * @param ?int $height The height, in number of rows, that you want the returned reference to be. * Height must be a positive number. - * @param mixed $width The width, in number of columns, that you want the returned reference to be. + * @param ?int $width The width, in number of columns, that you want the returned reference to be. * Width must be a positive number. * - * @return array|string An array containing a cell or range of cells, or a string on error + * @return array|string An array containing a cell or range of cells, or a string on error */ - public static function OFFSET(?string $cellAddress = null, mixed $rows = 0, mixed $columns = 0, mixed $height = null, mixed $width = null, ?Cell $cell = null): string|array + public static function OFFSET(?string $cellAddress = null, $rows = 0, $columns = 0, $height = null, $width = null, ?Cell $cell = null): string|array { + /** @var int */ $rows = Functions::flattenSingleValue($rows); + /** @var int */ $columns = Functions::flattenSingleValue($columns); + /** @var int */ $height = Functions::flattenSingleValue($height); + /** @var int */ $width = Functions::flattenSingleValue($width); if ($cellAddress === null || $cellAddress === '') { @@ -95,12 +99,14 @@ class Offset return self::extractRequiredCells($worksheet, $cellAddress); } + /** @return mixed[] */ private static function extractRequiredCells(?Worksheet $worksheet, string $cellAddress): array { return Calculation::getInstance($worksheet !== null ? $worksheet->getParent() : null) ->extractCellRange($cellAddress, $worksheet, false); } + /** @return array{string, ?Worksheet} */ private static function extractWorksheet(?string $cellAddress, Cell $cell): array { $cellAddress = self::assessCellAddress($cellAddress ?? '', $cell); @@ -126,7 +132,11 @@ class Offset return $cellAddress; } - private static function adjustEndCellColumnForWidth(string $endCellColumn, mixed $width, int $startCellColumn, mixed $columns): int + /** + * @param null|object|scalar $width + * @param scalar $columns + */ + private static function adjustEndCellColumnForWidth(string $endCellColumn, $width, int $startCellColumn, $columns): int { $endCellColumn = Coordinate::columnIndexFromString($endCellColumn) - 1; if (($width !== null) && (!is_object($width))) { @@ -138,7 +148,11 @@ class Offset return $endCellColumn; } - private static function adustEndCellRowForHeight(mixed $height, int $startCellRow, mixed $rows, mixed $endCellRow): int + /** + * @param null|object|scalar $height + * @param scalar $rows + */ + private static function adustEndCellRowForHeight($height, int $startCellRow, $rows, int $endCellRow): int { if (($height !== null) && (!is_object($height))) { $endCellRow = $startCellRow + (int) $height - 1; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php index ea3ce44..caf0983 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php @@ -3,9 +3,11 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class RowColumnInformation @@ -13,7 +15,7 @@ class RowColumnInformation /** * Test if cellAddress is null or whitespace string. * - * @param null|array|string $cellAddress A reference to a range of cells + * @param null|mixed[]|string $cellAddress A reference to a range of cells */ private static function cellAddressNullOrWhitespace($cellAddress): bool { @@ -38,11 +40,11 @@ class RowColumnInformation * Excel Function: * =COLUMN([cellAddress]) * - * @param null|array|string $cellAddress A reference to a range of cells for which you want the column numbers + * @param null|mixed[]|string $cellAddress A reference to a range of cells for which you want the column numbers * - * @return int|int[] + * @return int|int[]|string */ - public static function COLUMN($cellAddress = null, ?Cell $cell = null): int|array + public static function COLUMN($cellAddress = null, ?Cell $cell = null): int|string|array { if (self::cellAddressNullOrWhitespace($cellAddress)) { return self::cellColumn($cell); @@ -79,7 +81,11 @@ class RowColumnInformation $cellAddress = (string) preg_replace('/[^a-z]/i', '', $cellAddress); - return Coordinate::columnIndexFromString($cellAddress); + try { + return Coordinate::columnIndexFromString($cellAddress); + } catch (SpreadsheetException) { + return ExcelError::NAME(); + } } /** @@ -90,7 +96,7 @@ class RowColumnInformation * Excel Function: * =COLUMNS(cellAddress) * - * @param null|array|string $cellAddress An array or array formula, or a reference to a range of cells + * @param null|mixed[]|string $cellAddress An array or array formula, or a reference to a range of cells * for which you want the number of columns * * @return int|string The number of columns in cellAddress, or a string if arguments are invalid @@ -100,6 +106,9 @@ class RowColumnInformation if (self::cellAddressNullOrWhitespace($cellAddress)) { return 1; } + if (is_string($cellAddress) && ErrorValue::isError($cellAddress)) { + return $cellAddress; + } if (!is_array($cellAddress)) { return ExcelError::VALUE(); } @@ -115,9 +124,18 @@ class RowColumnInformation return $columns; } - private static function cellRow(?Cell $cell): int + private static function cellRow(?Cell $cell): int|string { - return ($cell !== null) ? $cell->getRow() : 1; + return ($cell !== null) ? self::convert0ToName($cell->getRow()) : 1; + } + + private static function convert0ToName(int|string $result): int|string + { + if (is_int($result) && ($result <= 0 || $result > 1048576)) { + return ExcelError::NAME(); + } + + return $result; } /** @@ -133,11 +151,11 @@ class RowColumnInformation * Excel Function: * =ROW([cellAddress]) * - * @param null|array|string $cellAddress A reference to a range of cells for which you want the row numbers + * @param null|mixed[][]|string $cellAddress A reference to a range of cells for which you want the row numbers * - * @return int|mixed[] + * @return int|mixed[]|string */ - public static function ROW($cellAddress = null, ?Cell $cell = null): int|array + public static function ROW($cellAddress = null, ?Cell $cell = null): int|string|array { if (self::cellAddressNullOrWhitespace($cellAddress)) { return self::cellRow($cell); @@ -172,7 +190,7 @@ class RowColumnInformation } [$cellAddress] = explode(':', $cellAddress); - return (int) preg_replace('/\D/', '', $cellAddress); + return self::convert0ToName((int) preg_replace('/\D/', '', $cellAddress)); } /** @@ -183,7 +201,7 @@ class RowColumnInformation * Excel Function: * =ROWS(cellAddress) * - * @param null|array|string $cellAddress An array or array formula, or a reference to a range of cells + * @param null|mixed[]|string $cellAddress An array or array formula, or a reference to a range of cells * for which you want the number of rows * * @return int|string The number of rows in cellAddress, or a string if arguments are invalid @@ -193,6 +211,9 @@ class RowColumnInformation if (self::cellAddressNullOrWhitespace($cellAddress)) { return 1; } + if (is_string($cellAddress) && ErrorValue::isError($cellAddress)) { + return $cellAddress; + } if (!is_array($cellAddress)) { return ExcelError::VALUE(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Sort.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Sort.php index 9ad47b4..78a30a4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Sort.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Sort.php @@ -36,6 +36,7 @@ class Sort extends LookupRefValidations return $sortArray; } + /** @var mixed[][] */ $sortArray = self::enumerateArrayKeys($sortArray); $byColumn = (bool) $byColumn; @@ -43,7 +44,7 @@ class Sort extends LookupRefValidations try { // If $sortIndex and $sortOrder are scalars, then convert them into arrays - if (is_scalar($sortIndex)) { + if (!is_array($sortIndex)) { $sortIndex = [$sortIndex]; $sortOrder = is_scalar($sortOrder) ? [$sortOrder] : $sortOrder; } @@ -55,7 +56,11 @@ class Sort extends LookupRefValidations } // We want a simple, enumrated array of arrays where we can reference column by its index number. - $sortArray = array_values(array_map('array_values', $sortArray)); + /** @var callable(mixed): mixed */ + $temp = 'array_values'; + /** @var array $sortOrder */ + $sortArray = array_values(array_map($temp, $sortArray)); + /** @var int[] $sortIndex */ return ($byColumn === true) ? self::sortByColumn($sortArray, $sortIndex, $sortOrder) @@ -104,6 +109,11 @@ class Sort extends LookupRefValidations return self::processSortBy($sortArray, $sortBy, $sortOrder); } + /** + * @param mixed[] $sortArray + * + * @return mixed[] + */ private static function enumerateArrayKeys(array $sortArray): array { array_walk( @@ -133,6 +143,7 @@ class Sort extends LookupRefValidations $sortOrder = self::validateSortOrder($sortOrder); } + /** @return mixed[] */ private static function validateSortVector(mixed $sortVector, int $sortArraySize): array { if (!is_array($sortVector)) { @@ -158,6 +169,7 @@ class Sort extends LookupRefValidations return $sortOrder; } + /** @param mixed[] $sortIndex */ private static function validateArrayArgumentsForSort(array &$sortIndex, mixed &$sortOrder, int $sortArraySize): void { // It doesn't matter if they're row or column vectors, it works either way @@ -184,6 +196,11 @@ class Sort extends LookupRefValidations } } + /** + * @param mixed[] $sortVector + * + * @return mixed[] + */ private static function prepareSortVectorValues(array $sortVector): array { // Strings should be sorted case-insensitive; with booleans converted to locale-strings @@ -202,14 +219,19 @@ class Sort extends LookupRefValidations } /** - * @param array[] $sortIndex + * @param mixed[] $sortArray + * @param mixed[] $sortIndex * @param int[] $sortOrder + * + * @return mixed[] */ private static function processSortBy(array $sortArray, array $sortIndex, array $sortOrder): array { $sortArguments = []; + /** @var mixed[] */ $sortData = []; foreach ($sortIndex as $index => $sortValues) { + /** @var mixed[] $sortValues */ $sortData[] = $sortValues; $sortArguments[] = self::prepareSortVectorValues($sortValues); $sortArguments[] = $sortOrder[$index] === self::ORDER_ASCENDING ? SORT_ASC : SORT_DESC; @@ -221,8 +243,11 @@ class Sort extends LookupRefValidations } /** + * @param mixed[] $sortArray * @param int[] $sortIndex * @param int[] $sortOrder + * + * @return mixed[] */ private static function sortByRow(array $sortArray, array $sortIndex, array $sortOrder): array { @@ -232,8 +257,11 @@ class Sort extends LookupRefValidations } /** + * @param mixed[] $sortArray * @param int[] $sortIndex * @param int[] $sortOrder + * + * @return mixed[] */ private static function sortByColumn(array $sortArray, array $sortIndex, array $sortOrder): array { @@ -244,8 +272,11 @@ class Sort extends LookupRefValidations } /** + * @param mixed[] $sortArray * @param int[] $sortIndex * @param int[] $sortOrder + * + * @return mixed[] */ private static function buildVectorForSort(array $sortArray, array $sortIndex, array $sortOrder): array { @@ -263,6 +294,12 @@ class Sort extends LookupRefValidations return $sortData; } + /** + * @param mixed[] $sortData + * @param mixed[] $sortArguments + * + * @return mixed[] + */ private static function executeVectorSortQuery(array $sortData, array $sortArguments): array { $sortData = Matrix::transpose($sortData); @@ -287,11 +324,18 @@ class Sort extends LookupRefValidations return $sortedData; } + /** + * @param mixed[] $sortArray + * @param mixed[] $sortVector + * + * @return mixed[] + */ private static function sortLookupArrayFromVector(array $sortArray, array $sortVector): array { // Building a new array in the correct (sorted) order works; but may be memory heavy for larger arrays $sortedArray = []; foreach ($sortVector as $index) { + /** @var int|string $index */ $sortedArray[] = $sortArray[$index]; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Unique.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Unique.php index 103520e..40a9df7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Unique.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Unique.php @@ -33,17 +33,20 @@ class Unique : self::uniqueByRow($lookupVector, $exactlyOnce); } + /** @param mixed[] $lookupVector */ private static function uniqueByRow(array $lookupVector, bool $exactlyOnce): mixed { // When not $byColumn, we count whole rows or values, not individual values // so implode each row into a single string value array_walk( $lookupVector, + //* @phpstan-ignore-next-line function (array &$value): void { $valuex = ''; $separator = ''; $numericIndicator = "\x01"; foreach ($value as $cellValue) { + /** @var scalar $cellValue */ $valuex .= $separator . $cellValue; $separator = "\x00"; if (is_int($cellValue) || is_float($cellValue)) { @@ -54,6 +57,7 @@ class Unique } ); + /** @var string[] $lookupVector */ $result = self::countValuesCaseInsensitive($lookupVector); if ($exactlyOnce === true) { @@ -84,8 +88,10 @@ class Unique return (count($result) === 1) ? array_pop($result) : $result; } + /** @param mixed[] $lookupVector */ private static function uniqueByColumn(array $lookupVector, bool $exactlyOnce): mixed { + /** @var string[] */ $flattenedLookupVector = Functions::flattenArray($lookupVector); if (count($lookupVector, COUNT_RECURSIVE) > count($flattenedLookupVector, COUNT_RECURSIVE) + 1) { @@ -111,6 +117,11 @@ class Unique return $result; } + /** + * @param string[] $caseSensitiveLookupValues + * + * @return mixed[] + */ private static function countValuesCaseInsensitive(array $caseSensitiveLookupValues): array { $caseInsensitiveCounts = array_count_values( @@ -138,6 +149,11 @@ class Unique return $caseSensitiveCounts; } + /** + * @param mixed[] $values + * + * @return mixed[] + */ private static function exactlyOnceFilter(array $values): array { return array_filter( diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php index 1c24b2a..76929c5 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php @@ -17,14 +17,14 @@ class VLookup extends LookupBase * in the same row based on the index_number. * * @param mixed $lookupValue The value that you want to match in lookup_array - * @param mixed $lookupArray The range of cells being searched - * @param mixed $indexNumber The column number in table_array from which the matching value must be returned. + * @param mixed[] $lookupArray The range of cells being searched + * @param array|float|int|string $indexNumber The column number in table_array from which the matching value must be returned. * The first column is 1. * @param mixed $notExactMatch determines if you are looking for an exact match based on lookup_value * * @return mixed The value of the found cell */ - public static function lookup(mixed $lookupValue, mixed $lookupArray, mixed $indexNumber, mixed $notExactMatch = true): mixed + public static function lookup(mixed $lookupValue, $lookupArray, mixed $indexNumber, mixed $notExactMatch = true): mixed { if (is_array($lookupValue) || is_array($indexNumber)) { return self::evaluateArrayArgumentsIgnore([self::class, __FUNCTION__], 1, $lookupValue, $lookupArray, $indexNumber, $notExactMatch); @@ -54,6 +54,7 @@ class VLookup extends LookupBase uasort($lookupArray, $callable); } + /** @var string[][] $lookupArray */ $rowNumber = self::vLookupSearch($lookupValue, $lookupArray, $firstColumn, $notExactMatch); if ($rowNumber !== null) { @@ -64,6 +65,10 @@ class VLookup extends LookupBase return ExcelError::NA(); } + /** + * @param scalar[] $a + * @param scalar[] $b + */ private static function vlookupSort(array $a, array $b): int { reset($a); @@ -80,11 +85,12 @@ class VLookup extends LookupBase /** * @param mixed $lookupValue The value that you want to match in lookup_array + * @param string[][] $lookupArray * @param int|string $column */ private static function vLookupSearch(mixed $lookupValue, array $lookupArray, $column, bool $notExactMatch): ?int { - $lookupLower = StringHelper::strToLower((string) $lookupValue); + $lookupLower = StringHelper::strToLower(StringHelper::convertToString($lookupValue)); $rowNumber = null; foreach ($lookupArray as $rowKey => $rowData) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php index 03e6139..3b7e532 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php @@ -16,7 +16,7 @@ class Absolute * * @param mixed $number Should be numeric, or can be an array of numbers * - * @return array|float|int|string rounded number + * @return array|float|int|string rounded number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Angle.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Angle.php index e7de7aa..7c3597d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Angle.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Angle.php @@ -16,7 +16,7 @@ class Angle * * @param mixed $number Should be numeric, or can be an array of numbers * - * @return array|float|string Rounded number + * @return array|float|string Rounded number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -42,7 +42,7 @@ class Angle * * @param mixed $number Should be numeric, or can be an array of numbers * - * @return array|float|string Rounded number + * @return array|float|string Rounded number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php index 8901d3f..47c2c98 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php @@ -22,6 +22,8 @@ class Arabic /** * Recursively calculate the arabic value of a roman numeral. + * + * @param string[] $roman */ private static function calculateArabic(array $roman, int &$sum = 0, int $subtract = 0): int { @@ -55,7 +57,7 @@ class Arabic * * @param string|string[] $roman Should be a string, or can be an array of strings * - * @return array|int|string the arabic numberal contrived from the roman numeral + * @return array|int|string the arabic numberal contrived from the roman numeral * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Base.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Base.php index 7eda72c..e9ef191 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Base.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Base.php @@ -25,7 +25,7 @@ class Base * @param mixed $minLength expect int or null * Or can be an array of values * - * @return array|string the text representation with the given radix (base) + * @return array|string the text representation with the given radix (base) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Ceiling.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Ceiling.php index 365ec2e..3458ca8 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Ceiling.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Ceiling.php @@ -22,12 +22,12 @@ class Ceiling * Excel Function: * CEILING(number[,significance]) * - * @param array|float $number the number you want the ceiling + * @param array|float $number the number you want the ceiling * Or can be an array of values - * @param array|float $significance the multiple to which you want to round + * @param array|float $significance the multiple to which you want to round * Or can be an array of values * - * @return array|float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -63,14 +63,14 @@ class Ceiling * Or can be an array of values * @param mixed $significance Significance * Or can be an array of values - * @param array|int $mode direction to round negative numbers + * @param array|int $mode direction to round negative numbers * Or can be an array of values * - * @return array|float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function math(mixed $number, mixed $significance = null, $mode = 0): array|string|float + public static function math(mixed $number, mixed $significance = null, $mode = 0, bool $checkSigns = false): array|string|float { if (is_array($number) || is_array($significance) || is_array($mode)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance, $mode); @@ -87,6 +87,11 @@ class Ceiling if (empty($significance * $number)) { return 0.0; } + if ($checkSigns) { + if (($number > 0 && $significance < 0) || ($number < 0 && $significance > 0)) { + return ExcelError::NAN(); + } + } if (self::ceilingMathTest((float) $significance, (float) $number, (int) $mode)) { return floor($number / $significance) * $significance; } @@ -104,10 +109,10 @@ class Ceiling * * @param mixed $number the number you want to round * Or can be an array of values - * @param array|float $significance the multiple to which you want to round + * @param array|float $significance the multiple to which you want to round * Or can be an array of values * - * @return array|float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -132,6 +137,23 @@ class Ceiling return ceil($result) * $significance * (($significance < 0) ? -1 : 1); } + /** + * CEILING.ODS, pseudo-function - CEILING as implemented in ODS. + * + * ODS Function (theoretical): + * CEILING.ODS(number[,significance[,mode]]) + * + * @param mixed $number Number to round + * @param mixed $significance Significance + * @param array|int $mode direction to round negative numbers + * + * @return array|float|string Rounded Number, or a string containing an error + */ + public static function mathOds(mixed $number, mixed $significance = null, $mode = 0): array|string|float + { + return self::math($number, $significance, $mode, true); + } + /** * Let CEILINGMATH complexity pass Scrutinizer. */ @@ -148,7 +170,12 @@ class Ceiling if (empty($number * $significance)) { return 0.0; } - if (Helpers::returnSign($number) == Helpers::returnSign($significance)) { + $signSig = Helpers::returnSign($significance); + $signNum = Helpers::returnSign($number); + if ( + ($signSig === 1 && ($signNum === 1 || Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC)) + || ($signSig === -1 && $signNum === -1) + ) { return ceil($number / $significance) * $significance; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php index 99eb05a..e38a455 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php @@ -21,7 +21,7 @@ class Combinations * @param mixed $numObjs Number of different objects, or can be an array of numbers * @param mixed $numInSet Number of objects in each combination, or can be an array of numbers * - * @return array|float|string Number of combinations, or a string containing an error + * @return array|float|string Number of combinations, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -62,7 +62,7 @@ class Combinations * @param mixed $numObjs Number of different objects, or can be an array of numbers * @param mixed $numInSet Number of objects in each combination, or can be an array of numbers * - * @return array|float|int|string Number of combinations, or a string containing an error + * @return array|float|int|string Number of combinations, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Exp.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Exp.php index ea67d5f..f029b66 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Exp.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Exp.php @@ -16,7 +16,7 @@ class Exp * * @param mixed $number Should be numeric, or can be an array of numbers * - * @return array|float|string Rounded number + * @return array|float|string Rounded number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php index 7bbd4d8..2e2a921 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php @@ -21,9 +21,9 @@ class Factorial * Excel Function: * FACT(factVal) * - * @param array|float $factVal Factorial Value, or can be an array of numbers + * @param array|float $factVal Factorial Value, or can be an array of numbers * - * @return array|float|int|string Factorial, or a string containing an error + * @return array|float|int|string Factorial, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -63,9 +63,9 @@ class Factorial * Excel Function: * FACTDOUBLE(factVal) * - * @param array|float $factVal Factorial Value, or can be an array of numbers + * @param array|float $factVal Factorial Value, or can be an array of numbers * - * @return array|float|int|string Double Factorial, or a string containing an error + * @return array|float|int|string Double Factorial, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -113,7 +113,9 @@ class Factorial Helpers::validateNotNegative($arg); $arg = (int) $arg; $summer += $arg; - $divisor *= self::fact($arg); + /** @var float|int */ + $temp = self::fact($arg); + $divisor *= $temp; } } catch (Exception $e) { return $e->getMessage(); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Floor.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Floor.php index 83cf051..b86fd45 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Floor.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Floor.php @@ -32,7 +32,7 @@ class Floor * @param mixed $significance Expect float. Significance * Or can be an array of values * - * @return array|float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -71,11 +71,11 @@ class Floor * @param mixed $mode direction to round negative numbers * Or can be an array of values * - * @return array|float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function math(mixed $number, mixed $significance = null, mixed $mode = 0) + public static function math(mixed $number, mixed $significance = null, mixed $mode = 0, bool $checkSigns = false) { if (is_array($number) || is_array($significance) || is_array($mode)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance, $mode); @@ -89,9 +89,37 @@ class Floor return $e->getMessage(); } + if (empty($significance * $number)) { + return 0.0; + } + if ($checkSigns) { + if (($number > 0 && $significance < 0) || ($number < 0 && $significance > 0)) { + return ExcelError::NAN(); + } + } + return self::argsOk((float) $number, (float) $significance, (int) $mode); } + /** + * FLOOR.ODS, pseudo-function - FLOOR as implemented in ODS. + * + * Round a number down to the nearest integer or to the nearest multiple of significance. + * + * ODS Function (theoretical): + * FLOOR.ODS(number[,significance[,mode]]) + * + * @param mixed $number Number to round + * @param mixed $significance Significance + * @param array|int $mode direction to round negative numbers + * + * @return array|float|string Rounded Number, or a string containing an error + */ + public static function mathOds(mixed $number, mixed $significance = null, mixed $mode = 0) + { + return self::math($number, $significance, $mode, true); + } + /** * FLOOR.PRECISE. * @@ -100,12 +128,12 @@ class Floor * Excel Function: * FLOOR.PRECISE(number[,significance]) * - * @param array|float $number Number to round + * @param array|float $number Number to round * Or can be an array of values - * @param array|float $significance Significance + * @param array|float $significance Significance * Or can be an array of values * - * @return array|float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -121,6 +149,9 @@ class Floor } catch (Exception $e) { return $e->getMessage(); } + if (!$significance) { + return 0.0; + } return self::argumentsOkPrecise((float) $number, (float) $significance); } @@ -179,10 +210,12 @@ class Floor if ($number == 0.0) { return 0.0; } - if (Helpers::returnSign($significance) == 1) { - return floor($number / $significance) * $significance; - } - if (Helpers::returnSign($number) == -1 && Helpers::returnSign($significance) == -1) { + $signSig = Helpers::returnSign($significance); + $signNum = Helpers::returnSign($number); + if ( + ($signSig === 1 && ($signNum === 1 || Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC)) + || ($signNum === -1 && $signSig === -1) + ) { return floor($number / $significance) * $significance; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php index 76bbced..f7d6da4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php @@ -17,9 +17,9 @@ class IntClass * Excel Function: * INT(number) * - * @param array|float $number Number to cast to an integer, or can be an array of numbers + * @param array|float $number Number to cast to an integer, or can be an array of numbers * - * @return array|int|string Integer value, or a string containing an error + * @return array|int|string Integer value, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Lcm.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Lcm.php index 979b6df..88a5222 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Lcm.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Lcm.php @@ -8,9 +8,11 @@ use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; class Lcm { - // - // Private method to return an array of the factors of the input value - // + /** + * Private method to return an array of the factors of the input value. + * + * @return int[] + */ private static function factors(float $value): array { $startVal = floor(sqrt($value)); @@ -27,6 +29,7 @@ class Lcm } if (!empty($factorArray)) { rsort($factorArray); + /** @var int[] $factorArray */ return $factorArray; } @@ -83,12 +86,17 @@ class Lcm self::processPoweredFactors($allPoweredFactors, $myPoweredFactors); } foreach ($allPoweredFactors as $allPoweredFactor) { + /** @var scalar $allPoweredFactor */ $returnValue *= (int) $allPoweredFactor; } return $returnValue; } + /** + * @param mixed[] $allPoweredFactors + * @param mixed[] $myPoweredFactors + */ private static function processPoweredFactors(array &$allPoweredFactors, array &$myPoweredFactors): void { foreach ($myPoweredFactors as $myPoweredValue => $myPoweredFactor) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Logarithms.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Logarithms.php index 3de0a2b..f2ccdf6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Logarithms.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Logarithms.php @@ -22,7 +22,7 @@ class Logarithms * @param mixed $base The base of the logarithm. If base is omitted, it is assumed to be 10. * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -52,7 +52,7 @@ class Logarithms * @param mixed $number Should be numeric * Or can be an array of values * - * @return array|float|string Rounded number + * @return array|float|string Rounded number * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -80,7 +80,7 @@ class Logarithms * @param mixed $number Should be numeric * Or can be an array of values * - * @return array|float|string Rounded number + * @return array|float|string Rounded number * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php index fad0108..df61e08 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php @@ -55,7 +55,7 @@ class MatrixFunctions * @param mixed $start the first number in the sequence, defaults to 1 * @param mixed $step the amount to increment each subsequent value in the array, defaults to 1 * - * @return array|string The resulting array, or a string containing an error + * @return array|string The resulting array, or a string containing an error */ public static function sequence(mixed $rows = 1, mixed $columns = 1, mixed $start = 1, mixed $step = 1): string|array { @@ -118,7 +118,7 @@ class MatrixFunctions * * @param mixed $matrixValues A matrix of values * - * @return array|string The result, or a string containing an error + * @return array|string The result, or a string containing an error */ public static function inverse(mixed $matrixValues): array|string { @@ -141,7 +141,7 @@ class MatrixFunctions * @param mixed $matrixData1 A matrix of values * @param mixed $matrixData2 A matrix of values * - * @return array|string The result, or a string containing an error + * @return array|string The result, or a string containing an error */ public static function multiply(mixed $matrixData1, mixed $matrixData2): array|string { @@ -162,7 +162,7 @@ class MatrixFunctions * * @param mixed $dimension Number of rows and columns * - * @return array|string The result, or a string containing an error + * @return array|string The result, or a string containing an error */ public static function identity(mixed $dimension) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Operations.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Operations.php index 0eca549..40b6dcd 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Operations.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Operations.php @@ -19,7 +19,7 @@ class Operations * @param mixed $divisor Divisor * Or can be an array of values * - * @return array|float|string Remainder, or a string containing an error + * @return array|float|string Remainder, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -52,10 +52,10 @@ class Operations * * Computes x raised to the power y. * - * @param null|array|bool|float|int|string $x Or can be an array of values - * @param null|array|bool|float|int|string $y Or can be an array of values + * @param null|array|bool|float|int|string $x Or can be an array of values + * @param null|array|bool|float|int|string $y Or can be an array of values * - * @return array|float|int|string The result, or a string containing an error + * @return array|float|int|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -133,7 +133,7 @@ class Operations * @param mixed $denominator Expect float|int * Or can be an array of values * - * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function quotient(mixed $numerator, mixed $denominator): array|string|int diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Random.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Random.php index 80d4caa..4db946a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Random.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Random.php @@ -28,7 +28,7 @@ class Random * @param mixed $max Maximal value * Or can be an array of values * - * @return array|int|string Random number + * @return array|int|string Random number * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -65,7 +65,7 @@ class Random * False - Decimal numbers to 15 decimal places. (default) * True - Whole (integer) numbers * - * @return array|string The resulting array, or a string containing an error + * @return array|string The resulting array, or a string containing an error */ public static function randArray(mixed $rows = 1, mixed $columns = 1, mixed $min = 0, mixed $max = 1, bool $wholeNumber = false): string|array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Roman.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Roman.php index 7c6f8e7..efb9dc0 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Roman.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Roman.php @@ -821,7 +821,7 @@ class Roman * @param mixed $style Number indicating one of five possible forms * Or can be an array of styles * - * @return array|string Roman numeral, or a string containing an error + * @return array|string Roman numeral, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Round.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Round.php index e0e03ae..d8e338c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Round.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Round.php @@ -20,7 +20,7 @@ class Round * @param mixed $number Should be numeric, or can be an array of numbers * @param mixed $precision Should be int, or can be an array of numbers * - * @return array|float|string Rounded number + * @return array|float|string Rounded number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -45,10 +45,10 @@ class Round * * Rounds a number up to a specified number of decimal places * - * @param array|float $number Number to round, or can be an array of numbers - * @param array|int $digits Number of digits to which you want to round $number, or can be an array of numbers + * @param array|float $number Number to round, or can be an array of numbers + * @param array|int $digits Number of digits to which you want to round $number, or can be an array of numbers * - * @return array|float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -77,11 +77,13 @@ class Round ); } + // @codeCoverageIgnoreStart if ($number < 0.0) { return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN); } return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN); + // @codeCoverageIgnoreEnd } /** @@ -89,10 +91,10 @@ class Round * * Rounds a number down to a specified number of decimal places * - * @param null|array|float|string $number Number to round, or can be an array of numbers - * @param array|float|int|string $digits Number of digits to which you want to round $number, or can be an array of numbers + * @param null|array|float|string $number Number to round, or can be an array of numbers + * @param array|float|int|string $digits Number of digits to which you want to round $number, or can be an array of numbers * - * @return array|float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -121,11 +123,13 @@ class Round ); } + // @codeCoverageIgnoreStart if ($number < 0.0) { return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP); } return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP); + // @codeCoverageIgnoreEnd } /** @@ -136,7 +140,7 @@ class Round * @param mixed $number Expect float. Number to round, or can be an array of numbers * @param mixed $multiple Expect int. Multiple to which you want to round, or can be an array of numbers. * - * @return array|float|int|string Rounded Number, or a string containing an error + * @return array|float|int|string Rounded Number, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -177,9 +181,9 @@ class Round * Excel Function: * EVEN(number) * - * @param array|float $number Number to round, or can be an array of numbers + * @param array|float $number Number to round, or can be an array of numbers * - * @return array|float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -203,9 +207,9 @@ class Round * * Returns number rounded up to the nearest odd integer. * - * @param array|float $number Number to round, or can be an array of numbers + * @param array|float $number Number to round, or can be an array of numbers * - * @return array|float|int|string Rounded Number, or a string containing an error + * @return array|float|int|string Rounded Number, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/SeriesSum.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/SeriesSum.php index bb10090..fee7bc4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/SeriesSum.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/SeriesSum.php @@ -20,7 +20,7 @@ class SeriesSum * @param mixed $m Step * @param mixed[] $args An array of coefficients for the Data Series * - * @return array|float|int|string The result, or a string containing an error + * @return array|float|int|string The result, or a string containing an error */ public static function evaluate(mixed $x, mixed $n, mixed $m, ...$args): array|string|float|int { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sign.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sign.php index 86a5509..5d2fb97 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sign.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sign.php @@ -15,9 +15,9 @@ class Sign * Determines the sign of a number. Returns 1 if the number is positive, zero (0) * if the number is 0, and -1 if the number is negative. * - * @param array|float $number Number to round, or can be an array of numbers + * @param array|float $number Number to round, or can be an array of numbers * - * @return array|int|string sign value, or a string containing an error + * @return array|int|string sign value, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php index 18289f7..60c152e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php @@ -16,7 +16,7 @@ class Sqrt * * @param mixed $number Should be numeric, or can be an array of numbers * - * @return array|float|string square root + * @return array|float|string square root * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -40,9 +40,9 @@ class Sqrt * * Returns the square root of (number * pi). * - * @param array|float $number Number, or can be an array of numbers + * @param array|float $number Number, or can be an array of numbers * - * @return array|float|string Square Root of Number * Pi, or a string containing an error + * @return array|float|string Square Root of Number * Pi, or a string containing an error * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php index cfced9e..09f9cfa 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php @@ -6,10 +6,16 @@ use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Cell\Cell; class Subtotal { - protected static function filterHiddenArgs(mixed $cellReference, mixed $args): array + /** + * @param mixed[] $args + * + * @return mixed[] + */ + protected static function filterHiddenArgs(Cell $cellReference, array $args): array { return array_filter( $args, @@ -20,13 +26,18 @@ class Subtotal return true; } - return $cellReference->getWorksheet()->getRowDimension($row)->getVisible(); + return $cellReference->getWorksheet()->getRowDimension((int) $row)->getVisible(); }, ARRAY_FILTER_USE_KEY ); } - protected static function filterFormulaArgs(mixed $cellReference, mixed $args): array + /** + * @param mixed[] $args + * + * @return mixed[] + */ + protected static function filterFormulaArgs(Cell $cellReference, array $args): array { return array_filter( $args, @@ -40,7 +51,7 @@ class Subtotal $isFormula = $cellReference->getWorksheet()->getCell($column . $row)->isFormula(); $cellFormula = !preg_match( '/^=.*\b(SUBTOTAL|AGGREGATE)\s*\(/i', - $cellReference->getWorksheet()->getCell($column . $row)->getValue() ?? '' + $cellReference->getWorksheet()->getCell($column . $row)->getValueString() ); $retVal = !$isFormula || $cellFormula; @@ -85,6 +96,7 @@ class Subtotal */ public static function evaluate(mixed $functionType, ...$args): float|int|string { + /** @var Cell */ $cellReference = array_pop($args); $bArgs = Functions::flattenArrayIndexed($args); $aArgs = []; @@ -119,7 +131,7 @@ class Subtotal if (array_key_exists($subtotal, self::CALL_FUNCTIONS)) { $call = self::CALL_FUNCTIONS[$subtotal]; - return call_user_func_array($call, $aArgs); + return call_user_func_array($call, $aArgs); //* @phpstan-ignore-line } return ExcelError::VALUE(); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php index f939d9e..b5d0339 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php @@ -28,6 +28,7 @@ class Sum if (is_numeric($arg)) { $returnValue += $arg; } elseif (ErrorValue::isError($arg)) { + /** @var string $arg */ return $arg; } } @@ -44,6 +45,8 @@ class Sum * SUM(value1[,value2[, ...]]) * * @param mixed ...$args Data values + * + * @return array|float|int|string */ public static function sumErroringStrings(mixed ...$args): float|int|string|array { @@ -57,6 +60,7 @@ class Sum } elseif (is_bool($arg)) { $returnValue += (int) $arg; } elseif (ErrorValue::isError($arg)) { + /** @var string $arg */ return $arg; } elseif ($arg !== null && !Functions::isCellValue($k)) { // ignore non-numerics from cell, but fail as literals (except null) @@ -101,6 +105,7 @@ class Sum if ((!is_numeric($val)) || (is_string($val))) { $val = 0; } + /** @var array $wrkArray */ $wrkArray[$i] *= $val; } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/SumSquares.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/SumSquares.php index b2e9cea..f37be22 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/SumSquares.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/SumSquares.php @@ -35,6 +35,10 @@ class SumSquares return $returnValue; } + /** + * @param mixed[] $array1 + * @param mixed[] $array2 + */ private static function getCount(array $array1, array $array2): int { $count = count($array1); @@ -62,7 +66,9 @@ class SumSquares public static function sumXSquaredMinusYSquared(array $matrixData1, array $matrixData2): string|int|float { try { + /** @var array */ $array1 = Functions::flattenArray($matrixData1); + /** @var array */ $array2 = Functions::flattenArray($matrixData2); $count = self::getCount($array1, $array2); @@ -88,7 +94,9 @@ class SumSquares public static function sumXSquaredPlusYSquared(array $matrixData1, array $matrixData2): string|int|float { try { + /** @var array */ $array1 = Functions::flattenArray($matrixData1); + /** @var array */ $array2 = Functions::flattenArray($matrixData2); $count = self::getCount($array1, $array2); @@ -114,7 +122,9 @@ class SumSquares public static function sumXMinusYSquared(array $matrixData1, array $matrixData2): string|int|float { try { + /** @var array */ $array1 = Functions::flattenArray($matrixData1); + /** @var array */ $array2 = Functions::flattenArray($matrixData2); $count = self::getCount($array1, $array2); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php index 845b6c1..b131b04 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php @@ -15,9 +15,9 @@ class Cosecant * * Returns the cosecant of an angle. * - * @param array|float $angle Number, or can be an array of numbers + * @param array|float $angle Number, or can be an array of numbers * - * @return array|float|string The cosecant of the angle + * @return array|float|string The cosecant of the angle * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -41,9 +41,9 @@ class Cosecant * * Returns the hyperbolic cosecant of an angle. * - * @param array|float $angle Number, or can be an array of numbers + * @param array|float $angle Number, or can be an array of numbers * - * @return array|float|string The hyperbolic cosecant of the angle + * @return array|float|string The hyperbolic cosecant of the angle * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php index 733e3d6..010a1c2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php @@ -17,7 +17,7 @@ class Cosine * * @param mixed $number Should be numeric, or can be an array of numbers * - * @return array|float|string cosine + * @return array|float|string cosine * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -43,7 +43,7 @@ class Cosine * * @param mixed $number Should be numeric, or can be an array of numbers * - * @return array|float|string hyperbolic cosine + * @return array|float|string hyperbolic cosine * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -67,9 +67,9 @@ class Cosine * * Returns the arccosine of a number. * - * @param array|float $number Number, or can be an array of numbers + * @param array|float $number Number, or can be an array of numbers * - * @return array|float|string The arccosine of the number + * @return array|float|string The arccosine of the number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -93,9 +93,9 @@ class Cosine * * Returns the arc inverse hyperbolic cosine of a number. * - * @param array|float $number Number, or can be an array of numbers + * @param array|float $number Number, or can be an array of numbers * - * @return array|float|string The inverse hyperbolic cosine of the number, or an error string + * @return array|float|string The inverse hyperbolic cosine of the number, or an error string * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php index 861159a..34b4c00 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php @@ -15,9 +15,9 @@ class Cotangent * * Returns the cotangent of an angle. * - * @param array|float $angle Number, or can be an array of numbers + * @param array|float $angle Number, or can be an array of numbers * - * @return array|float|string The cotangent of the angle + * @return array|float|string The cotangent of the angle * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -41,9 +41,9 @@ class Cotangent * * Returns the hyperbolic cotangent of an angle. * - * @param array|float $angle Number, or can be an array of numbers + * @param array|float $angle Number, or can be an array of numbers * - * @return array|float|string The hyperbolic cotangent of the angle + * @return array|float|string The hyperbolic cotangent of the angle * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -67,9 +67,9 @@ class Cotangent * * Returns the arccotangent of a number. * - * @param array|float $number Number, or can be an array of numbers + * @param array|float $number Number, or can be an array of numbers * - * @return array|float|string The arccotangent of the number + * @return array|float|string The arccotangent of the number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -93,9 +93,9 @@ class Cotangent * * Returns the hyperbolic arccotangent of a number. * - * @param array|float $number Number, or can be an array of numbers + * @param array|float $number Number, or can be an array of numbers * - * @return array|float|string The hyperbolic arccotangent of the number + * @return array|float|string The hyperbolic arccotangent of the number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php index 2d26e5d..6c9d317 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php @@ -15,9 +15,9 @@ class Secant * * Returns the secant of an angle. * - * @param array|float $angle Number, or can be an array of numbers + * @param array|float $angle Number, or can be an array of numbers * - * @return array|float|string The secant of the angle + * @return array|float|string The secant of the angle * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -41,9 +41,9 @@ class Secant * * Returns the hyperbolic secant of an angle. * - * @param array|float $angle Number, or can be an array of numbers + * @param array|float $angle Number, or can be an array of numbers * - * @return array|float|string The hyperbolic secant of the angle + * @return array|float|string The hyperbolic secant of the angle * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php index 924466e..5aad809 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php @@ -17,7 +17,7 @@ class Sine * * @param mixed $angle Should be numeric, or can be an array of numbers * - * @return array|float|string sine + * @return array|float|string sine * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -43,7 +43,7 @@ class Sine * * @param mixed $angle Should be numeric, or can be an array of numbers * - * @return array|float|string hyperbolic sine + * @return array|float|string hyperbolic sine * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -67,9 +67,9 @@ class Sine * * Returns the arcsine of a number. * - * @param array|float $number Number, or can be an array of numbers + * @param array|float $number Number, or can be an array of numbers * - * @return array|float|string The arcsine of the number + * @return array|float|string The arcsine of the number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -93,9 +93,9 @@ class Sine * * Returns the inverse hyperbolic sine of a number. * - * @param array|float $number Number, or can be an array of numbers + * @param array|float $number Number, or can be an array of numbers * - * @return array|float|string The inverse hyperbolic sine of the number + * @return array|float|string The inverse hyperbolic sine of the number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php index 9d6775f..a243bb7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php @@ -18,7 +18,7 @@ class Tangent * * @param mixed $angle Should be numeric, or can be an array of numbers * - * @return array|float|string tangent + * @return array|float|string tangent * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -44,7 +44,7 @@ class Tangent * * @param mixed $angle Should be numeric, or can be an array of numbers * - * @return array|float|string hyperbolic tangent + * @return array|float|string hyperbolic tangent * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -68,9 +68,9 @@ class Tangent * * Returns the arctangent of a number. * - * @param array|float $number Number, or can be an array of numbers + * @param array|float $number Number, or can be an array of numbers * - * @return array|float|string The arctangent of the number + * @return array|float|string The arctangent of the number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -94,9 +94,9 @@ class Tangent * * Returns the inverse hyperbolic tangent of a number. * - * @param array|float $number Number, or can be an array of numbers + * @param array|float $number Number, or can be an array of numbers * - * @return array|float|string The inverse hyperbolic tangent of the number + * @return array|float|string The inverse hyperbolic tangent of the number * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -134,7 +134,7 @@ class Tangent * @param mixed $xCoordinate should be float, the x-coordinate of the point, or can be an array of numbers * @param mixed $yCoordinate should be float, the y-coordinate of the point, or can be an array of numbers * - * @return array|float|string The inverse tangent of the specified x- and y-coordinates, or a string containing an error + * @return array|float|string The inverse tangent of the specified x- and y-coordinates, or a string containing an error * If an array of numbers is passed as one of the arguments, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trunc.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trunc.php index 096b27a..e032c20 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trunc.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Trunc.php @@ -18,10 +18,10 @@ class Trunc * (or possibly that value minus 1). * Excel is unlikely to do any better. * - * @param null|array|float|string $value Or can be an array of values - * @param array|float|int|string $digits Or can be an array of values + * @param null|array|float|string $value Or can be an array of values + * @param array|float|int|string $digits Or can be an array of values * - * @return array|float|string Truncated value, or a string containing an error + * @return array|float|string Truncated value, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Averages.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Averages.php index 789e529..5880982 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Averages.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Averages.php @@ -44,6 +44,8 @@ class Averages extends AggregateBase return ExcelError::VALUE(); } if (self::isAcceptedCountable($arg, $k)) { + /** @var float|int|numeric-string $arg */ + /** @var float|int|numeric-string $aMean */ $returnValue += abs($arg - $aMean); ++$aCount; } @@ -83,6 +85,7 @@ class Averages extends AggregateBase return ExcelError::VALUE(); } if (self::isAcceptedCountable($arg, $k)) { + /** @var float|int|numeric-string $arg */ $returnValue += $arg; ++$aCount; } @@ -153,13 +156,14 @@ class Averages extends AggregateBase $returnValue = ExcelError::NAN(); + /** @var array */ $aArgs = self::filterArguments($aArgs); $valueCount = count($aArgs); if ($valueCount > 0) { sort($aArgs, SORT_NUMERIC); $valueCount = $valueCount / 2; if ($valueCount == floor($valueCount)) { - $returnValue = ($aArgs[$valueCount--] + $aArgs[$valueCount]) / 2; + $returnValue = ($aArgs[$valueCount--] + $aArgs[$valueCount]) / 2; //* @phpstan-ignore-line } else { $valueCount = (int) floor($valueCount); $returnValue = $aArgs[$valueCount]; @@ -196,6 +200,11 @@ class Averages extends AggregateBase return $returnValue; } + /** + * @param mixed[] $args + * + * @return mixed[] + */ protected static function filterArguments(array $args): array { return array_filter( @@ -210,6 +219,8 @@ class Averages extends AggregateBase /** * Special variant of array_count_values that isn't limited to strings and integers, * but can work with floating point numbers as values. + * + * @param mixed[] $data */ private static function modeCalc(array $data): float|string { @@ -219,9 +230,11 @@ class Averages extends AggregateBase $maxfreqkey = ''; $maxfreqdatum = ''; foreach ($data as $datum) { + /** @var float|string $datum */ $found = false; ++$index; foreach ($frequencyArray as $key => $value) { + /** @var string[] $value */ if ((string) $value['value'] == (string) $datum) { ++$frequencyArray[$key]['frequency']; $freq = $frequencyArray[$key]['frequency']; @@ -230,7 +243,7 @@ class Averages extends AggregateBase $maxfreqkey = $key; $maxfreqdatum = $datum; } elseif ($freq == $maxfreq) { - if ($frequencyArray[$key]['index'] < $frequencyArray[$maxfreqkey]['index']) { + if ($frequencyArray[$key]['index'] < $frequencyArray[$maxfreqkey]['index']) { //* @phpstan-ignore-line $maxfreqkey = $key; $maxfreqdatum = $datum; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php index 5f75aef..818d9db 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php @@ -26,7 +26,7 @@ class Conditional * AVERAGEIF(range,condition[, average_range]) * * @param mixed $range Data values, expect array - * @param null|array|string $condition the criteria that defines which cells will be checked + * @param null|mixed[]|string $condition the criteria that defines which cells will be checked * @param mixed $averageRange Data values */ public static function AVERAGEIF(mixed $range, null|array|string $condition, mixed $averageRange = []): null|int|float|string @@ -40,6 +40,7 @@ class Conditional throw new CalcException('Must specify range of cells, not any kind of literal'); } $database = self::databaseFromRangeAndValue($range, $averageRange); + $condition = Functions::flattenSingleValue($condition); $condition = [[self::CONDITION_COLUMN_NAME, self::VALUE_COLUMN_NAME], [$condition, null]]; return DAverage::evaluate($database, self::VALUE_COLUMN_NAME, $condition); @@ -59,8 +60,9 @@ class Conditional { if (empty($args)) { return 0.0; - } elseif (count($args) === 3) { - return self::AVERAGEIF($args[1], $args[2], $args[0]); + } + if (count($args) === 3) { + return self::AVERAGEIF($args[1], $args[2], $args[0]); //* @phpstan-ignore-line } foreach ($args as $arg) { if (is_array($arg) && array_key_exists(0, $arg)) { @@ -83,7 +85,7 @@ class Conditional * COUNTIF(range,condition) * * @param mixed $range Data values, expect array - * @param null|array|string $condition the criteria that defines which cells will be counted + * @param null|mixed[]|string $condition the criteria that defines which cells will be counted */ public static function COUNTIF(mixed $range, null|array|string $condition): string|int { @@ -104,6 +106,7 @@ class Conditional ); $range = array_merge([[self::CONDITION_COLUMN_NAME]], array_chunk($range, 1)); + $condition = Functions::flattenSingleValue($condition); $condition = array_merge([[self::CONDITION_COLUMN_NAME]], [[$condition]]); return DCount::evaluate($range, null, $condition, false); @@ -204,6 +207,7 @@ class Conditional throw new CalcException('Must specify range of cells, not any kind of literal'); } $database = self::databaseFromRangeAndValue($range, $sumRange); + $condition = Functions::flattenSingleValue($condition); $condition = [[self::CONDITION_COLUMN_NAME, self::VALUE_COLUMN_NAME], [$condition, null]]; return DSum::evaluate($database, self::VALUE_COLUMN_NAME, $condition); @@ -233,7 +237,11 @@ class Conditional return DSum::evaluate($database, self::VALUE_COLUMN_NAME, $conditions); } - /** @param array $args */ + /** + * @param mixed[] $args + * + * @return mixed[][] + */ private static function buildConditionSet(...$args): array { $conditions = self::buildConditions(1, ...$args); @@ -241,7 +249,11 @@ class Conditional return array_map(null, ...$conditions); } - /** @param array $args */ + /** + * @param mixed[] $args + * + * @return mixed[][] + */ private static function buildConditionSetForValueRange(...$args): array { $conditions = self::buildConditions(2, ...$args); @@ -256,7 +268,11 @@ class Conditional return array_map(null, ...$conditions); } - /** @param array $args */ + /** + * @param mixed[] $args + * + * @return mixed[][] + */ private static function buildConditions(int $startOffset, ...$args): array { $conditions = []; @@ -271,7 +287,11 @@ class Conditional return $conditions; } - /** @param array $args */ + /** + * @param mixed[] $args + * + * @return mixed[] + */ private static function buildDatabase(...$args): array { $database = []; @@ -279,7 +299,11 @@ class Conditional return self::buildDataSet(0, $database, ...$args); } - /** @param array $args */ + /** + * @param mixed[] $args + * + * @return mixed[] + */ private static function buildDatabaseWithValueRange(...$args): array { $database = []; @@ -291,7 +315,12 @@ class Conditional return self::buildDataSet(1, $database, ...$args); } - /** @param array $args */ + /** + * @param mixed[][] $database + * @param mixed[] $args + * + * @return mixed[] + */ private static function buildDataSet(int $startOffset, array $database, ...$args): array { $pairCount = 1; @@ -307,6 +336,12 @@ class Conditional return array_map(null, ...$database); } + /** + * @param mixed[] $range + * @param mixed[] $valueRange + * + * @return mixed[] + */ private static function databaseFromRangeAndValue(array $range, array $valueRange = []): array { $range = Functions::flattenArray($range); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php index 492438a..fe3232d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php @@ -23,7 +23,7 @@ class Confidence * @param mixed $size As an integer * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function CONFIDENCE(mixed $alpha, mixed $stdDev, mixed $size) @@ -46,6 +46,9 @@ class Confidence /** @var float $temp */ $temp = Distributions\StandardNormal::inverse(1 - $alpha / 2); - return Functions::scalar($temp * $stdDev / sqrt($size)); + /** @var float */ + $result = Functions::scalar($temp * $stdDev / sqrt($size)); + + return $result; } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Deviations.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Deviations.php index 4ac6cb5..e6ffe8d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Deviations.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Deviations.php @@ -55,7 +55,7 @@ class Deviations * kurtosis indicates a relatively peaked distribution. Negative kurtosis indicates a * relatively flat distribution. * - * @param array ...$args Data Series + * @param mixed[] ...$args Data Series */ public static function kurtosis(...$args): string|int|float { @@ -98,7 +98,7 @@ class Deviations * asymmetric tail extending toward more positive values. Negative skewness indicates a * distribution with an asymmetric tail extending toward more negative values. * - * @param array ...$args Data Series + * @param mixed[] ...$args Data Series * * @return float|int|string The result, or a string containing an error */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php index 16817ce..378ce8a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php @@ -33,7 +33,7 @@ class Beta * @param mixed $rMax as an float * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function distribution(mixed $value, mixed $alpha, mixed $beta, mixed $rMin = 0.0, mixed $rMax = 1.0): array|string|float @@ -86,7 +86,7 @@ class Beta * @param mixed $rMax Maximum value as a float * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function inverse(mixed $probability, mixed $alpha, mixed $beta, mixed $rMin = 0.0, mixed $rMax = 1.0): array|string|float diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php index 2ce3fd5..67cf402 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php @@ -30,7 +30,7 @@ class Binomial * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function distribution(mixed $value, mixed $trials, mixed $probability, mixed $cumulative) @@ -78,7 +78,7 @@ class Binomial * If null, then this will indicate the same as the number of Successes * Or can be an array of values * - * @return array|float|int|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|int|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function range(mixed $trials, mixed $probability, mixed $successes, mixed $limit = null): array|string|float|int @@ -132,7 +132,7 @@ class Binomial * @param mixed $probability Probability of success on each trial as a float * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions * @@ -181,7 +181,7 @@ class Binomial * @param mixed $alpha criterion value as a float * Or can be an array of values * - * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function inverse(mixed $trials, mixed $probability, mixed $alpha): array|string|int diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php index edc50ad..b132484 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php @@ -23,7 +23,7 @@ class ChiSquared * @param mixed $degrees Integer degrees of freedom * Or can be an array of values * - * @return array|float|int|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|int|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function distributionRightTail(mixed $value, mixed $degrees): array|string|int|float @@ -65,7 +65,7 @@ class ChiSquared * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|int|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|int|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function distributionLeftTail(mixed $value, mixed $degrees, mixed $cumulative): array|string|int|float @@ -113,7 +113,7 @@ class ChiSquared * @param mixed $degrees Integer degrees of freedom * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function inverseRightTail(mixed $probability, mixed $degrees) @@ -133,7 +133,7 @@ class ChiSquared return ExcelError::NAN(); } - $callback = fn ($value): float => 1 - (Gamma::incompleteGamma($degrees / 2, $value / 2) + $callback = fn (float $value): float => 1 - (Gamma::incompleteGamma($degrees / 2, $value / 2) / Gamma::gammaValue($degrees / 2)); $newtonRaphson = new NewtonRaphson($callback); @@ -151,7 +151,7 @@ class ChiSquared * @param mixed $degrees Integer degrees of freedom * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function inverseLeftTail(mixed $probability, mixed $degrees): array|string|float @@ -181,13 +181,15 @@ class ChiSquared * (of observed and expected frequencies), are likely to be simply due to sampling error, * or if they are likely to be real. * - * @param mixed $actual an array of observed frequencies - * @param mixed $expected an array of expected frequencies + * @param float[] $actual an array of observed frequencies + * @param float[] $expected an array of expected frequencies */ - public static function test(mixed $actual, mixed $expected): float|string + public static function test($actual, $expected): float|string { $rows = count($actual); + /** @var float[] */ $actual = Functions::flattenArray($actual); + /** @var float[] */ $expected = Functions::flattenArray($expected); $columns = intdiv(count($actual), $rows); @@ -209,6 +211,7 @@ class ChiSquared $degrees = self::degrees($rows, $columns); + /** @var float|string */ $result = Functions::scalar(self::distributionRightTail($result, $degrees)); return $result; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php index 5526473..9acbf57 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php @@ -24,7 +24,7 @@ class Exponential * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function distribution(mixed $value, mixed $lambda, mixed $cumulative): array|string|float diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php index aa7a19d..0127565 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php @@ -27,7 +27,7 @@ class F * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function distribution(mixed $value, mixed $u, mixed $v, mixed $cumulative): array|string|float diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php index 9ad10db..2036a2a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php @@ -20,7 +20,7 @@ class Fisher * @param mixed $value Float value for which we want the probability * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function distribution(mixed $value): array|string|float @@ -30,7 +30,7 @@ class Fisher } try { - DistributionValidations::validateFloat($value); + $value = DistributionValidations::validateFloat($value); } catch (Exception $e) { return $e->getMessage(); } @@ -52,7 +52,7 @@ class Fisher * @param mixed $probability Float probability at which you want to evaluate the distribution * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function inverse(mixed $probability): array|string|float @@ -62,7 +62,7 @@ class Fisher } try { - DistributionValidations::validateFloat($probability); + $probability = DistributionValidations::validateFloat($probability); } catch (Exception $e) { return $e->getMessage(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php index babe937..60f5309 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php @@ -18,7 +18,7 @@ class Gamma extends GammaBase * @param mixed $value Float value for which we want the probability * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -55,7 +55,7 @@ class Gamma extends GammaBase * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function distribution(mixed $value, mixed $a, mixed $b, mixed $cumulative) @@ -92,7 +92,7 @@ class Gamma extends GammaBase * @param mixed $beta Parameter to the distribution as a float * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function inverse(mixed $probability, mixed $alpha, mixed $beta) @@ -124,7 +124,7 @@ class Gamma extends GammaBase * @param mixed $value Float Value at which you want to evaluate the distribution * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function ln(mixed $value): array|string|float diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php index 3a74bab..4ae6075 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php @@ -91,6 +91,16 @@ abstract class GammaBase return $x ** $a * exp(0 - $x) * $summer; } + private const GAMMA_VALUE_P0 = 1.000000000190015; + private const GAMMA_VALUE_P = [ + 1 => 76.18009172947146, + 2 => -86.50532032941677, + 3 => 24.01409824083091, + 4 => -1.231739572450155, + 5 => 1.208650973866179e-3, + 6 => -5.395239384953e-6, + ]; + // // Implementation of the Gamma function // @@ -100,23 +110,13 @@ abstract class GammaBase return 0; } - static $p0 = 1.000000000190015; - static $p = [ - 1 => 76.18009172947146, - 2 => -86.50532032941677, - 3 => 24.01409824083091, - 4 => -1.231739572450155, - 5 => 1.208650973866179e-3, - 6 => -5.395239384953e-6, - ]; - $y = $x = $value; $tmp = $x + 5.5; $tmp -= ($x + 0.5) * log($tmp); - $summer = $p0; + $summer = self::GAMMA_VALUE_P0; for ($j = 1; $j <= 6; ++$j) { - $summer += ($p[$j] / ++$y); + $summer += (self::GAMMA_VALUE_P[$j] / ++$y); } return exp(0 - $tmp + log(self::SQRT2PI * $summer / $x)); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php index 345ea81..697b875 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php @@ -26,7 +26,7 @@ class HyperGeometric * @param mixed $populationNumber Integer population size * Or can be an array of values * - * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function distribution(mixed $sampleSuccesses, mixed $sampleNumber, mixed $populationSuccesses, mixed $populationNumber): array|string|float diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php index 50f02e4..a3309b4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php @@ -23,7 +23,7 @@ class LogNormal * @param mixed $stdDev Standard Deviation as a float * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -63,7 +63,7 @@ class LogNormal * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -106,7 +106,7 @@ class LogNormal * @param mixed $stdDev Standard Deviation as a float * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions * diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php index 647c0c4..b2348dc 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php @@ -9,9 +9,10 @@ class NewtonRaphson { private const MAX_ITERATIONS = 256; - /** @var callable */ + /** @var callable(float): mixed */ protected $callback; + /** @param callable(float): mixed $callback */ public function __construct(callable $callback) { $this->callback = $callback; @@ -29,6 +30,9 @@ class NewtonRaphson while ((abs($dx) > Functions::PRECISION) && ($i++ < self::MAX_ITERATIONS)) { // Apply Newton-Raphson step $result = call_user_func($this->callback, $x); + if (!is_float($result)) { + return ExcelError::VALUE(); + } $error = $result - $probability; if ($error == 0.0) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php index 8d08d57..7e2ee92 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php @@ -29,7 +29,7 @@ class Normal * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -71,7 +71,7 @@ class Normal * @param mixed $stdDev Standard Deviation as a float * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -119,6 +119,7 @@ class Normal // Input paramater is $p - probability - where 0 < p < 1. // Coefficients in rational approximations + /** @var array */ static $a = [ 1 => -3.969683028665376e+01, 2 => 2.209460984245205e+02, @@ -128,6 +129,7 @@ class Normal 6 => 2.506628277459239e+00, ]; + /** @var array */ static $b = [ 1 => -5.447609879822406e+01, 2 => 1.615858368580409e+02, @@ -136,6 +138,7 @@ class Normal 5 => -1.328068155288572e+01, ]; + /** @var array */ static $c = [ 1 => -7.784894002430293e-03, 2 => -3.223964580411365e-01, @@ -145,6 +148,7 @@ class Normal 6 => 2.938163982698783e+00, ]; + /** @var array */ static $d = [ 1 => 7.784695709041462e-03, 2 => 3.224671290700398e-01, diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php index 931568e..cf9a776 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php @@ -25,7 +25,7 @@ class Poisson * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php index cb2c646..474f3ec 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php @@ -26,7 +26,7 @@ class StandardNormal * @param mixed $value Float value for which we want the probability * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -51,7 +51,7 @@ class StandardNormal * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -72,7 +72,7 @@ class StandardNormal * handled by the logic in Normal::inverse() * All we need to do is pass the value through as scalar or as array * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -89,7 +89,7 @@ class StandardNormal * * @param mixed $value Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -123,7 +123,7 @@ class StandardNormal * if null, we use the standard deviation of the dataset * Or can be an array of values * - * @return array|float|string (string if result is an error) + * @return array|float|string (string if result is an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StudentT.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StudentT.php index 5ec6489..cbe7d84 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StudentT.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StudentT.php @@ -23,7 +23,7 @@ class StudentT * @param mixed $tails Integer value for the number of tails (1 or 2) * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -58,7 +58,7 @@ class StudentT * @param mixed $degrees Integer value for degrees of freedom * Or can be an array of values * - * @return array|float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Weibull.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Weibull.php index 2f20b62..30ff2ef 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Weibull.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Weibull.php @@ -25,7 +25,7 @@ class Weibull * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) * Or can be an array of values * - * @return array|float|string (string if result is an error) + * @return array|float|string (string if result is an error) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Maximum.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Maximum.php index 47a98e6..88531a5 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Maximum.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Maximum.php @@ -41,6 +41,7 @@ class Maximum extends MaxMinBase if ($returnValue === null) { return 0; } + /** @var float|int|string $returnValue */ return $returnValue; } @@ -79,6 +80,7 @@ class Maximum extends MaxMinBase if ($returnValue === null) { return 0; } + /** @var float|int|string $returnValue */ return $returnValue; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Minimum.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Minimum.php index fcb77c6..874edc3 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Minimum.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Minimum.php @@ -41,6 +41,7 @@ class Minimum extends MaxMinBase if ($returnValue === null) { return 0; } + /** @var float|int|string $returnValue */ return $returnValue; } @@ -79,6 +80,7 @@ class Minimum extends MaxMinBase if ($returnValue === null) { return 0; } + /** @var float|int|string $returnValue */ return $returnValue; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php index dff0287..f2ee15f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php @@ -45,6 +45,7 @@ class Percentiles $mValueCount = count($mArgs); if ($mValueCount > 0) { sort($mArgs); + /** @var float[] $mArgs */ $count = Counts::COUNT($mArgs); $index = $entry * ($count - 1); $indexFloor = floor($index); @@ -102,6 +103,7 @@ class Percentiles $pos = array_search($value, $valueSet); if ($pos === false) { + /** @var float[] $valueSet */ $pos = 0; $testValue = $valueSet[0]; while ($testValue < $value) { @@ -185,6 +187,11 @@ class Percentiles return ++$pos; } + /** + * @param mixed[] $dataSet + * + * @return mixed[] + */ protected static function percentileFilterValues(array $dataSet): array { return array_filter( @@ -193,6 +200,11 @@ class Percentiles ); } + /** + * @param mixed[] $dataSet + * + * @return mixed[] + */ protected static function rankFilterValues(array $dataSet): array { return array_filter( diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php index 06e3b79..4863e14 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php @@ -26,7 +26,7 @@ class Permutations * @param mixed $numInSet Integer number of objects in each permutation * Or can be an array of values * - * @return array|float|int|string Number of permutations, or a string containing an error + * @return array|float|int|string Number of permutations, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ @@ -72,7 +72,7 @@ class Permutations * @param mixed $numInSet Integer number of objects in each permutation * Or can be an array of values * - * @return array|float|int|string Number of permutations, or a string containing an error + * @return array|float|int|string Number of permutations, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Size.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Size.php index 71594bd..134aa66 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Size.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Size.php @@ -35,6 +35,7 @@ class Size return ExcelError::NAN(); } rsort($mArgs); + /** @var float[] $mArgs */ return $mArgs[$entry]; } @@ -71,6 +72,7 @@ class Size return ExcelError::NAN(); } sort($mArgs); + /** @var float[] $mArgs */ return $mArgs[$entry]; } @@ -80,6 +82,8 @@ class Size /** * @param mixed[] $args Data values + * + * @return mixed[] */ protected static function filter(array $args): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Standardize.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Standardize.php index b8e7350..2868194 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Standardize.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Standardize.php @@ -15,14 +15,14 @@ class Standardize extends StatisticalValidations * * Returns a normalized value from a distribution characterized by mean and standard_dev. * - * @param array|float $value Value to normalize + * @param array|float $value Value to normalize * Or can be an array of values - * @param array|float $mean Mean Value + * @param array|float $mean Mean Value * Or can be an array of values - * @param array|float $stdDev Standard Deviation + * @param array|float $stdDev Standard Deviation * Or can be an array of values * - * @return array|float|string Standardized value, or a string containing an error + * @return array|float|string Standardized value, or a string containing an error * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Trends.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Trends.php index 365001f..a768808 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Trends.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Trends.php @@ -12,6 +12,10 @@ class Trends { use ArrayEnabled; + /** + * @param array $array1 + * @param array $array2 + */ private static function filterTrendValues(array &$array1, array &$array2): void { foreach ($array1 as $key => $value) { @@ -24,6 +28,9 @@ class Trends /** * @param mixed $array1 should be array, but scalar is made into one * @param mixed $array2 should be array, but scalar is made into one + * + * @param-out array $array1 + * @param-out array $array2 */ private static function checkTrendArrays(mixed &$array1, mixed &$array2): void { @@ -45,6 +52,10 @@ class Trends $array2 = array_merge($array2); } + /** + * @param mixed[] $yValues + * @param mixed[] $xValues + */ protected static function validateTrendArrays(array $yValues, array $xValues): void { $yValueCount = count($yValues); @@ -116,7 +127,7 @@ class Trends * @param mixed[] $yValues array of mixed Data Series Y * @param mixed[] $xValues array of mixed Data Series X * - * @return array|bool|float|string If an array of numbers is passed as an argument, then the returned result will also be an array + * @return array|bool|float|string If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ public static function FORECAST(mixed $xValue, array $yValues, array $xValues) @@ -164,6 +175,7 @@ class Trends $returnArray = []; foreach ($newValues as $xValue) { + /** @var float $xValue */ $returnArray[0][] = [$bestFitExponential->getValueOfYForX($xValue)]; } @@ -203,7 +215,7 @@ class Trends * @param mixed $const A logical (boolean) value specifying whether to force the intersect to equal 0 or not * @param mixed $stats A logical (boolean) value specifying whether to return additional regression statistics * - * @return array|string The result, or a string containing an error + * @return array|string The result, or a string containing an error */ public static function LINEST(array $yValues, ?array $xValues = null, mixed $const = true, mixed $stats = false): string|array { @@ -264,7 +276,7 @@ class Trends * @param mixed $const A logical (boolean) value specifying whether to force the intersect to equal 0 or not * @param mixed $stats A logical (boolean) value specifying whether to return additional regression statistics * - * @return array|string The result, or a string containing an error + * @return array|string The result, or a string containing an error */ public static function LOGEST(array $yValues, ?array $xValues = null, mixed $const = true, mixed $stats = false): string|array { @@ -417,6 +429,7 @@ class Trends $returnArray = []; foreach ($newValues as $xValue) { + /** @var float $xValue */ $returnArray[0][] = [$bestFitLinear->getValueOfYForX($xValue)]; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CaseConvert.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CaseConvert.php index 6667bac..ff67feb 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CaseConvert.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CaseConvert.php @@ -18,7 +18,7 @@ class CaseConvert * @param mixed $mixedCaseValue The string value to convert to lower case * Or can be an array of values * - * @return array|string If an array of values is passed as the argument, then the returned result will also be an array + * @return array|string If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function lower(mixed $mixedCaseValue): array|string @@ -44,7 +44,7 @@ class CaseConvert * @param mixed $mixedCaseValue The string value to convert to upper case * Or can be an array of values * - * @return array|string If an array of values is passed as the argument, then the returned result will also be an array + * @return array|string If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function upper(mixed $mixedCaseValue): array|string @@ -70,7 +70,7 @@ class CaseConvert * @param mixed $mixedCaseValue The string value to convert to title case * Or can be an array of values * - * @return array|string If an array of values is passed as the argument, then the returned result will also be an array + * @return array|string If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function proper(mixed $mixedCaseValue): array|string diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php index 06d0f90..2f15bfc 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php @@ -17,7 +17,7 @@ class CharacterConvert * @param mixed $character Integer Value to convert to its character representation * Or can be an array of values * - * @return array|string The character string + * @return array|string The character string * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -48,7 +48,7 @@ class CharacterConvert * @param mixed $characters String character to convert to its ASCII value * Or can be an array of values * - * @return array|int|string A string if arguments are invalid + * @return array|int|string A string if arguments are invalid * If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ @@ -81,6 +81,7 @@ class CharacterConvert $retVal = 0; $iconv = iconv('UTF-8', 'UCS-4LE', $character); if ($iconv !== false) { + /** @var false|int[] */ $result = unpack('V', $iconv); if (is_array($result) && isset($result[1])) { $retVal = $result[1]; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php index a48d053..d51d44b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php @@ -17,7 +17,7 @@ class Concatenate /** * This implements the CONCAT function, *not* CONCATENATE. * - * @param array $args + * @param mixed[] $args */ public static function CONCATENATE(...$args): string { @@ -47,7 +47,9 @@ class Concatenate /** * This implements the CONCATENATE function. * - * @param array $args data to be concatenated + * @param mixed[] $args data to be concatenated + * + * @return array|string */ public static function actualCONCATENATE(...$args): array|string { @@ -65,6 +67,12 @@ class Concatenate return $result; } + /** + * @param array|string $operand1 + * @param null|array|bool|float|int|string $operand2 + * + * @return array|string + */ private static function concatenate2Args(array|string $operand1, null|array|bool|float|int|string $operand2): array|string { if (is_array($operand1) || is_array($operand2)) { @@ -74,12 +82,14 @@ class Concatenate $errorFound = false; for ($row = 0; $row < $rows && !$errorFound; ++$row) { for ($column = 0; $column < $columns; ++$column) { + /** @var string[][] $operand2 */ if (ErrorValue::isError($operand2[$row][$column])) { return $operand2[$row][$column]; } + /** @var string[][] $operand1 */ $operand1[$row][$column] - = Calculation::boolToString($operand1[$row][$column]) - . Calculation::boolToString($operand2[$row][$column]); + = StringHelper::convertToString($operand1[$row][$column], convertBool: true) + . StringHelper::convertToString($operand2[$row][$column], convertBool: true); if (mb_strlen($operand1[$row][$column]) > DataType::MAX_STRING_LENGTH) { $operand1 = ExcelError::CALC(); $errorFound = true; @@ -91,11 +101,12 @@ class Concatenate } elseif (ErrorValue::isError($operand2, true) === true) { $operand1 = (string) $operand2; } else { - $operand1 .= (string) Calculation::boolToString($operand2); + $operand1 .= StringHelper::convertToString($operand2, convertBool: true); if (mb_strlen($operand1) > DataType::MAX_STRING_LENGTH) { $operand1 = ExcelError::CALC(); } } + /** @var array|string $operand1 */ return $operand1; } @@ -103,17 +114,17 @@ class Concatenate /** * TEXTJOIN. * - * @param mixed $delimiter The delimter to use between the joined arguments + * @param null|string|string[] $delimiter The delimiter to use between the joined arguments * Or can be an array of values - * @param mixed $ignoreEmpty true/false Flag indicating whether empty arguments should be skipped + * @param null|bool|bool[] $ignoreEmpty true/false Flag indicating whether empty arguments should be skipped * Or can be an array of values * @param mixed $args The values to join * - * @return array|string The joined string + * @return array|string The joined string * If an array of values is passed for the $delimiter or $ignoreEmpty arguments, then the returned result * will also be an array with matching dimensions */ - public static function TEXTJOIN(mixed $delimiter = '', mixed $ignoreEmpty = true, mixed ...$args): array|string + public static function TEXTJOIN($delimiter = '', $ignoreEmpty = true, mixed ...$args): array|string { if (is_array($delimiter) || is_array($ignoreEmpty)) { return self::evaluateArrayArgumentsSubset( @@ -127,6 +138,7 @@ class Concatenate $delimiter ??= ''; $ignoreEmpty ??= true; + /** @var mixed[] */ $aArgs = Functions::flattenArray($args); $returnValue = self::evaluateTextJoinArray($ignoreEmpty, $aArgs); @@ -138,6 +150,7 @@ class Concatenate return $returnValue; } + /** @param mixed[] $aArgs */ private static function evaluateTextJoinArray(bool $ignoreEmpty, array &$aArgs): ?string { foreach ($aArgs as $key => &$arg) { @@ -166,7 +179,7 @@ class Concatenate * @param mixed $repeatCount The number of times the string value should be repeated * Or can be an array of values * - * @return array|string The repeated string + * @return array|string The repeated string * If an array of values is passed for the $stringValue or $repeatCount arguments, then the returned result * will also be an array with matching dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Extract.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Extract.php index 1dfb724..6a05fa0 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Extract.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Extract.php @@ -20,7 +20,7 @@ class Extract * @param mixed $chars The number of characters to extract (as an integer) * Or can be an array of values * - * @return array|string The joined string + * @return array|string The joined string * If an array of values is passed for the $value or $chars arguments, then the returned result * will also be an array with matching dimensions */ @@ -50,7 +50,7 @@ class Extract * @param mixed $chars The number of characters to extract (as an integer) * Or can be an array of values * - * @return array|string The joined string + * @return array|string The joined string * If an array of values is passed for the $value, $start or $chars arguments, then the returned result * will also be an array with matching dimensions */ @@ -79,7 +79,7 @@ class Extract * @param mixed $chars The number of characters to extract (as an integer) * Or can be an array of values * - * @return array|string The joined string + * @return array|string The joined string * If an array of values is passed for the $value or $chars arguments, then the returned result * will also be an array with matching dimensions */ @@ -104,7 +104,7 @@ class Extract * * @param mixed $text the text that you're searching * Or can be an array of values - * @param null|array|string $delimiter the text that marks the point before which you want to extract + * @param null|array|string $delimiter the text that marks the point before which you want to extract * Multiple delimiters can be passed as an array of string values * @param mixed $instance The instance of the delimiter after which you want to extract the text. * By default, this is the first instance (1). @@ -118,11 +118,11 @@ class Extract * 0 - Don't match the delimiter against the end of the text. * 1 - Match the delimiter against the end of the text. * Or can be an array of values - * @param mixed $ifNotFound value to return if no match is found + * @param array|bool|float|int|string $ifNotFound value to return if no match is found * The default is a #N/A Error * Or can be an array of values * - * @return array|string the string extracted from text before the delimiter; or the $ifNotFound value + * @return array|string the string extracted from text before the delimiter; or the $ifNotFound value * If an array of values is passed for any of the arguments, then the returned result * will also be an array with matching dimensions */ @@ -139,9 +139,9 @@ class Extract return $e->getMessage(); } - $instance = (int) $instance; - $matchMode = (int) $matchMode; - $matchEnd = (int) $matchEnd; + $instance = (int) StringHelper::convertToString($instance); + $matchMode = (int) StringHelper::convertToString($matchMode); + $matchEnd = (int) StringHelper::convertToString($matchEnd); $split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); if (is_string($split)) { @@ -168,7 +168,7 @@ class Extract * TEXTAFTER. * * @param mixed $text the text that you're searching - * @param null|array|string $delimiter the text that marks the point before which you want to extract + * @param null|array|string $delimiter the text that marks the point before which you want to extract * Multiple delimiters can be passed as an array of string values * @param mixed $instance The instance of the delimiter after which you want to extract the text. * By default, this is the first instance (1). @@ -182,11 +182,11 @@ class Extract * 0 - Don't match the delimiter against the end of the text. * 1 - Match the delimiter against the end of the text. * Or can be an array of values - * @param mixed $ifNotFound value to return if no match is found + * @param array|scalar $ifNotFound value to return if no match is found * The default is a #N/A Error * Or can be an array of values * - * @return array|string the string extracted from text before the delimiter; or the $ifNotFound value + * @return array|string the string extracted from text before the delimiter; or the $ifNotFound value * If an array of values is passed for any of the arguments, then the returned result * will also be an array with matching dimensions */ @@ -203,9 +203,9 @@ class Extract return $e->getMessage(); } - $instance = (int) $instance; - $matchMode = (int) $matchMode; - $matchEnd = (int) $matchEnd; + $instance = (int) StringHelper::convertToString($instance); + $matchMode = (int) StringHelper::convertToString($matchMode); + $matchEnd = (int) StringHelper::convertToString($matchEnd); $split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); if (is_string($split)) { @@ -228,13 +228,19 @@ class Extract return implode('', $split); } + /** + * @param null|array|string $delimiter + * @param array|scalar $ifNotFound + * + * @return array|string + */ private static function validateTextBeforeAfter(string $text, null|array|string $delimiter, int $instance, int $matchMode, int $matchEnd, mixed $ifNotFound): array|string { $flags = self::matchFlags($matchMode); $delimiter = self::buildDelimiter($delimiter); if (preg_match('/' . $delimiter . "/{$flags}", $text) === 0 && $matchEnd === 0) { - return $ifNotFound; + return is_array($ifNotFound) ? $ifNotFound : StringHelper::convertToString($ifNotFound); } $split = preg_split('/' . $delimiter . "/{$flags}", $text, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); @@ -256,21 +262,23 @@ class Extract } /** - * @param null|array|string $delimiter the text that marks the point before which you want to extract + * @param null|array|string $delimiter the text that marks the point before which you want to extract * Multiple delimiters can be passed as an array of string values */ private static function buildDelimiter($delimiter): string { if (is_array($delimiter)) { + /** @var array */ $delimiter = Functions::flattenArray($delimiter); $quotedDelimiters = array_map( - fn ($delimiter): string => preg_quote($delimiter ?? '', '/'), + fn (?string $delimiter): string => preg_quote($delimiter ?? '', '/'), $delimiter ); $delimiters = implode('|', $quotedDelimiters); return '(' . $delimiters . ')'; } + /** @var ?string $delimiter */ return '(' . preg_quote($delimiter ?? '', '/') . ')'; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Format.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Format.php index 7251417..23bf74f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Format.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Format.php @@ -34,7 +34,7 @@ class Format * If you omit decimals, it is assumed to be 2 * Or can be an array of values * - * @return array|string If an array of values is passed for either of the arguments, then the returned result + * @return array|string If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function DOLLAR(mixed $value = 0, mixed $decimals = 2) @@ -76,7 +76,7 @@ class Format * @param mixed $noCommas Boolean value indicating whether the value should have thousands separators or not * Or can be an array of values * - * @return array|string If an array of values is passed for either of the arguments, then the returned result + * @return array|string If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function FIXEDFORMAT(mixed $value, mixed $decimals = 2, mixed $noCommas = false): array|string @@ -116,7 +116,7 @@ class Format * @param mixed $format A string with the Format mask that should be used * Or can be an array of values * - * @return array|string If an array of values is passed for either of the arguments, then the returned result + * @return array|string If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function TEXTFORMAT(mixed $value, mixed $format): array|string @@ -176,7 +176,7 @@ class Format * @param mixed $value Value to check * Or can be an array of values * - * @return array|DateTimeInterface|float|int|string A string if arguments are invalid + * @return array|DateTimeInterface|float|int|string A string if arguments are invalid * If an array of values is passed for the argument, then the returned result * will also be an array with matching dimensions */ @@ -192,6 +192,7 @@ class Format return $e->getMessage(); } if (!is_numeric($value)) { + $value = StringHelper::convertToString($value); $numberValue = str_replace( StringHelper::getThousandsSeparator(), '', @@ -212,14 +213,14 @@ class Format if ($timeValue !== ExcelError::VALUE()) { Functions::setReturnDateType($dateSetting); - return $timeValue; + return $timeValue; //* @phpstan-ignore-line } } $dateValue = Functions::scalar(DateTimeExcel\DateValue::fromString($value)); if ($dateValue !== ExcelError::VALUE()) { Functions::setReturnDateType($dateSetting); - return $dateValue; + return $dateValue; //* @phpstan-ignore-line } Functions::setReturnDateType($dateSetting); @@ -235,7 +236,7 @@ class Format * @param mixed $value The value to format * Or can be an array of values * - * @return array|string If an array of values is passed for either of the arguments, then the returned result + * @return array|string If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function valueToText(mixed $value, mixed $format = false): array|string @@ -250,23 +251,23 @@ class Format $value = $value->getPlainText(); } if (is_string($value)) { - $value = ($format === true) ? Calculation::wrapResult($value) : $value; + $value = ($format === true) ? StringHelper::convertToString(Calculation::wrapResult($value)) : $value; $value = str_replace("\n", '', $value); } elseif (is_bool($value)) { $value = Calculation::getLocaleBoolean($value ? 'TRUE' : 'FALSE'); } - return (string) $value; + return StringHelper::convertToString($value); } private static function getDecimalSeparator(mixed $decimalSeparator): string { - return empty($decimalSeparator) ? StringHelper::getDecimalSeparator() : (string) $decimalSeparator; + return empty($decimalSeparator) ? StringHelper::getDecimalSeparator() : StringHelper::convertToString($decimalSeparator); } private static function getGroupSeparator(mixed $groupSeparator): string { - return empty($groupSeparator) ? StringHelper::getThousandsSeparator() : (string) $groupSeparator; + return empty($groupSeparator) ? StringHelper::getThousandsSeparator() : StringHelper::convertToString($groupSeparator); } /** @@ -278,6 +279,8 @@ class Format * Or can be an array of values * @param mixed $groupSeparator A string with the group/thousands separator to use, defaults to locale defined value * Or can be an array of values + * + * @return array|float|string */ public static function NUMBERVALUE(mixed $value = '', mixed $decimalSeparator = null, mixed $groupSeparator = null): array|string|float { @@ -293,7 +296,9 @@ class Format return $e->getMessage(); } - if (!is_numeric($value)) { + /** @var null|array|scalar $value */ + if (!is_array($value) && !is_numeric($value)) { + $value = StringHelper::convertToString($value); $decimalPositions = Preg::matchAllWithOffsets('/' . preg_quote($decimalSeparator, '/') . '/', $value, $matches); if ($decimalPositions > 1) { return ExcelError::VALUE(); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Helpers.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Helpers.php index 719de04..e6dad29 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Helpers.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Helpers.php @@ -7,6 +7,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Helpers { @@ -31,7 +32,7 @@ class Helpers throw new CalcExp($value); } - return (string) $value; + return StringHelper::convertToString($value); } public static function extractInt(mixed $value, int $minValue, int $gnumericNull = 0, bool $ooBoolOk = false): int @@ -87,6 +88,6 @@ class Helpers throw new CalcExp($value); } - return (int) $value; + return (int) StringHelper::convertToString($value); } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Replace.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Replace.php index 8f6f196..6931c93 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Replace.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Replace.php @@ -25,7 +25,7 @@ class Replace * @param mixed $newText String to replace in the defined position * Or can be an array of values * - * @return array|string If an array of values is passed for either of the arguments, then the returned result + * @return array|string If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function replace(mixed $oldText, mixed $start, mixed $chars, mixed $newText): array|string @@ -65,7 +65,7 @@ class Replace * @param mixed $instance Integer instance Number for the occurrence of frmText to change * Or can be an array of values * - * @return array|string If an array of values is passed for either of the arguments, then the returned result + * @return array|string If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function substitute(mixed $text = '', mixed $fromText = '', mixed $toText = '', mixed $instance = null): array|string @@ -111,6 +111,6 @@ class Replace --$instance; } - return Functions::scalar(self::REPLACE($text, ++$pos, StringHelper::countCharacters($fromText), $toText)); + return StringHelper::convertToString(Functions::scalar(self::REPLACE($text, ++$pos, StringHelper::countCharacters($fromText), $toText))); } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Search.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Search.php index 663d49f..0c4b977 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Search.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Search.php @@ -21,7 +21,7 @@ class Search * @param mixed $offset Integer offset within $haystack to start searching from * Or can be an array of values * - * @return array|int|string The offset where the first occurrence of needle was found in the haystack + * @return array|int|string The offset where the first occurrence of needle was found in the haystack * If an array of values is passed for the $value or $chars arguments, then the returned result * will also be an array with matching dimensions */ @@ -63,7 +63,7 @@ class Search * @param mixed $offset Integer offset within $haystack to start searching from * Or can be an array of values * - * @return array|int|string The offset where the first occurrence of needle was found in the haystack + * @return array|int|string The offset where the first occurrence of needle was found in the haystack * If an array of values is passed for the $value or $chars arguments, then the returned result * will also be an array with matching dimensions */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Text.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Text.php index 57117ca..a4cc14f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Text.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Text.php @@ -8,6 +8,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Text { @@ -19,7 +20,7 @@ class Text * @param mixed $value String Value * Or can be an array of values * - * @return array|int|string If an array of values is passed for the argument, then the returned result + * @return array|int|string If an array of values is passed for the argument, then the returned result * will also be an array with matching dimensions */ public static function length(mixed $value = ''): array|int|string @@ -47,7 +48,7 @@ class Text * @param mixed $value2 String Value * Or can be an array of values * - * @return array|bool|string If an array of values is passed for either of the arguments, then the returned result + * @return array|bool|string If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ public static function exact(mixed $value1, mixed $value2): array|bool|string @@ -72,7 +73,7 @@ class Text * @param mixed $testValue Value to check * Or can be an array of values * - * @return array|string If an array of values is passed for the argument, then the returned result + * @return array|string If an array of values is passed for the argument, then the returned result * will also be an array with matching dimensions */ public static function test(mixed $testValue = ''): array|string @@ -92,9 +93,9 @@ class Text * TEXTSPLIT. * * @param mixed $text the text that you're searching - * @param null|array|string $columnDelimiter The text that marks the point where to spill the text across columns. + * @param null|array|string $columnDelimiter The text that marks the point where to spill the text across columns. * Multiple delimiters can be passed as an array of string values - * @param null|array|string $rowDelimiter The text that marks the point where to spill the text down rows. + * @param null|array|string $rowDelimiter The text that marks the point where to spill the text down rows. * Multiple delimiters can be passed as an array of string values * @param bool $ignoreEmpty Specify FALSE to create an empty cell when two delimiters are consecutive. * true = create empty cells @@ -107,13 +108,13 @@ class Text * @param mixed $padding The value with which to pad the result. * The default is #N/A. * - * @return array|string the array built from the text, split by the row and column delimiters, or an error string + * @return array|string the array built from the text, split by the row and column delimiters, or an error string */ public static function split(mixed $text, $columnDelimiter = null, $rowDelimiter = null, bool $ignoreEmpty = false, bool $matchMode = true, mixed $padding = '#N/A'): array|string { $text = Functions::flattenSingleValue($text); if (ErrorValue::isError($text, true)) { - return $text; + return StringHelper::convertToString($text); } $flags = self::matchFlags($matchMode); @@ -122,7 +123,7 @@ class Text $delimiter = self::buildDelimiter($rowDelimiter); $rows = ($delimiter === '()') ? [$text] - : Preg::split("/{$delimiter}/{$flags}", $text); + : Preg::split("/{$delimiter}/{$flags}", StringHelper::convertToString($text)); } else { $rows = [$text]; } @@ -141,7 +142,7 @@ class Text function (&$row) use ($delimiter, $flags, $ignoreEmpty): void { $row = ($delimiter === '()') ? [$row] - : Preg::split("/{$delimiter}/{$flags}", $row); + : Preg::split("/{$delimiter}/{$flags}", StringHelper::convertToString($row)); if ($ignoreEmpty === true) { $row = array_values(array_filter( $row, @@ -161,16 +162,21 @@ class Text return self::applyPadding($rows, $padding); } + /** + * @param mixed[] $rows + * + * @return mixed[] + */ private static function applyPadding(array $rows, mixed $padding): array { $columnCount = array_reduce( $rows, - fn (int $counter, array $row): int => max($counter, count($row)), + fn (int $counter, array $row): int => max($counter, count($row)), //* @phpstan-ignore-line 0 ); return array_map( - fn (array $row): array => (count($row) < $columnCount) + fn (array $row): array => (count($row) < $columnCount) //* @phpstan-ignore-line ? array_merge($row, array_fill(0, $columnCount - count($row), $padding)) : $row, $rows @@ -178,7 +184,7 @@ class Text } /** - * @param null|array|string $delimiter the text that marks the point before which you want to split + * @param null|array|string $delimiter the text that marks the point before which you want to split * Multiple delimiters can be passed as an array of string values */ private static function buildDelimiter($delimiter): string @@ -186,8 +192,9 @@ class Text $valueSet = Functions::flattenArray($delimiter); if (is_array($delimiter) && count($valueSet) > 1) { + /** @var array $valueSet */ $quotedDelimiters = array_map( - fn ($delimiter): string => preg_quote($delimiter ?? '', '/'), + fn (?string $delimiter): string => preg_quote($delimiter ?? '', '/'), $valueSet ); $delimiters = implode('|', $quotedDelimiters); @@ -195,7 +202,7 @@ class Text return '(' . $delimiters . ')'; } - return '(' . preg_quote(Functions::flattenSingleValue($delimiter), '/') . ')'; + return '(' . preg_quote(StringHelper::convertToString(Functions::flattenSingleValue($delimiter)), '/') . ')'; } private static function matchFlags(bool $matchMode): string @@ -203,6 +210,7 @@ class Text return ($matchMode === true) ? 'miu' : 'mu'; } + /** @param mixed[][] $array */ public static function fromArray(array $array, int $format = 0): string { $result = []; @@ -226,7 +234,7 @@ class Text return Calculation::getLocaleBoolean($cellValue ? 'TRUE' : 'FALSE'); } - return (string) $cellValue; + return StringHelper::convertToString($cellValue); } private static function formatValueMode1(mixed $cellValue): string @@ -237,6 +245,6 @@ class Text return Calculation::getLocaleBoolean($cellValue ? 'TRUE' : 'FALSE'); } - return (string) $cellValue; + return StringHelper::convertToString($cellValue); } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Trim.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Trim.php index d83e14d..0a7bb25 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Trim.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Trim.php @@ -14,7 +14,7 @@ class Trim * @param mixed $stringValue String Value to check * Or can be an array of values * - * @return array|string If an array of values is passed as the argument, then the returned result will also be an array + * @return array|string If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function nonPrintable(mixed $stringValue = '') @@ -34,7 +34,7 @@ class Trim * @param mixed $stringValue String Value to check * Or can be an array of values * - * @return array|string If an array of values is passed as the argument, then the returned result will also be an array + * @return array|string If an array of values is passed as the argument, then the returned result will also be an array * with the same dimensions */ public static function spaces(mixed $stringValue = ''): array|string diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Token/Stack.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Token/Stack.php index 13c6e5b..3301333 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Token/Stack.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Token/Stack.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Token; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Engine\BranchPruner; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Stack { @@ -12,7 +13,7 @@ class Stack /** * The parser stack for formulae. * - * @var mixed[] + * @var array> */ private array $stack = []; @@ -43,18 +44,20 @@ class Stack $this->stack[$this->count++] = $stackItem; if ($type === 'Function') { - $localeFunction = Calculation::localeFunc($value); + $localeFunction = Calculation::localeFunc(StringHelper::convertToString($value)); if ($localeFunction != $value) { $this->stack[($this->count - 1)]['localeValue'] = $localeFunction; } } } + /** @param array $stackItem */ public function pushStackItem(array $stackItem): void { $this->stack[$this->count++] = $stackItem; } + /** @return array */ public function getStackItem(string $type, mixed $value, ?string $reference = null): array { $stackItem = [ @@ -86,6 +89,8 @@ class Stack /** * Pop the last entry from the stack. + * + * @return null|array */ public function pop(): ?array { @@ -98,6 +103,8 @@ class Stack /** * Return an entry from the stack without removing it. + * + * @return null|array */ public function last(int $n = 1): ?array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/AdvancedValueBinder.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/AdvancedValueBinder.php index ffdf160..1db0c0f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/AdvancedValueBinder.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/AdvancedValueBinder.php @@ -110,6 +110,7 @@ class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder return parent::bindValue($cell, $value); } + /** @param array{0: string, 1: ?string, 2: numeric-string, 3: numeric-string, 4: numeric-string} $matches */ protected function setImproperFraction(array $matches, Cell $cell): bool { // Convert value to number @@ -130,6 +131,7 @@ class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder return true; } + /** @param array{0: string, 1: ?string, 2: numeric-string, 3: numeric-string} $matches */ protected function setProperFraction(array $matches, Cell $cell): bool { // Convert value to number diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Cell.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Cell.php index 0311991..e9fbabb 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Cell.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Cell.php @@ -181,9 +181,7 @@ class Cell implements Stringable public function getValueString(): string { - $value = $this->value; - - return ($value === '' || is_scalar($value) || $value instanceof Stringable) ? "$value" : ''; + return StringHelper::convertToString($this->value, false); } /** @@ -204,9 +202,9 @@ class Cell implements Stringable protected static function updateIfCellIsTableHeader(?Worksheet $workSheet, self $cell, mixed $oldValue, mixed $newValue): void { - $oldValue = (is_scalar($oldValue) || $oldValue instanceof Stringable) ? ((string) $oldValue) : null; - $newValue = (is_scalar($newValue) || $newValue instanceof Stringable) ? ((string) $newValue) : null; - if (StringHelper::strToLower($oldValue ?? '') === StringHelper::strToLower($newValue ?? '') || $workSheet === null) { + $oldValue = StringHelper::convertToString($oldValue, false); + $newValue = StringHelper::convertToString($newValue, false); + if (StringHelper::strToLower($oldValue) === StringHelper::strToLower($newValue) || $workSheet === null) { return; } @@ -279,24 +277,26 @@ class Cell implements Stringable // no break case DataType::TYPE_INLINE: // Rich text - if ($value !== null && !is_scalar($value) && !($value instanceof Stringable)) { - throw new SpreadsheetException('Invalid unstringable value for datatype Inline/String/String2'); + $value2 = StringHelper::convertToString($value, true); + // Cells?->Worksheet?->Spreadsheet + $binder = $this->parent?->getParent()?->getParent()?->getValueBinder(); + $preserveCr = false; + if ($binder !== null && method_exists($binder, 'getPreserveCr')) { + /** @var bool */ + $preserveCr = $binder->getPreserveCr(); } - $this->value = DataType::checkString(($value instanceof RichText) ? $value : ((string) $value)); + $this->value = DataType::checkString(($value instanceof RichText) ? $value : $value2, $preserveCr); break; case DataType::TYPE_NUMERIC: - if (is_string($value) && !is_numeric($value)) { + if ($value !== null && !is_bool($value) && !is_numeric($value)) { throw new SpreadsheetException('Invalid numeric value for datatype Numeric'); } $this->value = 0 + $value; break; case DataType::TYPE_FORMULA: - if ($value !== null && !is_scalar($value) && !($value instanceof Stringable)) { - throw new SpreadsheetException('Invalid unstringable value for datatype Formula'); - } - $this->value = (string) $value; + $this->value = StringHelper::convertToString($value, true); break; case DataType::TYPE_BOOL: @@ -391,7 +391,7 @@ class Cell implements Stringable $value = array_shift($value); } - return ($value === '' || is_scalar($value) || $value instanceof Stringable) ? "$value" : ''; + return StringHelper::convertToString($value, false); } /** @@ -453,6 +453,7 @@ class Cell implements Stringable } $newColumn = $this->getColumn(); if (is_array($result)) { + $result = self::convertSpecialArray($result); $this->formulaAttributes['t'] = 'array'; $this->formulaAttributes['ref'] = $maxCoordinate = $coordinate; $newRow = $row = $this->getRow(); @@ -471,7 +472,8 @@ class Cell implements Stringable } } } - ++$newColumn; + /** @var string $newColumn */ + StringHelper::stringIncrement($newColumn); } ++$newRow; } else { @@ -483,7 +485,7 @@ class Cell implements Stringable } } } - ++$newColumn; + StringHelper::stringIncrement($newColumn); } if ($spill) { break; @@ -504,12 +506,12 @@ class Cell implements Stringable if (isset($matches[3])) { $minCol = $matches[1]; $minRow = (int) $matches[2]; - // https://github.com/phpstan/phpstan/issues/11602 - $maxCol = $matches[4]; // @phpstan-ignore-line - ++$maxCol; - $maxRow = (int) $matches[5]; // @phpstan-ignore-line + $maxCol = $matches[4]; + StringHelper::stringIncrement($maxCol); + $maxRow = (int) $matches[5]; for ($row = $minRow; $row <= $maxRow; ++$row) { - for ($col = $minCol; $col !== $maxCol; ++$col) { + for ($col = $minCol; $col !== $maxCol; StringHelper::stringIncrement($col)) { + /** @var string $col */ if ("$col$row" !== $coordinate) { $thisworksheet->getCell("$col$row")->setValue(null); } @@ -532,16 +534,18 @@ class Cell implements Stringable $newColumn = $column; foreach ($resultRow as $resultValue) { if ($row !== $newRow || $column !== $newColumn) { - $thisworksheet->getCell($newColumn . $newRow)->setValue($resultValue); + $thisworksheet + ->getCell($newColumn . $newRow) + ->setValue($resultValue); } - ++$newColumn; + StringHelper::stringIncrement($newColumn); } ++$newRow; } else { if ($row !== $newRow || $column !== $newColumn) { $thisworksheet->getCell($newColumn . $newRow)->setValue($resultRow); } - ++$newColumn; + StringHelper::stringIncrement($newColumn); } } $thisworksheet->getCell($column . $row); @@ -578,6 +582,36 @@ class Cell implements Stringable return $this->convertDateTimeInt($this->value); } + /** + * Convert array like the following (preserve values, lose indexes): + * [ + * rowNumber1 => [colLetter1 => value, colLetter2 => value ...], + * rowNumber2 => [colLetter1 => value, colLetter2 => value ...], + * ... + * ]. + * + * @param mixed[] $array + * + * @return mixed[] + */ + private static function convertSpecialArray(array $array): array + { + $newArray = []; + foreach ($array as $rowIndex => $row) { + if (!is_int($rowIndex) || $rowIndex <= 0 || !is_array($row)) { + return $array; + } + $keys = array_keys($row); + $key0 = $keys[0] ?? ''; + if (!is_string($key0)) { + return $array; + } + $newArray[] = array_values($row); + } + + return $newArray; + } + /** * Set old calculated value (cached). * @@ -942,9 +976,7 @@ class Cell implements Stringable /** * Set the formula attributes. * - * @param $attributes null|array - * - * @return $this + * @param null|array $attributes */ public function setFormulaAttributes(?array $attributes): self { @@ -970,7 +1002,7 @@ class Cell implements Stringable { $retVal = $this->value; - return ($retVal === null || is_scalar($retVal) || $retVal instanceof Stringable) ? ((string) $retVal) : ''; + return StringHelper::convertToString($retVal, false); } public function getIgnoredErrors(): IgnoredErrors diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/CellAddress.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/CellAddress.php index ab6258e..a4a518e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/CellAddress.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/CellAddress.php @@ -48,6 +48,7 @@ class CellAddress implements Stringable return new self(Coordinate::stringFromColumnIndex($columnId) . $rowId, $worksheet); } + /** @param array $array */ public static function fromColumnRowArray(array $array, ?Worksheet $worksheet = null): self { [$columnId, $rowId] = $array; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php index 7d84027..227f2c1 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Exception; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Worksheet\Validations; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; @@ -135,11 +136,12 @@ abstract class Coordinate } /** - * Split range into coordinate strings. + * Split range into coordinate strings, using comma for union + * and ignoring intersection (space). * * @param string $range e.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4' * - * @return array Array containing one or more arrays containing one or two coordinate strings + * @return array> Array containing one or more arrays containing one or two coordinate strings * e.g. ['B4','D9'] or [['B4','D9'], ['H2','O11']] * or ['B4'] */ @@ -159,23 +161,48 @@ abstract class Coordinate return $outArray; } + /** + * Split range into coordinate strings, resolving unions and intersections. + * + * @param string $range e.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4' + * @param bool $unionIsComma true=comma is union, space is intersection + * false=space is union, comma is intersection + * + * @return array> Array containing one or more arrays containing one or two coordinate strings + * e.g. ['B4','D9'] or [['B4','D9'], ['H2','O11']] + * or ['B4'] + */ + public static function allRanges(string $range, bool $unionIsComma = true): array + { + if (!$unionIsComma) { + $range = str_replace([',', ' ', "\0"], ["\0", ',', ' '], $range); + } + + return self::splitRange( + self::resolveUnionAndIntersection($range) + ); + } + /** * Build range from coordinate strings. * - * @param array $range Array containing one or more arrays containing one or two coordinate strings + * @param mixed[] $range Array containing one or more arrays containing one or two coordinate strings * * @return string String representation of $pRange */ public static function buildRange(array $range): string { // Verify range - if (empty($range) || !is_array($range[0])) { + if (empty($range)) { throw new Exception('Range does not contain any information'); } // Build range $counter = count($range); for ($i = 0; $i < $counter; ++$i) { + if (!is_array($range[$i])) { + throw new Exception('Each array entry must be an array'); + } $range[$i] = implode(':', $range[$i]); } @@ -187,7 +214,7 @@ abstract class Coordinate * * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3) * - * @return array Range coordinates [Start Cell, End Cell] + * @return array{array{int, int}, array{int, int}} Range coordinates [Start Cell, End Cell] * where Start Cell and End Cell are arrays (Column Number, Row Number) */ public static function rangeBoundaries(string $range): array @@ -224,6 +251,8 @@ abstract class Coordinate // Translate column into index $rangeStart[0] = self::columnIndexFromString($rangeStart[0]); $rangeEnd[0] = self::columnIndexFromString($rangeEnd[0]); + $rangeStart[1] = (int) $rangeStart[1]; + $rangeEnd[1] = (int) $rangeEnd[1]; return [$rangeStart, $rangeEnd]; } @@ -233,7 +262,7 @@ abstract class Coordinate * * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3) * - * @return array Range dimension (width, height) + * @return array{int, int} Range dimension (width, height) */ public static function rangeDimension(string $range): array { @@ -248,7 +277,7 @@ abstract class Coordinate * * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3) * - * @return array Range coordinates [Start Cell, End Cell] + * @return array{array{string, int}, array{string, int}} Range coordinates [Start Cell, End Cell] * where Start Cell and End Cell are arrays [Column ID, Row Number] */ public static function getRangeBoundaries(string $range): array @@ -267,7 +296,7 @@ abstract class Coordinate * * @param string $reference Coordinate or Range (e.g. A1:A1, B2, B:C, 2:3) * - * @return array reference data + * @return array{type: string, firstCoordinate?: string, secondCoordinate?: string, coordinate?: string, worksheet?: string, localReference?: string} reference data */ private static function validateReferenceAndGetData($reference): array { @@ -331,7 +360,13 @@ abstract class Coordinate } } + if (!isset($rangeData['localReference'])) { + return false; + } $boundaries = self::rangeBoundaries($rangeData['localReference']); + if (!isset($coordinateData['localReference'])) { + return false; + } $coordinates = self::indexesFromString($coordinateData['localReference']); $columnIsInside = $boundaries[0][0] <= $coordinates[0] && $coordinates[0] <= $boundaries[1][0]; @@ -358,6 +393,7 @@ abstract class Coordinate // Using a lookup cache adds a slight memory overhead, but boosts speed // caching using a static within the method is faster than a class static, // though it's additional memory overhead + /** @var int[] */ static $indexCache = []; $columnAddress = $columnAddress ?? ''; @@ -367,6 +403,7 @@ abstract class Coordinate // It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array // rather than use ord() and make it case insensitive to get rid of the strtoupper() as well. // Because it's a static, there's no significant memory overhead either. + /** @var array */ static $columnLookup = [ 'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10, 'K' => 11, 'L' => 12, 'M' => 13, 'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18, 'S' => 19, @@ -402,6 +439,8 @@ abstract class Coordinate ); } + private const LOOKUP_CACHE = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + /** * String from column index. * @@ -409,8 +448,8 @@ abstract class Coordinate */ public static function stringFromColumnIndex(int|string $columnIndex): string { + /** @var string[] */ static $indexCache = []; - static $lookupCache = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ'; if (!isset($indexCache[$columnIndex])) { $indexValue = $columnIndex; @@ -418,7 +457,7 @@ abstract class Coordinate do { $characterValue = ($indexValue % 26) ?: 26; $indexValue = ($indexValue - $characterValue) / 26; - $base26 = $lookupCache[$characterValue] . $base26; + $base26 = self::LOOKUP_CACHE[$characterValue] . $base26; } while ($indexValue > 0); $indexCache[$columnIndex] = $base26; } @@ -431,7 +470,7 @@ abstract class Coordinate * * @param string $cellRange Range: e.g. 'A1' or 'A1:C10' or 'A1:E10,A20:E25' or 'A1:E5 C3:G7' or 'A1:C1,A3:C3 B1:C3' * - * @return array Array containing single cell references + * @return string[] Array containing single cell references */ public static function extractAllCellReferencesInRange(string $cellRange): array { @@ -452,23 +491,35 @@ abstract class Coordinate $cells = []; foreach ($ranges as $range) { + /** @var string $range */ $cells[] = self::getReferencesForCellBlock($range); } + /** @var mixed[] */ $cells = self::processRangeSetOperators($operators, $cells); if (empty($cells)) { return []; } - $cellList = array_merge(...$cells); + /** @var string[] */ + $cellList = array_merge(...$cells); //* @phpstan-ignore-line + // Unsure how to satisfy phpstan in line above - return array_map( - fn ($cellAddress) => ($worksheet !== '') ? "{$quoted}{$worksheet}{$quoted}!{$cellAddress}" : $cellAddress, + $retVal = array_map( + fn (string $cellAddress) => ($worksheet !== '') ? "{$quoted}{$worksheet}{$quoted}!{$cellAddress}" : $cellAddress, self::sortCellReferenceArray($cellList) ); + + return $retVal; } + /** + * @param mixed[] $operators + * @param mixed[][] $cells + * + * @return mixed[] + */ private static function processRangeSetOperators(array $operators, array $cells): array { $operatorCount = count($operators); @@ -489,6 +540,11 @@ abstract class Coordinate return $cells; } + /** + * @param string[] $cellList + * + * @return string[] + */ private static function sortCellReferenceArray(array $cellList): array { // Sort the result by column and row @@ -497,6 +553,7 @@ abstract class Coordinate $column = ''; $row = 0; sscanf($coordinate, '%[A-Z]%d', $column, $row); + /** @var int $row */ $key = (--$row * 16384) + self::columnIndexFromString((string) $column); $sortKeys[$key] = $coordinate; } @@ -548,7 +605,7 @@ abstract class Coordinate * * @param string $cellBlock A cell range e.g. A4:B5 * - * @return array All individual cells in that range + * @return string[] All individual cells in that range */ private static function getReferencesForCellBlock(string $cellBlock): array { @@ -585,6 +642,8 @@ abstract class Coordinate // Loop cells while ($currentColumnIndex < $endColumnIndex) { + /** @var int $currentRow */ + /** @var int $endRow */ while ($currentRow <= $endRow) { $returnValue[] = self::stringFromColumnIndex($currentColumnIndex) . $currentRow; ++$currentRow; @@ -610,9 +669,9 @@ abstract class Coordinate * * [ 'A1:A3' => 'x', 'A4' => 'y' ] * - * @param array $coordinateCollection associative array mapping coordinates to values + * @param array $coordinateCollection associative array mapping coordinates to values * - * @return array associative array mapping coordinate ranges to valuea + * @return array associative array mapping coordinate ranges to valuea */ public static function mergeRangesInCollection(array $coordinateCollection): array { @@ -628,7 +687,7 @@ abstract class Coordinate [$column, $row] = self::coordinateFromString($coord); $row = (int) (ltrim($row, '$')); - $hashCode = $column . '-' . ((is_object($value) && method_exists($value, 'getHashCode')) ? $value->getHashCode() : $value); + $hashCode = $column . '-' . StringHelper::convertToString((is_object($value) && method_exists($value, 'getHashCode')) ? $value->getHashCode() : $value); if (!isset($hashedValues[$hashCode])) { $hashedValues[$hashCode] = (object) [ @@ -687,7 +746,7 @@ abstract class Coordinate * Get the individual cell blocks from a range string, removing any $ characters. * then splitting by operators and returning an array with ranges and operators. * - * @return array[] + * @return mixed[][] */ private static function getCellBlocksFromRangeString(string $rangeString): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DataType.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DataType.php index a213725..774a57b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DataType.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DataType.php @@ -4,7 +4,6 @@ namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; -use Stringable; class DataType { @@ -54,7 +53,7 @@ class DataType * * @return RichText|string Sanitized value */ - public static function checkString(null|RichText|string $textValue): RichText|string + public static function checkString(null|RichText|string $textValue, bool $preserveCr = false): RichText|string { if ($textValue instanceof RichText) { // TODO: Sanitize Rich-Text string (max. character count is 32,767) @@ -65,7 +64,9 @@ class DataType $textValue = StringHelper::substring((string) $textValue, 0, self::MAX_STRING_LENGTH); // we require that newline is represented as "\n" in core, not as "\r\n" or "\r" - $textValue = str_replace(["\r\n", "\r"], "\n", $textValue); + if (!$preserveCr) { + $textValue = str_replace(["\r\n", "\r"], "\n", $textValue); + } return $textValue; } @@ -79,10 +80,11 @@ class DataType */ public static function checkErrorCode(mixed $value): string { - $value = (is_scalar($value) || $value instanceof Stringable) ? ((string) $value) : '#NULL!'; + $default = '#NULL!'; + $value = ($value === null) ? $default : StringHelper::convertToString($value, false, $default); if (!isset(self::$errorCodes[$value])) { - $value = '#NULL!'; + $value = $default; } return $value; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DataValidator.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DataValidator.php index dcee049..5a4c774 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DataValidator.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DataValidator.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Exception; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; /** * Validate a cell value according to its validation rules. @@ -60,8 +61,9 @@ class DataValidator $calculation = Calculation::getInstance($cell->getWorksheet()->getParent()); try { + $formula2 = StringHelper::convertToString($formula); $result = $calculation - ->calculateFormula("=$formula", $cell->getCoordinate(), $cell); + ->calculateFormula("=$formula2", $cell->getCoordinate(), $cell); while (is_array($result)) { $result = array_pop($result); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DefaultValueBinder.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DefaultValueBinder.php index 10c5c93..42a45a9 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DefaultValueBinder.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/DefaultValueBinder.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Cell; +use Composer\Pcre\Preg; use DateTimeInterface; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException; @@ -12,6 +13,9 @@ use Stringable; class DefaultValueBinder implements IValueBinder { + // 123 456 789 012 345 + private const FIFTEEN_NINES = 999_999_999_999_999; + /** * Bind value to a cell. * @@ -49,6 +53,9 @@ class DefaultValueBinder implements IValueBinder if ($value === null) { return DataType::TYPE_NULL; } + if (is_int($value) && abs($value) > self::FIFTEEN_NINES) { + return DataType::TYPE_STRING; + } if (is_float($value) || is_int($value)) { return DataType::TYPE_NUMERIC; } @@ -89,13 +96,18 @@ class DefaultValueBinder implements IValueBinder return DataType::TYPE_FORMULA; } - if (preg_match('/^[\+\-]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $value)) { + if (Preg::isMatch('/^[\+\-]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $value)) { $tValue = ltrim($value, '+-'); if (strlen($tValue) > 1 && $tValue[0] === '0' && $tValue[1] !== '.') { return DataType::TYPE_STRING; - } elseif ((!str_contains($value, '.')) && ($value > PHP_INT_MAX)) { - return DataType::TYPE_STRING; - } elseif (!is_numeric($value)) { + } + if (!Preg::isMatch('/[eE.]/', $value)) { + $aValue = abs((float) $value); + if ($aValue > self::FIFTEEN_NINES) { + return DataType::TYPE_STRING; + } + } + if (!is_numeric($value)) { return DataType::TYPE_STRING; } @@ -108,4 +120,18 @@ class DefaultValueBinder implements IValueBinder return DataType::TYPE_STRING; } + + protected bool $preserveCr = false; + + public function getPreserveCr(): bool + { + return $this->preserveCr; + } + + public function setPreserveCr(bool $preserveCr): self + { + $this->preserveCr = $preserveCr; + + return $this; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Hyperlink.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Hyperlink.php index 3117a7d..5f1c521 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Hyperlink.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Hyperlink.php @@ -68,11 +68,11 @@ class Hyperlink } /** - * Is this hyperlink internal? (to another worksheet). + * Is this hyperlink internal? (to another worksheet or a cell in this worksheet). */ public function isInternal(): bool { - return str_contains($this->url, 'sheet://'); + return str_starts_with($this->url, 'sheet://') || str_starts_with($this->url, '#'); } public function getTypeHyperlink(): string diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/IgnoredErrors.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/IgnoredErrors.php index a7c4d19..0d88fe3 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/IgnoredErrors.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/IgnoredErrors.php @@ -8,6 +8,8 @@ class IgnoredErrors private bool $formula = false; + private bool $formulaRange = false; + private bool $twoDigitTextYear = false; private bool $evalError = false; @@ -36,6 +38,18 @@ class IgnoredErrors return $this->formula; } + public function setFormulaRange(bool $value): self + { + $this->formulaRange = $value; + + return $this; + } + + public function getFormulaRange(): bool + { + return $this->formulaRange; + } + public function setTwoDigitTextYear(bool $value): self { $this->twoDigitTextYear = $value; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/RowRange.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/RowRange.php index 4ed232a..1d35acc 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/RowRange.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/RowRange.php @@ -27,6 +27,7 @@ class RowRange implements AddressRange, Stringable $this->worksheet = null; } + /** @param array{int, int} $array */ public static function fromArray(array $array, ?Worksheet $worksheet = null): self { [$from, $to] = $array; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Chart.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Chart.php index 6bcae28..e750edc 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Chart.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Chart.php @@ -128,7 +128,7 @@ class Chart * Create a new Chart. * majorGridlines and minorGridlines are deprecated, moved to Axis. */ - public function __construct(string $name, ?Title $title = null, ?Legend $legend = null, ?PlotArea $plotArea = null, bool $plotVisibleOnly = true, string $displayBlanksAs = DataSeries::EMPTY_AS_GAP, ?Title $xAxisLabel = null, ?Title $yAxisLabel = null, ?Axis $xAxis = null, ?Axis $yAxis = null, ?GridLines $majorGridlines = null, ?GridLines $minorGridlines = null) + public function __construct(string $name, ?Title $title = null, ?Legend $legend = null, ?PlotArea $plotArea = null, bool $plotVisibleOnly = true, string $displayBlanksAs = DataSeries::DEFAULT_EMPTY_AS, ?Title $xAxisLabel = null, ?Title $yAxisLabel = null, ?Axis $xAxis = null, ?Axis $yAxis = null, ?GridLines $majorGridlines = null, ?GridLines $minorGridlines = null) { $this->name = $name; $this->title = $title; @@ -137,7 +137,7 @@ class Chart $this->yAxisLabel = $yAxisLabel; $this->plotArea = $plotArea; $this->plotVisibleOnly = $plotVisibleOnly; - $this->displayBlanksAs = $displayBlanksAs; + $this->setDisplayBlanksAs($displayBlanksAs); $this->xAxis = $xAxis ?? new Axis(); $this->yAxis = $yAxis ?? new Axis(); if ($majorGridlines !== null) { @@ -318,7 +318,8 @@ class Chart */ public function setDisplayBlanksAs(string $displayBlanksAs): static { - $this->displayBlanksAs = $displayBlanksAs; + $displayBlanksAs = strtolower($displayBlanksAs); + $this->displayBlanksAs = in_array($displayBlanksAs, DataSeries::VALID_EMPTY_AS, true) ? $displayBlanksAs : DataSeries::DEFAULT_EMPTY_AS; return $this; } @@ -489,7 +490,7 @@ class Chart /** * Get the bottom right position of the chart. * - * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell + * @return array{cell: string, xOffset: int, yOffset:int} an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell */ public function getBottomRightPosition(): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/ChartColor.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/ChartColor.php index d6306de..6ac4b5a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/ChartColor.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/ChartColor.php @@ -22,7 +22,7 @@ class ChartColor private ?int $brightness = null; /** - * @param string|string[] $value + * @param array{value: ?string, alpha: null|int|string, brightness?: null|int|string, type: ?string}|string $value */ public function __construct($value = '', ?int $alpha = null, ?string $type = null, ?int $brightness = null) { @@ -114,6 +114,7 @@ class ChartColor return $this; } + /** @param array{value: ?string, alpha: null|int|string, brightness?: null|int|string, type: ?string} $color */ public function setColorPropertiesArray(array $color): self { return $this->setColorProperties( diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php index dd39200..06f1c3c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php @@ -43,6 +43,8 @@ class DataSeries const EMPTY_AS_GAP = 'gap'; const EMPTY_AS_ZERO = 'zero'; const EMPTY_AS_SPAN = 'span'; + const DEFAULT_EMPTY_AS = self::EMPTY_AS_GAP; + const VALID_EMPTY_AS = [self::EMPTY_AS_GAP, self::EMPTY_AS_ZERO, self::EMPTY_AS_SPAN]; /** * Series Plot Type. diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeriesValues.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeriesValues.php index 6da4bc4..f378932 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeriesValues.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeriesValues.php @@ -53,6 +53,8 @@ class DataSeriesValues extends Properties /** * Data Values. + * + * @var null|mixed[] */ private ?array $dataValues; @@ -75,6 +77,7 @@ class DataSeriesValues extends Properties /** * Create a new DataSeriesValues object. * + * @param null|mixed[] $dataValues * @param null|ChartColor|ChartColor[]|string|string[] $fillColor */ public function __construct( @@ -330,16 +333,12 @@ class DataSeriesValues extends Properties * Method for validating hex color. * * @param string $color value for color - * - * @return bool true if validation was successful */ - private function validateColor(string $color): bool + private function validateColor(string $color): void { if (!preg_match('/^[a-f0-9]{6}$/i', $color)) { throw new Exception(sprintf('Invalid hex color for chart series (color: "%s")', $color)); } - - return true; } /** @@ -347,7 +346,10 @@ class DataSeriesValues extends Properties */ public function getLineWidth(): null|float|int { - return $this->lineStyleProperties['width']; + /** @var null|float|int */ + $temp = $this->lineStyleProperties['width']; + + return $temp; } /** @@ -381,6 +383,7 @@ class DataSeriesValues extends Properties { $levelCount = 0; foreach (($this->dataValues ?? []) as $dataValueSet) { + /** @var mixed[] $dataValueSet */ $levelCount = max($levelCount, count($dataValueSet)); } @@ -389,6 +392,8 @@ class DataSeriesValues extends Properties /** * Get Series Data Values. + * + * @return null|mixed[] */ public function getDataValues(): ?array { @@ -416,6 +421,8 @@ class DataSeriesValues extends Properties /** * Set Series Data Values. * + * @param mixed[] $dataValues + * * @return $this */ public function setDataValues(array $dataValues): static @@ -451,8 +458,9 @@ class DataSeriesValues extends Properties if (($dimensions[0] == 1) || ($dimensions[1] == 1)) { $this->dataValues = Functions::flattenArray($newDataValues); } else { - /** @var array */ + /** @var array */ $newDataValuesx = $newDataValues; + /** @var mixed[][] $newArray */ $newArray = array_values(array_shift($newDataValuesx) ?? []); foreach ($newArray as $i => $newDataSet) { $newArray[$i] = [$newDataSet]; @@ -467,7 +475,7 @@ class DataSeriesValues extends Properties $this->dataValues = $newArray; } } - $this->pointCount = count($this->dataValues); + $this->pointCount = count($this->dataValues ?? []); } } @@ -532,6 +540,7 @@ class DataSeriesValues extends Properties return $this; } + /** @param TrendLine[] $trendLines */ public function setTrendLines(array $trendLines): self { $this->trendLines = $trendLines; @@ -539,6 +548,7 @@ class DataSeriesValues extends Properties return $this; } + /** @return TrendLine[] */ public function getTrendLines(): array { return $this->trendLines; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Layout.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Layout.php index 5dc2991..95e113d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Layout.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Layout.php @@ -101,9 +101,12 @@ class Layout /** * Create a new Layout. + * + * @param array $layout */ public function __construct(array $layout = []) { + /** @var array{layoutTarget?: string, xMode?: string, yMode?: string, x?: float, y?: float, w?:float, h?:float, dLblPos?: string, labelFont?: ?mixed, labelFontColor?: ?mixed, labelEffects?: ?mixed, numFmtCode?: string} $layout */ if (isset($layout['layoutTarget'])) { $this->layoutTarget = $layout['layoutTarget']; } @@ -155,6 +158,7 @@ class Layout } } + /** @param mixed[] $layout */ private function initBoolean(array $layout, string $name): void { if (isset($layout[$name])) { @@ -162,6 +166,7 @@ class Layout } } + /** @param mixed[] $layout */ private function initColor(array $layout, string $name): void { if (isset($layout[$name]) && $layout[$name] instanceof ChartColor) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/PlotArea.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/PlotArea.php index 228afad..e5e3907 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/PlotArea.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/PlotArea.php @@ -17,7 +17,7 @@ class PlotArea * First is position in %. * Second is ChartColor. * - * @var array[] + * @var array */ private array $gradientFillStops = []; @@ -126,6 +126,7 @@ class PlotArea return $this->noFill; } + /** @param array $gradientFillStops */ public function setGradientFillProperties(array $gradientFillStops, ?float $gradientFillAngle): self { $this->gradientFillStops = $gradientFillStops; @@ -144,6 +145,8 @@ class PlotArea /** * Get gradientFillStops. + * + * @return array */ public function getGradientFillStops(): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Properties.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Properties.php index 3e02a96..700ccd1 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Properties.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Properties.php @@ -109,10 +109,12 @@ abstract class Properties protected ChartColor $glowColor; + /** @var array{size: ?float} */ protected array $softEdges = [ 'size' => null, ]; + /** @var mixed[] */ protected array $shadowProperties = self::PRESETS_OPTIONS[0]; protected ChartColor $shadowColor; @@ -177,6 +179,7 @@ abstract class Properties return ((float) $value) / self::PERCENTAGE_MULTIPLIER; } + /** @return array{type: ?string, value: ?string, alpha: ?int} */ protected function setColorProperties(?string $color, null|float|int|string $alpha, ?string $colorType): array { return [ @@ -394,6 +397,7 @@ abstract class Properties ], ]; + /** @return mixed[] */ protected function getShadowPresetsMap(int $presetsOption): array { return self::PRESETS_OPTIONS[$presetsOption] ?? self::PRESETS_OPTIONS[0]; @@ -401,6 +405,9 @@ abstract class Properties /** * Get value of array element. + * + * @param mixed[] $properties + * @param array|int|string $elements */ protected function getArrayElementsValue(array $properties, array|int|string $elements): mixed { @@ -410,7 +417,7 @@ abstract class Properties } foreach ($elements as $keys) { - $reference = &$reference[$keys]; + $reference = &$reference[$keys]; //* @phpstan-ignore-line } return $reference; @@ -435,6 +442,10 @@ abstract class Properties /** * Get Glow Property. + * + * @param mixed[]|string $property + * + * @return null|array|float|int|string */ public function getGlowProperty(array|string $property): null|array|float|int|string { @@ -448,7 +459,9 @@ abstract class Properties 'alpha' => $this->glowColor->getColorProperty('alpha'), ]; } elseif (is_array($property) && count($property) >= 2 && $property[0] === 'color') { - $retVal = $this->glowColor->getColorProperty($property[1]); + /** @var string */ + $temp = $property[1]; + $retVal = $this->glowColor->getColorProperty($temp); } return $retVal; @@ -506,11 +519,14 @@ abstract class Properties return $this->softEdges['size']; } + /** @param null|array{value?: ?string, alpha?: null|int|string, brightness?: null|int|string, type?: ?string}|float|string $value */ public function setShadowProperty(string $propertyName, mixed $value): self { $this->activateObject(); if ($propertyName === 'color' && is_array($value)) { - $this->shadowColor->setColorPropertiesArray($value); + /** @var array{value: ?string, alpha: null|int|string, brightness?: null|int|string, type: ?string} */ + $valuex = $value; + $this->shadowColor->setColorPropertiesArray($valuex); } else { $this->shadowProperties[$propertyName] = $value; } @@ -562,6 +578,9 @@ abstract class Properties /** * Set Shadow Properties Values. * + * @param mixed[] $propertiesMap + * @param null|mixed[] $reference + * * @return $this */ protected function setShadowPropertiesMapValues(array $propertiesMap, ?array &$reference = null) @@ -570,8 +589,13 @@ abstract class Properties foreach ($propertiesMap as $property_key => $property_val) { if (is_array($property_val)) { if (in_array($property_key, self::SHADOW_ARRAY_KEYS, true)) { - $reference = &$this->shadowProperties[$property_key]; - $this->setShadowPropertiesMapValues($property_val, $reference); + /** @var null|array */ + $temp = &$this->shadowProperties[$property_key]; + $reference = &$temp; + $this->setShadowPropertiesMapValues( + $property_val, + $reference + ); } } else { if ($base_reference === null) { @@ -636,6 +660,8 @@ abstract class Properties * Get Shadow Property. * * @param string|string[] $elements + * + * @return null|mixed[]|string */ public function getShadowProperty($elements): array|string|null { @@ -658,6 +684,7 @@ abstract class Properties return $retVal; } + /** @return mixed[] */ public function getShadowArray(): array { $array = $this->shadowProperties; @@ -670,6 +697,7 @@ abstract class Properties protected ChartColor $lineColor; + /** @var array{width: null|float|int|string, compound: ?string, dash: ?string, cap: ?string, join: ?string, arrow: array{head: array{type: ?string, size: null|int|string, w: ?string, len: ?string}, end: array{type: ?string, size: null|int|string, w: ?string, len: ?string}}} */ protected array $lineStyleProperties = [ 'width' => null, //'9525', 'compound' => '', //self::LINE_STYLE_COMPOUND_SIMPLE, @@ -794,13 +822,16 @@ abstract class Properties } } + /** @return mixed[] */ public function getLineStyleArray(): array { return $this->lineStyleProperties; } + /** @param mixed[] $lineStyleProperties */ public function setLineStyleArray(array $lineStyleProperties = []): self { + /** @var array{width?: ?string, compound?: string, dash?: string, cap?: string, join?: string, arrow?: array{head?: array{type?: string, size?: int, w?: string, len?: string}, end?: array{type?: string, size?: int, w?: string, len?: string}}} $lineStyleProperties */ $this->activateObject(); $this->lineStyleProperties['width'] = $lineStyleProperties['width'] ?? null; $this->lineStyleProperties['compound'] = $lineStyleProperties['compound'] ?? ''; @@ -822,13 +853,15 @@ abstract class Properties public function setLineStyleProperty(string $propertyName, mixed $value): self { $this->activateObject(); - $this->lineStyleProperties[$propertyName] = $value; + $this->lineStyleProperties[$propertyName] = $value; //* @phpstan-ignore-line return $this; } /** * Get Line Style Property. + * + * @param array|string $elements */ public function getLineStyleProperty(array|string $elements): ?string { @@ -869,7 +902,7 @@ abstract class Properties */ public function getLineStyleArrowParameters(string $arrowSelector, string $propertySelector): string { - return $this->getLineStyleArrowSize($this->lineStyleProperties['arrow'][$arrowSelector]['size'], $propertySelector); + return $this->getLineStyleArrowSize((int) $this->lineStyleProperties['arrow'][$arrowSelector]['size'], $propertySelector); } /** diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Title.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Title.php index 29ba17b..adbb731 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Title.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Title.php @@ -36,6 +36,8 @@ class Title /** * Create a new Title. + * + * @param array|RichText|string $caption */ public function __construct(array|RichText|string $caption = '', ?Layout $layout = null, bool $overlay = false) { @@ -46,6 +48,8 @@ class Title /** * Get caption. + * + * @return array|RichText|string */ public function getCaption(): array|RichText|string { @@ -84,6 +88,8 @@ class Title /** * Set caption. * + * @param array|RichText|string $caption + * * @return $this */ public function setCaption(array|RichText|string $caption): static @@ -159,11 +165,11 @@ class Title $this->layout = ($this->layout === null) ? null : clone $this->layout; $this->font = ($this->font === null) ? null : clone $this->font; if (is_array($this->caption)) { - $captions = $this->caption; - $this->caption = []; - foreach ($captions as $caption) { - $this->caption[] = is_object($caption) ? (clone $caption) : $caption; + $captions = []; + foreach ($this->caption as $caption) { + $captions[] = is_object($caption) ? (clone $caption) : $caption; } + $this->caption = $captions; } else { $this->caption = is_object($this->caption) ? (clone $this->caption) : $this->caption; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php index 76bbc32..0661867 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php @@ -43,6 +43,25 @@ class Cells */ private array $index = []; + /** + * Flag to avoid sorting the index every time. + */ + private bool $indexSorted = false; + + /** + * Index keys cache to avoid recalculating on large arrays. + * + * @var null|string[] + */ + private ?array $indexKeysCache = null; + + /** + * Index values cache to avoid recalculating on large arrays. + * + * @var null|int[] + */ + private ?array $indexValuesCache = null; + /** * Prefix used to uniquely identify cache data for this worksheet. */ @@ -112,6 +131,10 @@ class Cells unset($this->index[$cellCoordinate]); + // Clear index caches + $this->indexKeysCache = null; + $this->indexValuesCache = null; + // Delete the entry from cache $this->cache->delete($this->cachePrefix . $cellCoordinate); } @@ -123,7 +146,12 @@ class Cells */ public function getCoordinates(): array { - return array_keys($this->index); + // Build or rebuild index keys cache + if ($this->indexKeysCache === null) { + $this->indexKeysCache = array_keys($this->index); + } + + return $this->indexKeysCache; } /** @@ -133,9 +161,21 @@ class Cells */ public function getSortedCoordinates(): array { - asort($this->index); + // Sort only when required + if (!$this->indexSorted) { + asort($this->index); + $this->indexSorted = true; + // Clear unsorted cache + $this->indexKeysCache = null; + $this->indexValuesCache = null; + } - return array_keys($this->index); + // Build or rebuild index keys cache + if ($this->indexKeysCache === null) { + $this->indexKeysCache = array_keys($this->index); + } + + return $this->indexKeysCache; } /** @@ -145,9 +185,19 @@ class Cells */ public function getSortedCoordinatesInt(): array { - asort($this->index); + if (!$this->indexSorted) { + asort($this->index); + $this->indexSorted = true; + // Clear unsorted cache + $this->indexKeysCache = null; + $this->indexValuesCache = null; + } - return array_values($this->index); + if ($this->indexValuesCache === null) { + $this->indexValuesCache = array_values($this->index); + } + + return $this->indexValuesCache; } /** @@ -185,7 +235,7 @@ class Cells /** * Get highest worksheet column and highest row that have cell records. * - * @return array Highest column name and highest row number + * @return array{row: int, column: string} Highest column name and highest row number */ public function getHighestRowAndColumn(): array { @@ -300,6 +350,11 @@ class Cells } } + // Clear index sorted flag and index caches + $newCollection->indexSorted = false; + $newCollection->indexKeysCache = null; + $newCollection->indexValuesCache = null; + return $newCollection; } @@ -387,8 +442,14 @@ class Cells $column = 0; $row = ''; sscanf($cellCoordinate, '%[A-Z]%d', $column, $row); + /** @var int $row */ $this->index[$cellCoordinate] = (--$row * self::MAX_COLUMN_ID) + Coordinate::columnIndexFromString((string) $column); + // Clear index sorted flag and index caches + $this->indexSorted = false; + $this->indexKeysCache = null; + $this->indexValuesCache = null; + $this->currentCoordinate = $cellCoordinate; $this->currentCell = $cell; $this->currentCellIsDirty = true; @@ -443,6 +504,11 @@ class Cells $this->index = []; + // Clear index sorted flag and index caches + $this->indexSorted = false; + $this->indexKeysCache = null; + $this->indexValuesCache = null; + // detach ourself from the worksheet, so that it can then delete this object successfully $this->parent = null; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Document/Security.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Document/Security.php index 31a32be..c65072a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Document/Security.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Document/Security.php @@ -31,12 +31,21 @@ class Security */ private string $workbookPassword = ''; - /** - * Create a new Document Security instance. - */ - public function __construct() - { - } + private string $workbookAlgorithmName = ''; + + private string $workbookHashValue = ''; + + private string $workbookSaltValue = ''; + + private int $workbookSpinCount = 0; + + private string $revisionsAlgorithmName = ''; + + private string $revisionsHashValue = ''; + + private string $revisionsSaltValue = ''; + + private int $revisionsSpinCount = 0; /** * Is some sort of document security enabled? @@ -105,10 +114,18 @@ class Security public function setRevisionsPassword(?string $password, bool $alreadyHashed = false): static { if ($password !== null) { - if (!$alreadyHashed) { - $password = PasswordHasher::hashPassword($password); + if ($this->advancedRevisionsPassword()) { + if (!$alreadyHashed) { + $password = PasswordHasher::hashPassword($password, $this->revisionsAlgorithmName, $this->revisionsSaltValue, $this->revisionsSpinCount); + } + $this->revisionsHashValue = $password; + $this->revisionsPassword = ''; + } else { + if (!$alreadyHashed) { + $password = PasswordHasher::hashPassword($password); + } + $this->revisionsPassword = $password; } - $this->revisionsPassword = $password; } return $this; @@ -129,12 +146,112 @@ class Security public function setWorkbookPassword(?string $password, bool $alreadyHashed = false): static { if ($password !== null) { - if (!$alreadyHashed) { - $password = PasswordHasher::hashPassword($password); + if ($this->advancedPassword()) { + if (!$alreadyHashed) { + $password = PasswordHasher::hashPassword($password, $this->workbookAlgorithmName, $this->workbookSaltValue, $this->workbookSpinCount); + } + $this->workbookHashValue = $password; + $this->workbookPassword = ''; + } else { + if (!$alreadyHashed) { + $password = PasswordHasher::hashPassword($password); + } + $this->workbookPassword = $password; } - $this->workbookPassword = $password; } return $this; } + + public function getWorkbookHashValue(): string + { + return $this->advancedPassword() ? $this->workbookHashValue : ''; + } + + public function advancedPassword(): bool + { + return $this->workbookAlgorithmName !== '' && $this->workbookSaltValue !== '' && $this->workbookSpinCount > 0; + } + + public function getWorkbookAlgorithmName(): string + { + return $this->workbookAlgorithmName; + } + + public function setWorkbookAlgorithmName(string $workbookAlgorithmName): static + { + $this->workbookAlgorithmName = $workbookAlgorithmName; + + return $this; + } + + public function getWorkbookSpinCount(): int + { + return $this->workbookSpinCount; + } + + public function setWorkbookSpinCount(int $workbookSpinCount): static + { + $this->workbookSpinCount = $workbookSpinCount; + + return $this; + } + + public function getWorkbookSaltValue(): string + { + return $this->workbookSaltValue; + } + + public function setWorkbookSaltValue(string $workbookSaltValue, bool $base64Required): static + { + $this->workbookSaltValue = $base64Required ? base64_encode($workbookSaltValue) : $workbookSaltValue; + + return $this; + } + + public function getRevisionsHashValue(): string + { + return $this->advancedRevisionsPassword() ? $this->revisionsHashValue : ''; + } + + public function advancedRevisionsPassword(): bool + { + return $this->revisionsAlgorithmName !== '' && $this->revisionsSaltValue !== '' && $this->revisionsSpinCount > 0; + } + + public function getRevisionsAlgorithmName(): string + { + return $this->revisionsAlgorithmName; + } + + public function setRevisionsAlgorithmName(string $revisionsAlgorithmName): static + { + $this->revisionsAlgorithmName = $revisionsAlgorithmName; + + return $this; + } + + public function getRevisionsSpinCount(): int + { + return $this->revisionsSpinCount; + } + + public function setRevisionsSpinCount(int $revisionsSpinCount): static + { + $this->revisionsSpinCount = $revisionsSpinCount; + + return $this; + } + + public function getRevisionsSaltValue(): string + { + return $this->revisionsSaltValue; + } + + public function setRevisionsSaltValue(string $revisionsSaltValue, bool $base64Required): static + { + $this->revisionsSaltValue = $base64Required ? base64_encode($revisionsSaltValue) : $revisionsSaltValue; + + return $this; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Dimension.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Dimension.php index a729dfd..e8c6c83 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Dimension.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Dimension.php @@ -52,20 +52,15 @@ class Dimension protected ?string $unit = null; - /** - * Phpstan bug has been fixed; this function allows us to - * pass Phpstan whether fixed or not. - */ - private static function stanBugFixed(array|int|null $value): array - { - return is_array($value) ? $value : [null, null]; - } - public function __construct(string $dimension) { - [$size, $unit] = self::stanBugFixed(sscanf($dimension, '%[1234567890.]%s')); - $unit = strtolower(trim($unit ?? '')); - $size = (float) $size; + $size = 0.0; + $unit = ''; + $sscanf = sscanf($dimension, '%[1234567890.]%s'); + if (is_array($sscanf)) { + $size = (float) ($sscanf[0] ?? 0.0); + $unit = strtolower($sscanf[1] ?? ''); + } // If a UoM is specified, then convert the size to pixels for internal storage if (isset(self::ABSOLUTE_UNITS[$unit])) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Downloader.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Downloader.php index 85131dc..0c39efe 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Downloader.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Downloader.php @@ -35,8 +35,9 @@ class Downloader $filepath = "{$folder}/{$filename}"; $this->filepath = (string) realpath($filepath); $this->filename = basename($filepath); - if ((file_exists($this->filepath) === false) || (is_readable($this->filepath) === false)) { - throw new Exception('File not found, or cannot be read'); + clearstatcache(); + if ((is_file($this->filepath) === false) || (is_readable($this->filepath) === false)) { + throw new Exception('File not found, or not a regular file, or cannot be read'); } $filetype ??= pathinfo($filename, PATHINFO_EXTENSION); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Html.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Html.php index 46fdd75..7def686 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Html.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Html.php @@ -557,6 +557,7 @@ class Html /** @var callable[] */ protected array $endTagCallbacks; + /** @var mixed[] */ private array $stack = []; public string $stringData = ''; @@ -711,12 +712,15 @@ class Html public static function colourNameLookup(string $colorName): string { - return static::COLOUR_MAP[$colorName] ?? ''; + /** @var string[] */ + $temp = static::COLOUR_MAP; + + return $temp[$colorName] ?? ''; } protected function startFontTag(DOMElement $tag): void { - $attrs = $tag->attributes; + $attrs = $tag->attributes ?? []; /** @var DOMAttr $attribute */ foreach ($attrs as $attribute) { $attributeName = strtolower($attribute->name); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Sample.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Sample.php index 420e80b..729d5d7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Sample.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Sample.php @@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Chart\Chart; use PhpOffice\PhpSpreadsheet\Chart\Renderer\MtJpGraphRenderer; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Settings; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PhpOffice\PhpSpreadsheet\Writer\IWriter; @@ -35,7 +36,7 @@ class Sample */ public function getScriptFilename(): string { - return basename($_SERVER['SCRIPT_FILENAME'], '.php'); + return basename(StringHelper::convertToString($_SERVER['SCRIPT_FILENAME']), '.php'); } /** @@ -184,10 +185,10 @@ class Sample return $temporaryFilename . '.' . $extension; } - public function log(string $message): void + public function log(mixed $message): void { $eol = $this->isCli() ? PHP_EOL : '
                  '; - echo ($this->isCli() ? date('H:i:s ') : '') . $message . $eol; + echo ($this->isCli() ? date('H:i:s ') : '') . StringHelper::convertToString($message) . $eol; } /** @@ -240,6 +241,7 @@ class Sample : $this->log(sprintf('Function: %s() - %s.', rtrim($functionName, '()'), rtrim($description, '.'))); } + /** @param mixed[][] $matrix */ public function displayGrid(array $matrix): void { $renderer = new TextGrid($matrix, $this->isCli()); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/TextGrid.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/TextGrid.php index 693e025..9c64c61 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/TextGrid.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/TextGrid.php @@ -2,19 +2,31 @@ namespace PhpOffice\PhpSpreadsheet\Helper; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; + class TextGrid { private bool $isCli; + /** @var mixed[][] */ protected array $matrix; + /** @var int[] */ protected array $rows; + /** @var string[] */ protected array $columns; private string $gridDisplay; - public function __construct(array $matrix, bool $isCli = true) + private bool $rowDividers = false; + + private bool $rowHeaders = true; + + private bool $columnHeaders = true; + + /** @param mixed[][] $matrix */ + public function __construct(array $matrix, bool $isCli = true, bool $rowDividers = false, bool $rowHeaders = true, bool $columnHeaders = true) { $this->rows = array_keys($matrix); $this->columns = array_keys($matrix[$this->rows[0]]); @@ -29,20 +41,25 @@ class TextGrid $this->matrix = $matrix; $this->isCli = $isCli; + $this->rowDividers = $rowDividers; + $this->rowHeaders = $rowHeaders; + $this->columnHeaders = $columnHeaders; } public function render(): string { - $this->gridDisplay = $this->isCli ? '' : '
                  ';
                  +        $this->gridDisplay = $this->isCli ? '' : ('
                  ' . PHP_EOL);
                   
                           if (!empty($this->rows)) {
                               $maxRow = max($this->rows);
                  -            $maxRowLength = mb_strlen((string) $maxRow) + 1;
                  +            $maxRowLength = strlen((string) $maxRow) + 1;
                               $columnWidths = $this->getColumnWidths();
                   
                               $this->renderColumnHeader($maxRowLength, $columnWidths);
                               $this->renderRows($maxRowLength, $columnWidths);
                  -            $this->renderFooter($maxRowLength, $columnWidths);
                  +            if (!$this->rowDividers) {
                  +                $this->renderFooter($maxRowLength, $columnWidths);
                  +            }
                           }
                   
                           $this->gridDisplay .= $this->isCli ? '' : '
                  '; @@ -50,34 +67,60 @@ class TextGrid return $this->gridDisplay; } + /** @param int[] $columnWidths */ private function renderRows(int $maxRowLength, array $columnWidths): void { foreach ($this->matrix as $row => $rowData) { - $this->gridDisplay .= '|' . str_pad((string) $this->rows[$row], $maxRowLength, ' ', STR_PAD_LEFT) . ' '; + if ($this->rowHeaders) { + $this->gridDisplay .= '|' . str_pad((string) $this->rows[$row], $maxRowLength, ' ', STR_PAD_LEFT) . ' '; + } $this->renderCells($rowData, $columnWidths); $this->gridDisplay .= '|' . PHP_EOL; + if ($this->rowDividers) { + $this->renderFooter($maxRowLength, $columnWidths); + } } } + /** + * @param mixed[] $rowData + * @param int[] $columnWidths + */ private function renderCells(array $rowData, array $columnWidths): void { foreach ($rowData as $column => $cell) { - $displayCell = ($this->isCli) ? (string) $cell : htmlentities((string) $cell); + $valueForLength = $this->getString($cell); + $displayCell = $this->isCli ? $valueForLength : htmlentities($valueForLength); $this->gridDisplay .= '| '; - $this->gridDisplay .= $displayCell . str_repeat(' ', $columnWidths[$column] - mb_strlen($cell ?? '') + 1); + $this->gridDisplay .= $displayCell . str_repeat(' ', $columnWidths[$column] - $this->strlen($valueForLength) + 1); } } - private function renderColumnHeader(int $maxRowLength, array $columnWidths): void + /** @param int[] $columnWidths */ + private function renderColumnHeader(int $maxRowLength, array &$columnWidths): void { - $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2); + if (!$this->columnHeaders) { + $this->renderFooter($maxRowLength, $columnWidths); + + return; + } + foreach ($this->columns as $column => $reference) { + /** @var string $reference */ + $columnWidths[$column] = max($columnWidths[$column], $this->strlen($reference)); + } + if ($this->rowHeaders) { + $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2); + } foreach ($this->columns as $column => $reference) { $this->gridDisplay .= '+-' . str_repeat('-', $columnWidths[$column] + 1); } $this->gridDisplay .= '+' . PHP_EOL; - $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2); + if ($this->rowHeaders) { + $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2); + } foreach ($this->columns as $column => $reference) { + /** @var scalar $reference */ $this->gridDisplay .= '| ' . str_pad((string) $reference, $columnWidths[$column] + 1, ' '); } $this->gridDisplay .= '|' . PHP_EOL; @@ -85,9 +128,12 @@ class TextGrid $this->renderFooter($maxRowLength, $columnWidths); } + /** @param int[] $columnWidths */ private function renderFooter(int $maxRowLength, array $columnWidths): void { - $this->gridDisplay .= '+' . str_repeat('-', $maxRowLength + 1); + if ($this->rowHeaders) { + $this->gridDisplay .= '+' . str_repeat('-', $maxRowLength + 1); + } foreach ($this->columns as $column => $reference) { $this->gridDisplay .= '+-'; $this->gridDisplay .= str_pad((string) '', $columnWidths[$column] + 1, '-'); @@ -95,6 +141,7 @@ class TextGrid $this->gridDisplay .= '+' . PHP_EOL; } + /** @return int[] */ private function getColumnWidths(): array { $columnCount = count($this->matrix, COUNT_RECURSIVE) / count($this->matrix); @@ -106,21 +153,26 @@ class TextGrid return $columnWidths; } + /** @param mixed[] $columnData */ private function getColumnWidth(array $columnData): int { $columnWidth = 0; $columnData = array_values($columnData); foreach ($columnData as $columnValue) { - if (is_string($columnValue)) { - $columnWidth = max($columnWidth, mb_strlen($columnValue)); - } elseif (is_bool($columnValue)) { - $columnWidth = max($columnWidth, mb_strlen($columnValue ? 'TRUE' : 'FALSE')); - } - - $columnWidth = max($columnWidth, mb_strlen((string) $columnWidth)); + $columnWidth = max($columnWidth, $this->strlen($this->getString($columnValue))); } return $columnWidth; } + + protected function getString(mixed $value): string + { + return StringHelper::convertToString($value, convertBool: true); + } + + protected function strlen(string $value): int + { + return mb_strlen($value); + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php index 73734fc..91eec42 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php @@ -116,6 +116,8 @@ abstract class IOFactory /** * Identify file type using automatic IReader resolution. + * + * @param string[] $readers */ public static function identify(string $filename, ?array $readers = null, bool $fullClassName = false): string { @@ -225,7 +227,8 @@ abstract class IOFactory */ public static function registerWriter(string $writerType, string $writerClass): void { - if (!is_a($writerClass, IWriter::class, true)) { + // We want phpstan to validate caller, but still need this test + if (!is_a($writerClass, IWriter::class, true)) { //* @phpstan-ignore-line throw new Writer\Exception('Registered writers must implement ' . IWriter::class); } @@ -239,7 +242,8 @@ abstract class IOFactory */ public static function registerReader(string $readerType, string $readerClass): void { - if (!is_a($readerClass, IReader::class, true)) { + // We want phpstan to validate caller, but still need this test + if (!is_a($readerClass, IReader::class, true)) { //* @phpstan-ignore-line throw new Reader\Exception('Registered readers must implement ' . IReader::class); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/NamedRange.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/NamedRange.php index 819ddea..c7fb853 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/NamedRange.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/NamedRange.php @@ -43,6 +43,7 @@ class NamedRange extends DefinedName return $this; } + /** @return string[] */ public function getCellsInRange(): array { $range = $this->value; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/BaseReader.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/BaseReader.php index de80834..c4184bd 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/BaseReader.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/BaseReader.php @@ -47,6 +47,19 @@ abstract class BaseReader implements IReader */ protected bool $ignoreRowsWithNoCells = false; + /** + * Allow external images. Use with caution. + * Improper specification of these within a spreadsheet + * can subject the caller to security exploits. + */ + protected bool $allowExternalImages = false; + + /** + * Create a blank sheet if none are read, + * possibly due to a typo when using LoadSheetsOnly. + */ + protected bool $createBlankSheetIfNoneRead = false; + /** * IReadFilter instance. */ @@ -112,11 +125,13 @@ abstract class BaseReader implements IReader return $this; } + /** @return null|string[] */ public function getLoadSheetsOnly(): ?array { return $this->loadSheetsOnly; } + /** @param null|string|string[] $sheetList */ public function setLoadSheetsOnly(string|array|null $sheetList): self { if ($sheetList === null) { @@ -147,6 +162,34 @@ abstract class BaseReader implements IReader return $this; } + /** + * Allow external images. Use with caution. + * Improper specification of these within a spreadsheet + * can subject the caller to security exploits. + */ + public function setAllowExternalImages(bool $allowExternalImages): self + { + $this->allowExternalImages = $allowExternalImages; + + return $this; + } + + public function getAllowExternalImages(): bool + { + return $this->allowExternalImages; + } + + /** + * Create a blank sheet if none are read, + * possibly due to a typo when using LoadSheetsOnly. + */ + public function setCreateBlankSheetIfNoneRead(bool $createBlankSheetIfNoneRead): self + { + $this->createBlankSheetIfNoneRead = $createBlankSheetIfNoneRead; + + return $this; + } + public function getSecurityScanner(): ?XmlScanner { return $this->securityScanner; @@ -175,6 +218,15 @@ abstract class BaseReader implements IReader if (((bool) ($flags & self::IGNORE_ROWS_WITH_NO_CELLS)) === true) { $this->setIgnoreRowsWithNoCells(true); } + if (((bool) ($flags & self::ALLOW_EXTERNAL_IMAGES)) === true) { + $this->setAllowExternalImages(true); + } + if (((bool) ($flags & self::DONT_ALLOW_EXTERNAL_IMAGES)) === true) { + $this->setAllowExternalImages(false); + } + if (((bool) ($flags & self::CREATE_BLANK_SHEET_IF_NONE_READ)) === true) { + $this->setCreateBlankSheetIfNoneRead(true); + } } protected function loadSpreadsheetFromFile(string $filename): Spreadsheet @@ -221,6 +273,8 @@ abstract class BaseReader implements IReader /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ public function listWorksheetInfo(string $filename): array { @@ -232,15 +286,15 @@ abstract class BaseReader implements IReader * possibly without parsing the whole file to a Spreadsheet object. * Readers will often have a more efficient method with which * they can override this method. + * + * @return string[] */ public function listWorksheetNames(string $filename): array { $returnArray = []; $info = $this->listWorksheetInfo($filename); foreach ($info as $infoArray) { - if (isset($infoArray['worksheetName'])) { - $returnArray[] = $infoArray['worksheetName']; - } + $returnArray[] = $infoArray['worksheetName']; } return $returnArray; @@ -257,4 +311,9 @@ abstract class BaseReader implements IReader return $this; } + + protected function newSpreadsheet(): Spreadsheet + { + return new Spreadsheet(); + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv.php index cd69f2e..55fe08a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv.php @@ -188,7 +188,8 @@ class Csv extends BaseReader */ protected function inferSeparator(): void { - if ($this->delimiter !== null) { + $temp = $this->delimiter; + if ($temp !== null) { return; } @@ -214,6 +215,8 @@ class Csv extends BaseReader /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ public function listWorksheetInfo(string $filename): array { @@ -226,12 +229,15 @@ class Csv extends BaseReader $this->checkSeparator(); $this->inferSeparator(); - $worksheetInfo = []; - $worksheetInfo[0]['worksheetName'] = 'Worksheet'; - $worksheetInfo[0]['lastColumnLetter'] = 'A'; - $worksheetInfo[0]['lastColumnIndex'] = 0; - $worksheetInfo[0]['totalRows'] = 0; - $worksheetInfo[0]['totalColumns'] = 0; + $worksheetInfo = [ + [ + 'worksheetName' => 'Worksheet', + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ], + ]; $delimiter = $this->delimiter ?? ''; // Loop through each line of the file in turn @@ -257,8 +263,7 @@ class Csv extends BaseReader */ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet { - // Create new Spreadsheet - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->newSpreadsheet(); $spreadsheet->setValueBinder($this->valueBinder); // Load into this instance @@ -270,8 +275,7 @@ class Csv extends BaseReader */ public function loadSpreadsheetFromString(string $contents): Spreadsheet { - // Create new Spreadsheet - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->newSpreadsheet(); $spreadsheet->setValueBinder($this->valueBinder); // Load into this instance @@ -445,7 +449,7 @@ class Csv extends BaseReader // Set cell value $sheet->getCell($columnLetter . $outRow)->setValue($rowDatum); } - ++$columnLetter; + StringHelper::stringIncrement($columnLetter); } $rowData = self::getCsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter); ++$currentRow; @@ -601,6 +605,7 @@ class Csv extends BaseReader 'text/csv', 'text/plain', 'inode/x-empty', + 'application/x-empty', // has now replaced previous 'text/html', ]; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv/Delimiter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv/Delimiter.php index 348331e..05b898f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv/Delimiter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv/Delimiter.php @@ -13,6 +13,7 @@ class Delimiter protected string $enclosure; + /** @var array */ protected array $counts = []; protected int $numberLines = 0; @@ -53,6 +54,7 @@ class Delimiter } } + /** @param array $delimiterKeys */ protected function countDelimiterValues(string $line, array $delimiterKeys): void { $splitString = mb_str_split($line, 1, 'UTF-8'); @@ -69,7 +71,7 @@ class Delimiter // Calculate the mean square deviations for each delimiter // (ignoring delimiters that haven't been found consistently) $meanSquareDeviations = []; - $middleIdx = floor(($this->numberLines - 1) / 2); + $middleIdx = (int) floor(($this->numberLines - 1) / 2); foreach (self::POTENTIAL_DELIMETERS as $delimiter) { $series = $this->counts[$delimiter]; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric.php index 5b2c1a5..5e68360 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric.php @@ -38,6 +38,8 @@ class Gnumeric extends BaseReader /** * Shared Expressions. + * + * @var array */ private array $expressions = []; @@ -48,6 +50,7 @@ class Gnumeric extends BaseReader private ReferenceHelper $referenceHelper; + /** @var array{'dataType': string[]} */ public static array $mappings = [ 'dataType' => [ '10' => DataType::TYPE_NULL, @@ -96,6 +99,8 @@ class Gnumeric extends BaseReader /** * Reads names of the worksheets from a file, without parsing the whole file to a Spreadsheet object. + * + * @return string[] */ public function listWorksheetNames(string $filename): array { @@ -125,6 +130,8 @@ class Gnumeric extends BaseReader /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ public function listWorksheetInfo(string $filename): array { @@ -201,6 +208,7 @@ class Gnumeric extends BaseReader return $data; } + /** @return mixed[] */ public static function gnumericMappings(): array { return array_merge(self::$mappings, Styles::$mappings); @@ -231,8 +239,7 @@ class Gnumeric extends BaseReader */ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet { - // Create new Spreadsheet - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->newSpreadsheet(); $spreadsheet->setValueBinder($this->valueBinder); $spreadsheet->removeSheetByIndex(0); @@ -262,6 +269,7 @@ class Gnumeric extends BaseReader (new Properties($this->spreadsheet))->readProperties($xml, $gnmXML); $worksheetID = 0; + $sheetCreated = false; foreach ($gnmXML->Sheets->Sheet as $sheetOrNull) { $sheet = self::testSimpleXml($sheetOrNull); $worksheetName = (string) $sheet->Name; @@ -273,6 +281,7 @@ class Gnumeric extends BaseReader // Create new Worksheet $this->spreadsheet->createSheet(); + $sheetCreated = true; $this->spreadsheet->setActiveSheetIndex($worksheetID); // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet @@ -322,6 +331,9 @@ class Gnumeric extends BaseReader $this->setSelectedCells($sheet); ++$worksheetID; } + if ($this->createBlankSheetIfNoneRead && !$sheetCreated) { + $this->spreadsheet->createSheet(); + } $this->processDefinedNames($gnmXML); @@ -558,8 +570,8 @@ class Gnumeric extends BaseReader if (((string) $cell) > '') { // Formula $this->expressions[$ExprID] = [ - 'column' => $cellAttributes->Col, - 'row' => $cellAttributes->Row, + 'column' => (int) $cellAttributes->Col, + 'row' => (int) $cellAttributes->Row, 'formula' => (string) $cell, ]; } else { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric/PageSetup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric/PageSetup.php index f12b742..8315aa5 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric/PageSetup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric/PageSetup.php @@ -70,6 +70,11 @@ class PageSetup return $this; } + /** + * @param float[] $marginSet + * + * @return float[] + */ private function buildMarginSet(SimpleXMLElement $sheet, array $marginSet): array { foreach ($sheet->PrintInformation->Margins->children(Gnumeric::NAMESPACE_GNM) as $key => $margin) { @@ -83,6 +88,7 @@ class PageSetup return $marginSet; } + /** @param float[] $marginSet */ private function adjustMargins(array $marginSet): void { foreach ($marginSet as $key => $marginSize) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric/Styles.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric/Styles.php index f901c4a..e947ae2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric/Styles.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric/Styles.php @@ -18,6 +18,7 @@ class Styles protected bool $readDataOnly; + /** @var array */ public static array $mappings = [ 'borderStyle' => [ '0' => Border::BORDER_NONE, @@ -100,6 +101,7 @@ class Styles $styleAttributes = $style->Style->attributes(); + /** @var mixed[][] */ $styleArray = []; // We still set the number format mask for date/time values, even if readDataOnly is true // so that we can identify whether a float is a float or a date value @@ -112,11 +114,16 @@ class Styles $styleArray['numberFormat']['formatCode'] = $formatCode; $styleArray = $this->readStyle($styleArray, $styleAttributes, $style); } - $this->spreadsheet->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray); + /** @var mixed[][] $styleArray */ + $this->spreadsheet + ->getActiveSheet() + ->getStyle($cellRange) + ->applyFromArray($styleArray); } } } + /** @param mixed[][] $styleArray */ private function addBorderDiagonal(SimpleXMLElement $srssb, array &$styleArray): void { if (isset($srssb->Diagonal, $srssb->{'Rev-Diagonal'})) { @@ -131,11 +138,14 @@ class Styles } } + /** @param mixed[][] $styleArray */ private function addBorderStyle(SimpleXMLElement $srssb, array &$styleArray, string $direction): void { $ucDirection = ucfirst($direction); if (isset($srssb->$ucDirection)) { - $styleArray['borders'][$direction] = self::parseBorderAttributes($srssb->$ucDirection->attributes()); + /** @var SimpleXMLElement */ + $temp = $srssb->$ucDirection; + $styleArray['borders'][$direction] = self::parseBorderAttributes($temp->attributes()); } } @@ -150,13 +160,15 @@ class Styles return $rotation; } + /** @param mixed[][] $styleArray */ private static function addStyle(array &$styleArray, string $key, string $value): void { if (array_key_exists($value, self::$mappings[$key])) { - $styleArray[$key] = self::$mappings[$key][$value]; + $styleArray[$key] = self::$mappings[$key][$value]; //* @phpstan-ignore-line } } + /** @param mixed[][] $styleArray */ private static function addStyle2(array &$styleArray, string $key1, string $key, string $value): void { if (array_key_exists($value, self::$mappings[$key])) { @@ -164,8 +176,10 @@ class Styles } } + /** @return mixed[][] */ private static function parseBorderAttributes(?SimpleXMLElement $borderAttributes): array { + /** @var mixed[][] */ $styleArray = []; if ($borderAttributes !== null) { if (isset($borderAttributes['Color'])) { @@ -174,6 +188,7 @@ class Styles self::addStyle($styleArray, 'borderStyle', (string) $borderAttributes['Style']); } + /** @var mixed[][] $styleArray */ return $styleArray; } @@ -188,9 +203,11 @@ class Styles return $gnmR . $gnmG . $gnmB; } + /** @param mixed[][] $styleArray */ private function addColors(array &$styleArray, SimpleXMLElement $styleAttributes): void { $RGB = self::parseGnumericColour((string) $styleAttributes['Fore']); + /** @var mixed[][][] $styleArray */ $styleArray['font']['color']['rgb'] = $RGB; $RGB = self::parseGnumericColour((string) $styleAttributes['Back']); $shade = (string) $styleAttributes['Shade']; @@ -221,6 +238,11 @@ class Styles return $cellRange; } + /** + * @param mixed[][] $styleArray + * + * @return mixed[] + */ private function readStyle(array $styleArray, SimpleXMLElement $styleAttributes, SimpleXMLElement $style): array { self::addStyle2($styleArray, 'alignment', 'horizontal', (string) $styleAttributes['HAlign']); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php index a733e0d..579f389 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php @@ -16,7 +16,9 @@ use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; use PhpOffice\PhpSpreadsheet\Helper\Dimension as CssDimension; use PhpOffice\PhpSpreadsheet\Helper\Html as HelperHtml; use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Style\Alignment; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Style\Color; use PhpOffice\PhpSpreadsheet\Style\Fill; @@ -50,7 +52,7 @@ class Html extends BaseReader /** * Formats. */ - protected array $formats = [ + protected const FORMATS = [ 'h1' => [ 'font' => [ 'bold' => true, @@ -127,6 +129,7 @@ class Html extends BaseReader ], // Italic ]; + /** @var array */ protected array $rowspan = []; /** @@ -210,20 +213,24 @@ class Html extends BaseReader */ public function loadSpreadsheetFromFile(string $filename): Spreadsheet { - // Create new Spreadsheet - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->newSpreadsheet(); $spreadsheet->setValueBinder($this->valueBinder); // Load into this instance return $this->loadIntoExisting($filename, $spreadsheet); } - // Data Array used for testing only, should write to Spreadsheet object on completion of tests - + /** + * Data Array used for testing only, should write to + * Spreadsheet object on completion of tests. + * + * @var mixed[][] + */ protected array $dataArray = []; protected int $tableLevel = 0; + /** @var string[] */ protected array $nestedColumn = ['A']; protected function setTableStartColumn(string $column): string @@ -246,11 +253,15 @@ class Html extends BaseReader { --$this->tableLevel; - return array_pop($this->nestedColumn); + return array_pop($this->nestedColumn) ?? ''; } /** * Flush cell. + * + * @param string[] $attributeArray + * + * @param-out string $cellContent In one case, it can be bool */ protected function flushCell(Worksheet $sheet, string $column, int|string $row, mixed &$cellContent, array $attributeArray): void { @@ -273,7 +284,8 @@ class Html extends BaseReader } } if ($datatype === DataType::TYPE_BOOL) { - $cellContent = self::convertBoolean($cellContent); + // This is the case where we can set cellContent to bool rather than string + $cellContent = self::convertBoolean($cellContent); //* @phpstan-ignore-line if (!is_bool($cellContent)) { $attributeArray['data-type'] = DataType::TYPE_STRING; } @@ -293,7 +305,7 @@ class Html extends BaseReader } else { // We have a Rich Text run // TODO - $this->dataArray[$row][$column] = 'RICH TEXT: ' . $cellContent; + $this->dataArray[$row][$column] = 'RICH TEXT: ' . StringHelper::convertToString($cellContent); } $cellContent = (string) ''; } @@ -327,7 +339,7 @@ class Html extends BaseReader { $attributeArray = []; /** @var DOMAttr $attribute */ - foreach ($child->attributes as $attribute) { + foreach (($child->attributes ?? []) as $attribute) { $attributeArray[$attribute->name] = $attribute->value; } @@ -342,6 +354,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementTitle(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if ($child->nodeName === 'title') { @@ -361,6 +374,7 @@ class Html extends BaseReader private const SPAN_ETC = ['span', 'div', 'font', 'i', 'em', 'strong', 'b']; + /** @param string[] $attributeArray */ private function processDomElementSpanEtc(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if (in_array((string) $child->nodeName, self::SPAN_ETC, true)) { @@ -373,7 +387,7 @@ class Html extends BaseReader } if (isset($attributeArray['style'])) { $alignStyle = $attributeArray['style']; - if (preg_match('/\btext-align:\s*(left|right|center|justify)\b/', $alignStyle, $matches) === 1) { + if (preg_match('/\btext-align:\s*(left|right|center|justify)\b/', (string) $alignStyle, $matches) === 1) { $sheet->getComment($column . $row)->setAlignment($matches[1]); } } @@ -381,28 +395,28 @@ class Html extends BaseReader $this->processDomElement($child, $sheet, $row, $column, $cellContent); } - if (isset($this->formats[$child->nodeName])) { - $sheet->getStyle($column . $row)->applyFromArray($this->formats[$child->nodeName]); + if (isset(self::FORMATS[$child->nodeName])) { + $sheet->getStyle($column . $row)->applyFromArray(self::FORMATS[$child->nodeName]); } } else { $this->processDomElementHr($sheet, $row, $column, $cellContent, $child, $attributeArray); } } + /** @param string[] $attributeArray */ private function processDomElementHr(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if ($child->nodeName === 'hr') { $this->flushCell($sheet, $column, $row, $cellContent, $attributeArray); ++$row; - if (isset($this->formats[$child->nodeName])) { - $sheet->getStyle($column . $row)->applyFromArray($this->formats[$child->nodeName]); - } + $sheet->getStyle($column . $row)->applyFromArray(self::FORMATS[$child->nodeName]); ++$row; } // fall through to br $this->processDomElementBr($sheet, $row, $column, $cellContent, $child, $attributeArray); } + /** @param string[] $attributeArray */ private function processDomElementBr(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if ($child->nodeName === 'br' || $child->nodeName === 'hr') { @@ -420,6 +434,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementA(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if ($child->nodeName === 'a') { @@ -427,9 +442,7 @@ class Html extends BaseReader switch ($attributeName) { case 'href': $sheet->getCell($column . $row)->getHyperlink()->setUrl($attributeValue); - if (isset($this->formats[$child->nodeName])) { - $sheet->getStyle($column . $row)->applyFromArray($this->formats[$child->nodeName]); - } + $sheet->getStyle($column . $row)->applyFromArray(self::FORMATS[$child->nodeName]); break; case 'class': @@ -448,6 +461,7 @@ class Html extends BaseReader private const H1_ETC = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', 'p']; + /** @param string[] $attributeArray */ private function processDomElementH1Etc(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if (in_array((string) $child->nodeName, self::H1_ETC, true)) { @@ -464,8 +478,8 @@ class Html extends BaseReader $this->processDomElement($child, $sheet, $row, $column, $cellContent); $this->flushCell($sheet, $column, $row, $cellContent, $attributeArray); - if (isset($this->formats[$child->nodeName])) { - $sheet->getStyle($column . $row)->applyFromArray($this->formats[$child->nodeName]); + if (isset(self::FORMATS[$child->nodeName])) { + $sheet->getStyle($column . $row)->applyFromArray(self::FORMATS[$child->nodeName]); } ++$row; @@ -476,6 +490,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementLi(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if ($child->nodeName === 'li') { @@ -497,6 +512,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementImg(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if ($child->nodeName === 'img') { @@ -508,6 +524,7 @@ class Html extends BaseReader private string $currentColumn = 'A'; + /** @param string[] $attributeArray */ private function processDomElementTable(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if ($child->nodeName === 'table') { @@ -516,6 +533,9 @@ class Html extends BaseReader $sheet->setShowGridlines(in_array('gridlines', $classes, true)); $sheet->setPrintGridlines(in_array('gridlinesp', $classes, true)); } + if ('rtl' === ($attributeArray['dir'] ?? '')) { + $sheet->setRightToLeft(true); + } $this->currentColumn = 'A'; $this->flushCell($sheet, $column, $row, $cellContent, $attributeArray); $column = $this->setTableStartColumn($column); @@ -525,7 +545,7 @@ class Html extends BaseReader $this->processDomElement($child, $sheet, $row, $column, $cellContent); $column = $this->releaseTableStartColumn(); if ($this->tableLevel > 1) { - ++$column; //* @phpstan-ignore-line + StringHelper::stringIncrement($column); } else { ++$row; } @@ -534,18 +554,19 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementTr(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if ($child->nodeName === 'col') { $this->applyInlineStyle($sheet, -1, $this->currentColumn, $attributeArray); - ++$this->currentColumn; + StringHelper::stringIncrement($this->currentColumn); } elseif ($child->nodeName === 'tr') { $column = $this->getTableStartColumn(); $cellContent = ''; $this->processDomElement($child, $sheet, $row, $column, $cellContent); if (isset($attributeArray['height'])) { - $sheet->getRowDimension($row)->setRowHeight($attributeArray['height']); + $sheet->getRowDimension($row)->setRowHeight((float) $attributeArray['height']); } ++$row; @@ -554,6 +575,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementThTdOther(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { if ($child->nodeName !== 'td' && $child->nodeName !== 'th') { @@ -563,6 +585,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementBgcolor(Worksheet $sheet, int $row, string $column, array $attributeArray): void { if (isset($attributeArray['bgcolor'])) { @@ -577,6 +600,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementWidth(Worksheet $sheet, string $column, array $attributeArray): void { if (isset($attributeArray['width'])) { @@ -584,6 +608,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementHeight(Worksheet $sheet, int $row, array $attributeArray): void { if (isset($attributeArray['height'])) { @@ -591,6 +616,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementAlign(Worksheet $sheet, int $row, string $column, array $attributeArray): void { if (isset($attributeArray['align'])) { @@ -598,6 +624,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementVAlign(Worksheet $sheet, int $row, string $column, array $attributeArray): void { if (isset($attributeArray['valign'])) { @@ -605,6 +632,7 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementDataFormat(Worksheet $sheet, int $row, string $column, array $attributeArray): void { if (isset($attributeArray['data-format'])) { @@ -612,17 +640,19 @@ class Html extends BaseReader } } + /** @param string[] $attributeArray */ private function processDomElementThTd(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void { while (isset($this->rowspan[$column . $row])) { - ++$column; //* @phpstan-ignore-line + $temp = (string) $column; + $column = StringHelper::stringIncrement($temp); } - //* @phpstan-ignore-next-line - $this->processDomElement($child, $sheet, $row, $column, $cellContent); // ++$column above confuses Phpstan + $this->processDomElement($child, $sheet, $row, $column, $cellContent); // apply inline style $this->applyInlineStyle($sheet, $row, $column, $attributeArray); + /** @var string $cellContent */ $this->flushCell($sheet, $column, $row, $cellContent, $attributeArray); $this->processDomElementBgcolor($sheet, $row, $column, $attributeArray); @@ -636,15 +666,14 @@ class Html extends BaseReader //create merging rowspan and colspan $columnTo = $column; for ($i = 0; $i < (int) $attributeArray['colspan'] - 1; ++$i) { - ++$columnTo; + StringHelper::stringIncrement($columnTo); } $range = $column . $row . ':' . $columnTo . ($row + (int) $attributeArray['rowspan'] - 1); foreach (Coordinate::extractAllCellReferencesInRange($range) as $value) { $this->rowspan[$value] = true; } $sheet->mergeCells($range); - //* @phpstan-ignore-next-line - $column = $columnTo; // ++$columnTo above confuses phpstan + $column = $columnTo; } elseif (isset($attributeArray['rowspan'])) { //create merging rowspan $range = $column . $row . ':' . $column . ($row + (int) $attributeArray['rowspan'] - 1); @@ -656,14 +685,13 @@ class Html extends BaseReader //create merging colspan $columnTo = $column; for ($i = 0; $i < (int) $attributeArray['colspan'] - 1; ++$i) { - ++$columnTo; + StringHelper::stringIncrement($columnTo); } $sheet->mergeCells($column . $row . ':' . $columnTo . $row); - //* @phpstan-ignore-next-line - $column = $columnTo; // ++$columnTo above confuses phpstan + $column = $columnTo; } - ++$column; + StringHelper::stringIncrement($column); } protected function processDomElement(DOMNode $element, Worksheet $sheet, int &$row, string &$column, string &$cellContent): void @@ -700,13 +728,13 @@ class Html extends BaseReader // Reload the HTML file into the DOM object try { $convert = $this->getSecurityScannerOrThrow()->scanFile($filename); - $convert = self::replaceNonAsciiIfNeeded($convert); + $convert = static::replaceNonAsciiIfNeeded($convert); $loaded = ($convert === null) ? false : $dom->loadHTML($convert); } catch (Throwable $e) { $loaded = false; } if ($loaded === false) { - throw new Exception('Failed to load ' . $filename . ' as a DOM Document', 0, $e ?? null); + throw new Exception('Failed to load file ' . $filename . ' as a DOM Document', 0, $e ?? null); } self::loadProperties($dom, $spreadsheet); @@ -788,12 +816,13 @@ class Html extends BaseReader } } + /** @param string[] $matches */ private static function replaceNonAscii(array $matches): string { return '&#' . mb_ord($matches[0], 'UTF-8') . ';'; } - private static function replaceNonAsciiIfNeeded(string $convert): ?string + protected static function replaceNonAsciiIfNeeded(string $convert): ?string { if (preg_match(self::STARTS_WITH_BOM, $convert) !== 1 && preg_match(self::DECLARES_CHARSET, $convert) !== 1) { $lowend = "\u{80}"; @@ -818,7 +847,7 @@ class Html extends BaseReader // Reload the HTML file into the DOM object try { $convert = $this->getSecurityScannerOrThrow()->scan($content); - $convert = self::replaceNonAsciiIfNeeded($convert); + $convert = static::replaceNonAsciiIfNeeded($convert); $loaded = ($convert === null) ? false : $dom->loadHTML($convert); } catch (Throwable $e) { $loaded = false; @@ -826,7 +855,7 @@ class Html extends BaseReader if ($loaded === false) { throw new Exception('Failed to load content as a DOM Document', 0, $e ?? null); } - $spreadsheet = $spreadsheet ?? new Spreadsheet(); + $spreadsheet = $spreadsheet ?? $this->newSpreadsheet(); $spreadsheet->setValueBinder($this->valueBinder); self::loadProperties($dom, $spreadsheet); @@ -887,6 +916,8 @@ class Html extends BaseReader * * TODO : * - Implement to other propertie, such as border + * + * @param string[] $attributeArray */ private function applyInlineStyle(Worksheet &$sheet, int $row, string $column, array $attributeArray): void { @@ -899,7 +930,7 @@ class Html extends BaseReader } elseif (isset($attributeArray['rowspan'], $attributeArray['colspan'])) { $columnTo = $column; for ($i = 0; $i < (int) $attributeArray['colspan'] - 1; ++$i) { - ++$columnTo; + StringHelper::stringIncrement($columnTo); } $range = $column . $row . ':' . $columnTo . ($row + (int) $attributeArray['rowspan'] - 1); $cellStyle = $sheet->getStyle($range); @@ -909,7 +940,7 @@ class Html extends BaseReader } elseif (isset($attributeArray['colspan'])) { $columnTo = $column; for ($i = 0; $i < (int) $attributeArray['colspan'] - 1; ++$i) { - ++$columnTo; + StringHelper::stringIncrement($columnTo); } $range = $column . $row . ':' . $columnTo . $row; $cellStyle = $sheet->getStyle($range); @@ -984,6 +1015,17 @@ class Html extends BaseReader break; + case 'direction': + if ($styleValue === 'rtl') { + $cellStyle->getAlignment() + ->setReadOrder(Alignment::READORDER_RTL); + } elseif ($styleValue === 'ltr') { + $cellStyle->getAlignment() + ->setReadOrder(Alignment::READORDER_LTR); + } + + break; + case 'font-weight': if ($styleValue === 'bold' || $styleValue >= 500) { $cellStyle->getFont()->setBold(true); @@ -1053,8 +1095,11 @@ class Html extends BaseReader break; case 'text-indent': + $indentDimension = new CssDimension($styleValueString); + $indent = $indentDimension + ->toUnit(CssDimension::UOM_PIXELS); $cellStyle->getAlignment()->setIndent( - (int) str_replace(['px'], '', $styleValueString) + (int) ($indent / Alignment::INDENT_UNITS_TO_PIXELS) ); break; @@ -1075,6 +1120,7 @@ class Html extends BaseReader return HelperHtml::colourNameLookup($value); } + /** @param string[] $attributes */ private function insertImage(Worksheet $sheet, string $column, int $row, array $attributes): void { if (!isset($attributes['src'])) { @@ -1091,7 +1137,7 @@ class Html extends BaseReader $name = $attributes['alt'] ?? null; $drawing = new Drawing(); - $drawing->setPath($src, false); + $drawing->setPath($src, false, allowExternal: $this->allowExternalImages); if ($drawing->getPath() === '') { return; } @@ -1105,6 +1151,8 @@ class Html extends BaseReader $drawing->setName($name); } + /** @var null|scalar $width */ + /** @var null|scalar $height */ if ($width) { if ($height) { $drawing->setWidthAndHeight((int) $width, (int) $height); @@ -1131,6 +1179,11 @@ class Html extends BaseReader } } + /** + * @param string[] $attributes + * + * @return mixed[] + */ private static function getStyleArray(array $attributes): array { $styleArray = []; @@ -1145,13 +1198,13 @@ class Html extends BaseReader if (substr($arrayValue, -2) === 'px') { $arrayValue = (string) (((float) substr($arrayValue, 0, -2))); } else { - $arrayValue = (new CssDimension($arrayValue))->width(); + $arrayValue = (new CssDimension($arrayValue))->toUnit(CssDimension::UOM_PIXELS); } } elseif ($arrayKey === 'height') { if (substr($arrayValue, -2) === 'px') { $arrayValue = substr($arrayValue, 0, -2); } else { - $arrayValue = (new CssDimension($arrayValue))->height(); + $arrayValue = (new CssDimension($arrayValue))->toUnit(CssDimension::UOM_PIXELS); } } $styleArray[$arrayKey] = $arrayValue; @@ -1179,6 +1232,7 @@ class Html extends BaseReader 'thick' => Border::BORDER_THICK, ]; + /** @return array */ public static function getBorderMappings(): array { return self::BORDER_MAPPINGS; @@ -1221,11 +1275,13 @@ class Html extends BaseReader /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ public function listWorksheetInfo(string $filename): array { $info = []; - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->newSpreadsheet(); $this->loadIntoExisting($filename, $spreadsheet); foreach ($spreadsheet->getAllSheets() as $sheet) { $newEntry = ['worksheetName' => $sheet->getTitle()]; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/IReader.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/IReader.php index 250ef4f..5f2890a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/IReader.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/IReader.php @@ -33,6 +33,16 @@ interface IReader */ public const IGNORE_ROWS_WITH_NO_CELLS = 8; + /** + * Allow external images. Use with caution. + * Improper specification of these within a spreadsheet + * can subject the caller to security exploits. + */ + public const ALLOW_EXTERNAL_IMAGES = 16; + public const DONT_ALLOW_EXTERNAL_IMAGES = 32; + + public const CREATE_BLANK_SHEET_IF_NONE_READ = 64; + public function __construct(); /** @@ -96,13 +106,15 @@ interface IReader * Get which sheets to load * Returns either an array of worksheet names (the list of worksheets that should be loaded), or a null * indicating that all worksheets in the workbook should be loaded. + * + * @return null|string[] */ public function getLoadSheetsOnly(): ?array; /** * Set which sheets to load. * - * @param null|array|string $value This should be either an array of worksheet names to be loaded, + * @param null|string|string[] $value This should be either an array of worksheet names to be loaded, * or a string containing a single worksheet name. If NULL, then it tells the Reader to * read all worksheets in the workbook * @@ -130,6 +142,21 @@ interface IReader */ public function setReadFilter(IReadFilter $readFilter): self; + /** + * Allow external images. Use with caution. + * Improper specification of these within a spreadsheet + * can subject the caller to security exploits. + */ + public function setAllowExternalImages(bool $allowExternalImages): self; + + public function getAllowExternalImages(): bool; + + /** + * Create a blank sheet if none are read, + * possibly due to a typo when using LoadSheetsOnly. + */ + public function setCreateBlankSheetIfNoneRead(bool $createBlankSheetIfNoneRead): self; + /** * Loads PhpSpreadsheet from file. * @@ -139,6 +166,10 @@ interface IReader * self::READ_DATA_ONLY Read only data, not style or structure information, from the file * self::IGNORE_EMPTY_CELLS Don't read empty cells (cells that contain a null value, * empty string, or a string containing only whitespace characters) + * self::IGNORE_ROWS_WITH_NO_CELLS Don't load any rows that contain no cells. + * self::ALLOW_EXTERNAL_IMAGES Attempt to fetch images stored outside the spreadsheet. + * self::DONT_ALLOW_EXTERNAL_IMAGES Don't attempt to fetch images stored outside the spreadsheet. + * self::CREATE_BLANK_SHEET_IF_NONE_READ If no sheets are read, create a blank one. */ public function load(string $filename, int $flags = 0): Spreadsheet; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods.php index 77e0739..d243f4d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods.php @@ -19,6 +19,7 @@ use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\File; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; @@ -139,6 +140,8 @@ class Ods extends BaseReader /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ public function listWorksheetInfo(string $filename): array { @@ -175,7 +178,7 @@ class Ods extends BaseReader $styleName = $xml->getAttribute('table:style-name') ?? ''; $visibility = $tableVisibility[$styleName] ?? ''; $tmpInfo = [ - 'worksheetName' => $xml->getAttribute('table:name'), + 'worksheetName' => (string) $xml->getAttribute('table:name'), 'lastColumnLetter' => 'A', 'lastColumnIndex' => 0, 'totalRows' => 0, @@ -189,7 +192,7 @@ class Ods extends BaseReader $xml->read(); if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) { $rowspan = $xml->getAttribute('table:number-rows-repeated'); - $rowspan = empty($rowspan) ? 1 : $rowspan; + $rowspan = empty($rowspan) ? 1 : (int) $rowspan; $tmpInfo['totalRows'] += $rowspan; $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells); $currCells = 0; @@ -229,8 +232,7 @@ class Ods extends BaseReader */ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet { - // Create new Spreadsheet - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->newSpreadsheet(); $spreadsheet->setValueBinder($this->valueBinder); $spreadsheet->removeSheetByIndex(0); @@ -258,6 +260,7 @@ class Ods extends BaseReader throw new Exception('Unable to read data from {$pFilename}'); } + /** @var array{meta?: string, office?: string, dc?: string} */ $namespacesMeta = $xml->getNamespaces(true); (new DocumentProperties($spreadsheet))->load($xml, $namespacesMeta); @@ -315,6 +318,7 @@ class Ods extends BaseReader $tables = $workbookData->getElementsByTagNameNS($tableNs, 'table'); $worksheetID = 0; + $sheetCreated = false; foreach ($tables as $worksheetDataSet) { /** @var DOMElement $worksheetDataSet */ $worksheetName = $worksheetDataSet->getAttributeNS($tableNs, 'name'); @@ -332,6 +336,7 @@ class Ods extends BaseReader // Create sheet $spreadsheet->createSheet(); + $sheetCreated = true; $spreadsheet->setActiveSheetIndex($worksheetID); if ($worksheetName || is_numeric($worksheetName)) { @@ -352,318 +357,95 @@ class Ods extends BaseReader continue; } - $key = $childNode->nodeName; - - // Remove ns from node name - if (str_contains($key, ':')) { - $keyChunks = explode(':', $key); - $key = array_pop($keyChunks); - } + $key = self::extractNodeName($childNode->nodeName); switch ($key) { case 'table-header-rows': - /// TODO :: Figure this out. This is only a partial implementation I guess. - // ($rowData it's not used at all and I'm not sure that PHPExcel - // has an API for this) + case 'table-rows': + $this->processTableHeaderRows( + $childNode, + $tableNs, + $rowID, + $worksheetName, + $officeNs, + $textNs, + $xlinkNs, + $spreadsheet + ); + + break; + case 'table-row-group': + $this->processTableRowGroup( + $childNode, + $tableNs, + $rowID, + $worksheetName, + $officeNs, + $textNs, + $xlinkNs, + $spreadsheet + ); + + break; + case 'table-header-columns': + case 'table-columns': + $this->processTableHeaderColumns( + $childNode, + $tableNs, + $columnWidths, + $tableColumnIndex, + $spreadsheet + ); + + break; + case 'table-column-group': + $this->processTableColumnGroup( + $childNode, + $tableNs, + $columnWidths, + $tableColumnIndex, + $spreadsheet + ); -// foreach ($rowData as $keyRowData => $cellData) { -// $rowData = $cellData; -// break; -// } break; case 'table-column': - if ($childNode->hasAttributeNS($tableNs, 'number-columns-repeated')) { - $rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-columns-repeated'); - } else { - $rowRepeats = 1; - } - $tableStyleName = $childNode->getAttributeNS($tableNs, 'style-name'); - if (isset($columnWidths[$tableStyleName])) { - $columnWidth = new HelperDimension($columnWidths[$tableStyleName]); - $tableColumnString = Coordinate::stringFromColumnIndex($tableColumnIndex); - for ($rowRepeats2 = $rowRepeats; $rowRepeats2 > 0; --$rowRepeats2) { - $spreadsheet->getActiveSheet() - ->getColumnDimension($tableColumnString) - ->setWidth($columnWidth->toUnit('cm'), 'cm'); - ++$tableColumnString; - } - } - $tableColumnIndex += $rowRepeats; + $this->processTableColumn( + $childNode, + $tableNs, + $columnWidths, + $tableColumnIndex, + $spreadsheet + ); break; case 'table-row': - if ($childNode->hasAttributeNS($tableNs, 'number-rows-repeated')) { - $rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated'); - } else { - $rowRepeats = 1; - } - - $columnID = 'A'; - /** @var DOMElement|DOMText $cellData */ - foreach ($childNode->childNodes as $cellData) { - if ($cellData instanceof DOMText) { - continue; // should just be whitespace - } - if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { - if ($cellData->hasAttributeNS($tableNs, 'number-columns-repeated')) { - $colRepeats = (int) $cellData->getAttributeNS($tableNs, 'number-columns-repeated'); - } else { - $colRepeats = 1; - } - - for ($i = 0; $i < $colRepeats; ++$i) { - ++$columnID; - } - - continue; - } - - // Initialize variables - $formatting = $hyperlink = null; - $hasCalculatedValue = false; - $cellDataFormula = ''; - $cellDataType = ''; - $cellDataRef = ''; - - if ($cellData->hasAttributeNS($tableNs, 'formula')) { - $cellDataFormula = $cellData->getAttributeNS($tableNs, 'formula'); - $hasCalculatedValue = true; - } - if ($cellData->hasAttributeNS($tableNs, 'number-matrix-columns-spanned')) { - if ($cellData->hasAttributeNS($tableNs, 'number-matrix-rows-spanned')) { - $cellDataType = 'array'; - $arrayRow = (int) $cellData->getAttributeNS($tableNs, 'number-matrix-rows-spanned'); - $arrayCol = (int) $cellData->getAttributeNS($tableNs, 'number-matrix-columns-spanned'); - $lastRow = $rowID + $arrayRow - 1; - $lastCol = $columnID; - while ($arrayCol > 1) { - ++$lastCol; - --$arrayCol; - } - $cellDataRef = "$columnID$rowID:$lastCol$lastRow"; - } - } - - // Annotations - $annotation = $cellData->getElementsByTagNameNS($officeNs, 'annotation'); - - if ($annotation->length > 0 && $annotation->item(0) !== null) { - $textNode = $annotation->item(0)->getElementsByTagNameNS($textNs, 'p'); - $textNodeLength = $textNode->length; - $newLineOwed = false; - for ($textNodeIndex = 0; $textNodeIndex < $textNodeLength; ++$textNodeIndex) { - $textNodeItem = $textNode->item($textNodeIndex); - if ($textNodeItem !== null) { - $text = $this->scanElementForText($textNodeItem); - if ($newLineOwed) { - $spreadsheet->getActiveSheet() - ->getComment($columnID . $rowID) - ->getText() - ->createText("\n"); - } - $newLineOwed = true; - - $spreadsheet->getActiveSheet() - ->getComment($columnID . $rowID) - ->getText() - ->createText($this->parseRichText($text)); - } - } - } - - // Content - - /** @var DOMElement[] $paragraphs */ - $paragraphs = []; - - foreach ($cellData->childNodes as $item) { - /** @var DOMElement $item */ - - // Filter text:p elements - if ($item->nodeName == 'text:p') { - $paragraphs[] = $item; - } - } - - if (count($paragraphs) > 0) { - // Consolidate if there are multiple p records (maybe with spans as well) - $dataArray = []; - - // Text can have multiple text:p and within those, multiple text:span. - // text:p newlines, but text:span does not. - // Also, here we assume there is no text data is span fields are specified, since - // we have no way of knowing proper positioning anyway. - - foreach ($paragraphs as $pData) { - $dataArray[] = $this->scanElementForText($pData); - } - $allCellDataText = implode("\n", $dataArray); - - $type = $cellData->getAttributeNS($officeNs, 'value-type'); - - switch ($type) { - case 'string': - $type = DataType::TYPE_STRING; - $dataValue = $allCellDataText; - - foreach ($paragraphs as $paragraph) { - $link = $paragraph->getElementsByTagNameNS($textNs, 'a'); - if ($link->length > 0 && $link->item(0) !== null) { - $hyperlink = $link->item(0)->getAttributeNS($xlinkNs, 'href'); - } - } - - break; - case 'boolean': - $type = DataType::TYPE_BOOL; - $dataValue = ($cellData->getAttributeNS($officeNs, 'boolean-value') === 'true') ? true : false; - - break; - case 'percentage': - $type = DataType::TYPE_NUMERIC; - $dataValue = (float) $cellData->getAttributeNS($officeNs, 'value'); - - // percentage should always be float - //if (floor($dataValue) == $dataValue) { - // $dataValue = (int) $dataValue; - //} - $formatting = NumberFormat::FORMAT_PERCENTAGE_00; - - break; - case 'currency': - $type = DataType::TYPE_NUMERIC; - $dataValue = (float) $cellData->getAttributeNS($officeNs, 'value'); - - if (floor($dataValue) == $dataValue) { - $dataValue = (int) $dataValue; - } - $formatting = NumberFormat::FORMAT_CURRENCY_USD_INTEGER; - - break; - case 'float': - $type = DataType::TYPE_NUMERIC; - $dataValue = (float) $cellData->getAttributeNS($officeNs, 'value'); - - if (floor($dataValue) == $dataValue) { - if ($dataValue == (int) $dataValue) { - $dataValue = (int) $dataValue; - } - } - - break; - case 'date': - $type = DataType::TYPE_NUMERIC; - $value = $cellData->getAttributeNS($officeNs, 'date-value'); - $dataValue = Date::convertIsoDate($value); - - if ($dataValue != floor($dataValue)) { - $formatting = NumberFormat::FORMAT_DATE_XLSX15 - . ' ' - . NumberFormat::FORMAT_DATE_TIME4; - } else { - $formatting = NumberFormat::FORMAT_DATE_XLSX15; - } - - break; - case 'time': - $type = DataType::TYPE_NUMERIC; - - $timeValue = $cellData->getAttributeNS($officeNs, 'time-value'); - - $dataValue = Date::PHPToExcel( - strtotime( - '01-01-1970 ' . implode(':', sscanf($timeValue, 'PT%dH%dM%dS') ?? []) - ) - ); - $formatting = NumberFormat::FORMAT_DATE_TIME4; - - break; - default: - $dataValue = null; - } - } else { - $type = DataType::TYPE_NULL; - $dataValue = null; - } - - if ($hasCalculatedValue) { - $type = DataType::TYPE_FORMULA; - $cellDataFormula = substr($cellDataFormula, strpos($cellDataFormula, ':=') + 1); - $cellDataFormula = FormulaTranslator::convertToExcelFormulaValue($cellDataFormula); - } - - if ($cellData->hasAttributeNS($tableNs, 'number-columns-repeated')) { - $colRepeats = (int) $cellData->getAttributeNS($tableNs, 'number-columns-repeated'); - } else { - $colRepeats = 1; - } - - if ($type !== null) { // @phpstan-ignore-line - for ($i = 0; $i < $colRepeats; ++$i) { - if ($i > 0) { - ++$columnID; - } - - if ($type !== DataType::TYPE_NULL) { - for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) { - $rID = $rowID + $rowAdjust; - - $cell = $spreadsheet->getActiveSheet() - ->getCell($columnID . $rID); - - // Set value - if ($hasCalculatedValue) { - $cell->setValueExplicit($cellDataFormula, $type); - if ($cellDataType === 'array') { - $cell->setFormulaAttributes(['t' => 'array', 'ref' => $cellDataRef]); - } - } else { - $cell->setValueExplicit($dataValue, $type); - } - - if ($hasCalculatedValue) { - $cell->setCalculatedValue($dataValue, $type === DataType::TYPE_NUMERIC); - } - - // Set other properties - if ($formatting !== null) { - $spreadsheet->getActiveSheet() - ->getStyle($columnID . $rID) - ->getNumberFormat() - ->setFormatCode($formatting); - } else { - $spreadsheet->getActiveSheet() - ->getStyle($columnID . $rID) - ->getNumberFormat() - ->setFormatCode(NumberFormat::FORMAT_GENERAL); - } - - if ($hyperlink !== null) { - if ($hyperlink[0] === '#') { - $hyperlink = 'sheet://' . substr($hyperlink, 1); - } - $cell->getHyperlink() - ->setUrl($hyperlink); - } - } - } - } - } - - // Merged cells - $this->processMergedCells($cellData, $tableNs, $type, $columnID, $rowID, $spreadsheet); - - ++$columnID; - } - $rowID += $rowRepeats; + $this->processTableRow( + $childNode, + $tableNs, + $rowID, + $worksheetName, + $officeNs, + $textNs, + $xlinkNs, + $spreadsheet + ); break; } } - $pageSettings->setVisibilityForWorksheet($spreadsheet->getActiveSheet(), $worksheetStyleName); - $pageSettings->setPrintSettingsForWorksheet($spreadsheet->getActiveSheet(), $worksheetStyleName); + $pageSettings->setVisibilityForWorksheet( + $spreadsheet->getActiveSheet(), + $worksheetStyleName + ); + $pageSettings->setPrintSettingsForWorksheet( + $spreadsheet->getActiveSheet(), + $worksheetStyleName + ); ++$worksheetID; } + if ($this->createBlankSheetIfNoneRead && !$sheetCreated) { + $spreadsheet->createSheet(); + } $autoFilterReader->read($workbookData); $definedNameReader->read($workbookData); @@ -678,6 +460,491 @@ class Ods extends BaseReader return $spreadsheet; } + private function processTableHeaderRows( + DOMElement $childNode, + string $tableNs, + int &$rowID, + string $worksheetName, + string $officeNs, + string $textNs, + string $xlinkNs, + Spreadsheet $spreadsheet + ): void { + foreach ($childNode->childNodes as $grandchildNode) { + /** @var DOMElement $grandchildNode */ + $grandkey = self::extractNodeName($grandchildNode->nodeName); + switch ($grandkey) { + case 'table-row': + $this->processTableRow( + $grandchildNode, + $tableNs, + $rowID, + $worksheetName, + $officeNs, + $textNs, + $xlinkNs, + $spreadsheet + ); + + break; + } + } + } + + private function processTableRowGroup( + DOMElement $childNode, + string $tableNs, + int &$rowID, + string $worksheetName, + string $officeNs, + string $textNs, + string $xlinkNs, + Spreadsheet $spreadsheet + ): void { + foreach ($childNode->childNodes as $grandchildNode) { + /** @var DOMElement $grandchildNode */ + $grandkey = self::extractNodeName($grandchildNode->nodeName); + switch ($grandkey) { + case 'table-row': + $this->processTableRow( + $grandchildNode, + $tableNs, + $rowID, + $worksheetName, + $officeNs, + $textNs, + $xlinkNs, + $spreadsheet + ); + + break; + case 'table-header-rows': + case 'table-rows': + $this->processTableHeaderRows( + $grandchildNode, + $tableNs, + $rowID, + $worksheetName, + $officeNs, + $textNs, + $xlinkNs, + $spreadsheet + ); + + break; + case 'table-row-group': + $this->processTableRowGroup( + $grandchildNode, + $tableNs, + $rowID, + $worksheetName, + $officeNs, + $textNs, + $xlinkNs, + $spreadsheet + ); + + break; + } + } + } + + private function processTableRow( + DOMElement $childNode, + string $tableNs, + int &$rowID, + string $worksheetName, + string $officeNs, + string $textNs, + string $xlinkNs, + Spreadsheet $spreadsheet + ): void { + if ($childNode->hasAttributeNS($tableNs, 'number-rows-repeated')) { + $rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated'); + } else { + $rowRepeats = 1; + } + + $columnID = 'A'; + /** @var DOMElement|DOMText $cellData */ + foreach ($childNode->childNodes as $cellData) { + if ($cellData instanceof DOMText) { + continue; // should just be whitespace + } + if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { + if ($cellData->hasAttributeNS($tableNs, 'number-columns-repeated')) { + $colRepeats = (int) $cellData->getAttributeNS($tableNs, 'number-columns-repeated'); + } else { + $colRepeats = 1; + } + + for ($i = 0; $i < $colRepeats; ++$i) { + StringHelper::stringIncrement($columnID); + } + + continue; + } + + // Initialize variables + $formatting = $hyperlink = null; + $hasCalculatedValue = false; + $cellDataFormula = ''; + $cellDataType = ''; + $cellDataRef = ''; + + if ($cellData->hasAttributeNS($tableNs, 'formula')) { + $cellDataFormula = $cellData->getAttributeNS($tableNs, 'formula'); + $hasCalculatedValue = true; + } + if ($cellData->hasAttributeNS($tableNs, 'number-matrix-columns-spanned')) { + if ($cellData->hasAttributeNS($tableNs, 'number-matrix-rows-spanned')) { + $cellDataType = 'array'; + $arrayRow = (int) $cellData->getAttributeNS($tableNs, 'number-matrix-rows-spanned'); + $arrayCol = (int) $cellData->getAttributeNS($tableNs, 'number-matrix-columns-spanned'); + $lastRow = $rowID + $arrayRow - 1; + $lastCol = $columnID; + while ($arrayCol > 1) { + StringHelper::stringIncrement($lastCol); + --$arrayCol; + } + $cellDataRef = "$columnID$rowID:$lastCol$lastRow"; + } + } + + // Annotations + $annotation = $cellData->getElementsByTagNameNS($officeNs, 'annotation'); + + if ($annotation->length > 0 && $annotation->item(0) !== null) { + $textNode = $annotation->item(0)->getElementsByTagNameNS($textNs, 'p'); + $textNodeLength = $textNode->length; + $newLineOwed = false; + for ($textNodeIndex = 0; $textNodeIndex < $textNodeLength; ++$textNodeIndex) { + $textNodeItem = $textNode->item($textNodeIndex); + if ($textNodeItem !== null) { + $text = $this->scanElementForText($textNodeItem); + if ($newLineOwed) { + $spreadsheet->getActiveSheet() + ->getComment($columnID . $rowID) + ->getText() + ->createText("\n"); + } + $newLineOwed = true; + + $spreadsheet->getActiveSheet() + ->getComment($columnID . $rowID) + ->getText() + ->createText( + $this->parseRichText($text) + ); + } + } + } + + // Content + + /** @var DOMElement[] $paragraphs */ + $paragraphs = []; + + foreach ($cellData->childNodes as $item) { + /** @var DOMElement $item */ + + // Filter text:p elements + if ($item->nodeName == 'text:p') { + $paragraphs[] = $item; + } + } + + if (count($paragraphs) > 0) { + // Consolidate if there are multiple p records (maybe with spans as well) + $dataArray = []; + + // Text can have multiple text:p and within those, multiple text:span. + // text:p newlines, but text:span does not. + // Also, here we assume there is no text data is span fields are specified, since + // we have no way of knowing proper positioning anyway. + + foreach ($paragraphs as $pData) { + $dataArray[] = $this->scanElementForText($pData); + } + $allCellDataText = implode("\n", $dataArray); + + $type = $cellData->getAttributeNS($officeNs, 'value-type'); + + switch ($type) { + case 'string': + $type = DataType::TYPE_STRING; + $dataValue = $allCellDataText; + + foreach ($paragraphs as $paragraph) { + $link = $paragraph->getElementsByTagNameNS($textNs, 'a'); + if ($link->length > 0 && $link->item(0) !== null) { + $hyperlink = $link->item(0)->getAttributeNS($xlinkNs, 'href'); + } + } + + break; + case 'boolean': + $type = DataType::TYPE_BOOL; + $dataValue = ($cellData->getAttributeNS($officeNs, 'boolean-value') === 'true') ? true : false; + + break; + case 'percentage': + $type = DataType::TYPE_NUMERIC; + $dataValue = (float) $cellData->getAttributeNS($officeNs, 'value'); + + // percentage should always be float + //if (floor($dataValue) == $dataValue) { + // $dataValue = (int) $dataValue; + //} + $formatting = NumberFormat::FORMAT_PERCENTAGE_00; + + break; + case 'currency': + $type = DataType::TYPE_NUMERIC; + $dataValue = (float) $cellData->getAttributeNS($officeNs, 'value'); + + if (floor($dataValue) == $dataValue) { + $dataValue = (int) $dataValue; + } + $formatting = NumberFormat::FORMAT_CURRENCY_USD_INTEGER; + + break; + case 'float': + $type = DataType::TYPE_NUMERIC; + $dataValue = (float) $cellData->getAttributeNS($officeNs, 'value'); + + if (floor($dataValue) == $dataValue) { + if ($dataValue == (int) $dataValue) { + $dataValue = (int) $dataValue; + } + } + + break; + case 'date': + $type = DataType::TYPE_NUMERIC; + $value = $cellData->getAttributeNS($officeNs, 'date-value'); + $dataValue = Date::convertIsoDate($value); + + if ($dataValue != floor($dataValue)) { + $formatting = NumberFormat::FORMAT_DATE_XLSX15 + . ' ' + . NumberFormat::FORMAT_DATE_TIME4; + } else { + $formatting = NumberFormat::FORMAT_DATE_XLSX15; + } + + break; + case 'time': + $type = DataType::TYPE_NUMERIC; + + $timeValue = $cellData->getAttributeNS($officeNs, 'time-value'); + + $dataValue = Date::PHPToExcel( + strtotime( + '01-01-1970 ' . implode(':', sscanf($timeValue, 'PT%dH%dM%dS') ?? []) + ) + ); + $formatting = NumberFormat::FORMAT_DATE_TIME4; + + break; + default: + $dataValue = null; + } + } else { + $type = DataType::TYPE_NULL; + $dataValue = null; + } + + if ($hasCalculatedValue) { + $type = DataType::TYPE_FORMULA; + $cellDataFormula = substr($cellDataFormula, strpos($cellDataFormula, ':=') + 1); + $cellDataFormula = FormulaTranslator::convertToExcelFormulaValue($cellDataFormula); + } + + if ($cellData->hasAttributeNS($tableNs, 'number-columns-repeated')) { + $colRepeats = (int) $cellData->getAttributeNS($tableNs, 'number-columns-repeated'); + } else { + $colRepeats = 1; + } + + if ($type !== null) { // @phpstan-ignore-line + for ($i = 0; $i < $colRepeats; ++$i) { + if ($i > 0) { + StringHelper::stringIncrement($columnID); + } + + if ($type !== DataType::TYPE_NULL) { + for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) { + $rID = $rowID + $rowAdjust; + + $cell = $spreadsheet->getActiveSheet() + ->getCell($columnID . $rID); + + // Set value + if ($hasCalculatedValue) { + $cell->setValueExplicit($cellDataFormula, $type); + if ($cellDataType === 'array') { + $cell->setFormulaAttributes(['t' => 'array', 'ref' => $cellDataRef]); + } + } elseif ($type !== '' || $dataValue !== null) { + $cell->setValueExplicit($dataValue, $type); + } + + if ($hasCalculatedValue) { + $cell->setCalculatedValue($dataValue, $type === DataType::TYPE_NUMERIC); + } + + // Set other properties + if ($formatting !== null) { + $spreadsheet->getActiveSheet() + ->getStyle($columnID . $rID) + ->getNumberFormat() + ->setFormatCode($formatting); + } else { + $spreadsheet->getActiveSheet() + ->getStyle($columnID . $rID) + ->getNumberFormat() + ->setFormatCode(NumberFormat::FORMAT_GENERAL); + } + + if ($hyperlink !== null) { + if ($hyperlink[0] === '#') { + $hyperlink = 'sheet://' . substr($hyperlink, 1); + } + $cell->getHyperlink() + ->setUrl($hyperlink); + } + } + } + } + } + + // Merged cells + $this->processMergedCells($cellData, $tableNs, $type, $columnID, $rowID, $spreadsheet); + + StringHelper::stringIncrement($columnID); + } + $rowID += $rowRepeats; + } + + private static function extractNodeName(string $key): string + { + // Remove ns from node name + if (str_contains($key, ':')) { + $keyChunks = explode(':', $key); + $key = array_pop($keyChunks); + } + + return $key; + } + + /** + * @param string[] $columnWidths + */ + private function processTableHeaderColumns( + DOMElement $childNode, + string $tableNs, + array $columnWidths, + int &$tableColumnIndex, + Spreadsheet $spreadsheet + ): void { + foreach ($childNode->childNodes as $grandchildNode) { + /** @var DOMElement $grandchildNode */ + $grandkey = self::extractNodeName($grandchildNode->nodeName); + switch ($grandkey) { + case 'table-column': + $this->processTableColumn( + $grandchildNode, + $tableNs, + $columnWidths, + $tableColumnIndex, + $spreadsheet + ); + + break; + } + } + } + + /** + * @param string[] $columnWidths + */ + private function processTableColumnGroup( + DOMElement $childNode, + string $tableNs, + array $columnWidths, + int &$tableColumnIndex, + Spreadsheet $spreadsheet + ): void { + foreach ($childNode->childNodes as $grandchildNode) { + /** @var DOMElement $grandchildNode */ + $grandkey = self::extractNodeName($grandchildNode->nodeName); + switch ($grandkey) { + case 'table-column': + $this->processTableColumn( + $grandchildNode, + $tableNs, + $columnWidths, + $tableColumnIndex, + $spreadsheet + ); + + break; + case 'table-header-columns': + case 'table-columns': + $this->processTableHeaderColumns( + $grandchildNode, + $tableNs, + $columnWidths, + $tableColumnIndex, + $spreadsheet + ); + + break; + case 'table-column-group': + $this->processTableColumnGroup( + $grandchildNode, + $tableNs, + $columnWidths, + $tableColumnIndex, + $spreadsheet + ); + + break; + } + } + } + + /** + * @param string[] $columnWidths + */ + private function processTableColumn( + DOMElement $childNode, + string $tableNs, + array $columnWidths, + int &$tableColumnIndex, + Spreadsheet $spreadsheet + ): void { + if ($childNode->hasAttributeNS($tableNs, 'number-columns-repeated')) { + $rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-columns-repeated'); + } else { + $rowRepeats = 1; + } + $tableStyleName = $childNode->getAttributeNS($tableNs, 'style-name'); + if (isset($columnWidths[$tableStyleName])) { + $columnWidth = new HelperDimension($columnWidths[$tableStyleName]); + $tableColumnString = Coordinate::stringFromColumnIndex($tableColumnIndex); + for ($rowRepeats2 = $rowRepeats; $rowRepeats2 > 0; --$rowRepeats2) { + /** @var string $tableColumnString */ + $spreadsheet->getActiveSheet() + ->getColumnDimension($tableColumnString) + ->setWidth($columnWidth->toUnit('cm'), 'cm'); + StringHelper::stringIncrement($tableColumnString); + } + } + $tableColumnIndex += $rowRepeats; + } + private function processSettings(ZipArchive $zip, Spreadsheet $spreadsheet): void { $dom = new DOMDocument('1.01', 'UTF-8'); @@ -685,9 +952,7 @@ class Ods extends BaseReader $this->getSecurityScannerOrThrow() ->scan($zip->getFromName('settings.xml')) ); - //$xlinkNs = $dom->lookupNamespaceUri('xlink'); $configNs = (string) $dom->lookupNamespaceUri('config'); - //$oooNs = $dom->lookupNamespaceUri('ooo'); $officeNs = (string) $dom->lookupNamespaceUri('office'); $settings = $dom->getElementsByTagNameNS($officeNs, 'settings') ->item(0); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods/FormulaTranslator.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods/FormulaTranslator.php index 123f909..032c04a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods/FormulaTranslator.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods/FormulaTranslator.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Ods; +use Composer\Pcre\Preg; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; class FormulaTranslator @@ -27,7 +28,7 @@ class FormulaTranslator // Cell range 3-d reference // As we don't support 3-d ranges, we're just going to take a quick and dirty approach // and assume that the second worksheet reference is the same as the first - $excelAddress = (string) preg_replace( + $excelAddress = Preg::replace( [ '/\$?([^\.]+)\.([^\.]+):\$?([^\.]+)\.([^\.]+)/miu', '/\$?([^\.]+)\.([^\.]+):\.([^\.]+)/miu', // Cell range reference in another sheet @@ -62,7 +63,7 @@ class FormulaTranslator // so that conversion isn't done in string values $tKey = $tKey === false; if ($tKey) { - $value = (string) preg_replace( + $value = Preg::replace( [ '/\[\$?([^\.]+)\.([^\.]+):\.([^\.]+)\]/miu', // Cell range reference in another sheet '/\[\$?([^\.]+)\.([^\.]+)\]/miu', // Cell reference in another sheet @@ -103,7 +104,18 @@ class FormulaTranslator Calculation::FORMULA_CLOSE_MATRIX_BRACE ); - $value = (string) preg_replace('/COM\.MICROSOFT\./ui', '', $value); + $value = Preg::replace( + [ + '/\b(?pageLayoutStyles)) { return; } + /** @var (object{orientation: string, scale: int|string, printOrder: ?string, + * horizontalCentered: bool, verticalCentered: bool, marginLeft: float, marginRight: float, marginTop: float, + * marginBottom: float, marginHeader: float, marginFooter: float}&stdClass) */ $printSettings = $this->pageLayoutStyles[$printSettingsIndex]; $worksheet->getPageSetup() ->setOrientation($printSettings->orientation ?? PageSetup::ORIENTATION_DEFAULT) ->setPageOrder($printSettings->printOrder === 'ltr' ? PageSetup::PAGEORDER_OVER_THEN_DOWN : PageSetup::PAGEORDER_DOWN_THEN_OVER) - ->setScale((int) trim($printSettings->scale, '%')) + ->setScale((int) trim((string) $printSettings->scale, '%')) ->setHorizontalCentered($printSettings->horizontalCentered) ->setVerticalCentered($printSettings->verticalCentered); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods/Properties.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods/Properties.php index a5f0c79..4dada28 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods/Properties.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods/Properties.php @@ -15,10 +15,11 @@ class Properties $this->spreadsheet = $spreadsheet; } + /** @param array{meta?: string, office?: string, dc?: string} $namespacesMeta */ public function load(SimpleXMLElement $xml, array $namespacesMeta): void { $docProps = $this->spreadsheet->getProperties(); - $officeProperty = $xml->children($namespacesMeta['office']); + $officeProperty = $xml->children($namespacesMeta['office'] ?? ''); foreach ($officeProperty as $officePropertyData) { if (isset($namespacesMeta['dc'])) { $officePropertiesDC = $officePropertyData->children($namespacesMeta['dc']); @@ -27,7 +28,7 @@ class Properties $officePropertyMeta = null; if (isset($namespacesMeta['dc'])) { - $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); + $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta'] ?? ''); } $officePropertyMeta = $officePropertyMeta ?? []; foreach ($officePropertyMeta as $propertyName => $propertyValue) { @@ -66,13 +67,14 @@ class Properties } } + /** @param array{meta?: string, office?: mixed, dc?: mixed} $namespacesMeta */ private function setMetaProperties( array $namespacesMeta, SimpleXMLElement $propertyValue, string $propertyName, DocumentProperties $docProps ): void { - $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']); + $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta'] ?? ''); $propertyValue = (string) $propertyValue; switch ($propertyName) { case 'initial-creator': @@ -101,14 +103,17 @@ class Properties } } + /** @param iterable $propertyValueAttributes */ private function setUserDefinedProperty(iterable $propertyValueAttributes, string $propertyValue, DocumentProperties $docProps): void { $propertyValueName = ''; $propertyValueType = DocumentProperties::PROPERTY_TYPE_STRING; foreach ($propertyValueAttributes as $key => $value) { if ($key == 'name') { + /** @var scalar $value */ $propertyValueName = (string) $value; } elseif ($key == 'value-type') { + /** @var string $value */ switch ($value) { case 'date': $propertyValue = DocumentProperties::convertProperty($propertyValue, 'date'); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Security/XmlScanner.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Security/XmlScanner.php index 6d4ed44..e4da44f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Security/XmlScanner.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Security/XmlScanner.php @@ -102,6 +102,7 @@ class XmlScanner if ($this->callback !== null) { $xml = call_user_func($this->callback, $xml); } + /** @var string $xml */ return $xml; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Slk.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Slk.php index 10995c5..73d3738 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Slk.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Slk.php @@ -21,6 +21,8 @@ class Slk extends BaseReader /** * Formats. + * + * @var mixed[] */ private array $formats = []; @@ -31,6 +33,8 @@ class Slk extends BaseReader /** * Fonts. + * + * @var mixed[] */ private array $fonts = []; @@ -84,6 +88,8 @@ class Slk extends BaseReader /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ public function listWorksheetInfo(string $filename): array { @@ -92,8 +98,7 @@ class Slk extends BaseReader $fileHandle = $this->fileHandle; rewind($fileHandle); - $worksheetInfo = []; - $worksheetInfo[0]['worksheetName'] = basename($filename, '.slk'); + $worksheetInfo = [['worksheetName' => basename($filename, '.slk')]]; // loop through one row (line) at a time in the file $rowIndex = 0; @@ -144,8 +149,7 @@ class Slk extends BaseReader */ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet { - // Create new Spreadsheet - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->newSpreadsheet(); $spreadsheet->setValueBinder($this->valueBinder); // Load into this instance @@ -169,6 +173,9 @@ class Slk extends BaseReader 'U' => 'underline', ]; + /** + * @param-out true $hasCalculatedValue + */ private function processFormula(string $rowDatum, bool &$hasCalculatedValue, string &$cellDataFormula, string $row, string $column): void { $cellDataFormula = '=' . substr($rowDatum, 1); @@ -217,6 +224,7 @@ class Slk extends BaseReader $hasCalculatedValue = true; } + /** @param mixed[] $rowData */ private function processCRecord(array $rowData, Spreadsheet &$spreadsheet, string &$row, string &$column): void { // Read cell value data @@ -226,6 +234,7 @@ class Slk extends BaseReader $sharedColumn = $sharedRow = -1; $sharedFormula = false; foreach ($rowData as $rowDatum) { + /** @var string $rowDatum */ switch ($rowDatum[0]) { case 'X': $column = substr($rowDatum, 1); @@ -301,6 +310,7 @@ class Slk extends BaseReader } } + /** @param mixed[] $rowData */ private function processFRecord(array $rowData, Spreadsheet &$spreadsheet, string &$row, string &$column): void { // Read cell formatting @@ -309,6 +319,7 @@ class Slk extends BaseReader $fontStyle = ''; $styleData = []; foreach ($rowData as $rowDatum) { + /** @var string $rowDatum */ switch ($rowDatum[0]) { case 'C': case 'X': @@ -334,6 +345,7 @@ class Slk extends BaseReader break; } } + /** @var string $formatStyle */ $this->addFormats($spreadsheet, $formatStyle, $row, $column); $this->addFonts($spreadsheet, $fontStyle, $row, $column); $this->addStyle($spreadsheet, $styleData, $row, $column); @@ -349,6 +361,7 @@ class Slk extends BaseReader 'T' => 'top', ]; + /** @param mixed[][] $styleData */ private function styleSettings(string $rowDatum, array &$styleData, string &$fontStyle): void { $styleSettings = substr($rowDatum, 1); @@ -358,7 +371,7 @@ class Slk extends BaseReader if (array_key_exists($char, self::STYLE_SETTINGS_FONT)) { $styleData['font'][self::STYLE_SETTINGS_FONT[$char]] = true; } elseif (array_key_exists($char, self::STYLE_SETTINGS_BORDER)) { - $styleData['borders'][self::STYLE_SETTINGS_BORDER[$char]]['borderStyle'] = Border::BORDER_THIN; + $styleData['borders'][self::STYLE_SETTINGS_BORDER[$char]]['borderStyle'] = Border::BORDER_THIN; //* @phpstan-ignore-line } elseif ($char == 'S') { $styleData['fill']['fillType'] = Fill::FILL_PATTERN_GRAY125; } elseif ($char == 'M') { @@ -373,7 +386,7 @@ class Slk extends BaseReader { if ($formatStyle && $column > '' && $row > '') { $columnLetter = Coordinate::stringFromColumnIndex((int) $column); - if (isset($this->formats[$formatStyle])) { + if (isset($this->formats[$formatStyle]) && is_array($this->formats[$formatStyle])) { $spreadsheet->getActiveSheet()->getStyle($columnLetter . $row)->applyFromArray($this->formats[$formatStyle]); } } @@ -383,12 +396,13 @@ class Slk extends BaseReader { if ($fontStyle && $column > '' && $row > '') { $columnLetter = Coordinate::stringFromColumnIndex((int) $column); - if (isset($this->fonts[$fontStyle])) { + if (isset($this->fonts[$fontStyle]) && is_array($this->fonts[$fontStyle])) { $spreadsheet->getActiveSheet()->getStyle($columnLetter . $row)->applyFromArray($this->fonts[$fontStyle]); } } } + /** @param mixed[] $styleData */ private function addStyle(Spreadsheet &$spreadsheet, array $styleData, string $row, string $column): void { if ((!empty($styleData)) && $column > '' && $row > '') { @@ -408,13 +422,18 @@ class Slk extends BaseReader $endCol = Coordinate::stringFromColumnIndex((int) $endCol); $spreadsheet->getActiveSheet()->getColumnDimension($startCol)->setWidth((float) $columnWidth); do { - // ++$startCol below tricks Phpstan into thinking it's float/int - $spreadsheet->getActiveSheet()->getColumnDimension((string) ++$startCol)->setWidth((float) $columnWidth); - } while ($startCol !== $endCol); // @phpstan-ignore-line + /** @var string $startCol */ + $spreadsheet->getActiveSheet() + ->getColumnDimension( + StringHelper::stringIncrement($startCol) + ) + ->setWidth((float) $columnWidth); + } while ($startCol !== $endCol); } } } + /** @param string[] $rowData */ private function processPRecord(array $rowData, Spreadsheet &$spreadsheet): void { // Read shared styles @@ -437,6 +456,7 @@ class Slk extends BaseReader break; case 'L': + /** @var mixed[][][] $formatArray */ $this->processPColors($rowDatum, $formatArray); break; @@ -449,6 +469,7 @@ class Slk extends BaseReader $this->processPFinal($spreadsheet, $formatArray); } + /** @param mixed[][][] $formatArray */ private function processPColors(string $rowDatum, array &$formatArray): void { if (preg_match('/L([1-9]\d*)/', $rowDatum, $matches)) { @@ -457,6 +478,7 @@ class Slk extends BaseReader } } + /** @param mixed[][] $formatArray */ private function processPFontStyles(string $rowDatum, array &$formatArray): void { $styleSettings = substr($rowDatum, 1); @@ -468,6 +490,7 @@ class Slk extends BaseReader } } + /** @param mixed[] $formatArray */ private function processPFinal(Spreadsheet &$spreadsheet, array $formatArray): void { if (array_key_exists('numberFormat', $formatArray)) { @@ -533,6 +556,7 @@ class Slk extends BaseReader return $spreadsheet; } + /** @param string[] $rowData */ private function columnRowFromRowData(array $rowData, string &$column, string &$row): void { foreach ($rowData as $rowDatum) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls.php index 7da2082..09a2b77 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls.php @@ -104,6 +104,8 @@ class Xls extends XlsBase /** * Shared formats. + * + * @var mixed[] */ protected array $formats; @@ -116,36 +118,50 @@ class Xls extends XlsBase /** * Color palette. + * + * @var string[][] */ protected array $palette; /** * Worksheets. + * + * @var array */ protected array $sheets; /** * External books. + * + * @var mixed[][] */ protected array $externalBooks; /** * REF structures. Only applies to BIFF8. + * + * @var array */ protected array $ref; /** * External names. + * + * @var array|string> */ protected array $externalNames; /** * Defined names. + * + * @var array{isBuiltInName: int, name: string, formula: string, scope: int} */ protected array $definedname; /** * Shared strings. Only applies to BIFF8. + * + * @var array */ protected array $sst; @@ -161,16 +177,22 @@ class Xls extends XlsBase /** * Objects. One OBJ record contributes with one entry. + * + * @var mixed[] */ protected array $objs; /** * Text Objects. One TXO record corresponds with one entry. + * + * @var array */ protected array $textObjects; /** * Cell Annotations (BIFF8). + * + * @var mixed[] */ protected array $cellNotes; @@ -191,22 +213,30 @@ class Xls extends XlsBase /** * Mapping of XF index (that is a cell XF) to final index in cellXf collection. + * + * @var int[] */ protected array $mapCellXfIndex; /** * Mapping of XF index (that is a style XF) to final index in cellStyleXf collection. + * + * @var int[] */ protected array $mapCellStyleXfIndex; /** * The shared formulas in a sheet. One SHAREDFMLA record contributes with one value. + * + * @var mixed[] */ protected array $sharedFormulas; /** * The shared formula parts in a sheet. One FORMULA record contributes with one value if it * refers to a shared formula. + * + * @var mixed[] */ protected array $sharedFormulaParts; @@ -220,6 +250,8 @@ class Xls extends XlsBase */ protected int $encryptionStartPos = 0; + protected string $encryptionPassword = 'VelvetSweatshop'; + /** * The current RC4 decryption object. */ @@ -232,7 +264,7 @@ class Xls extends XlsBase /** * The current MD5 context state. - * It is never set in the program, so code which uses it is suspect. + * It is set via call-by-reference to verifyPassword. */ private string $md5Ctxt = ''; @@ -244,6 +276,8 @@ class Xls extends XlsBase /** * Reads names of the worksheets from a file, without parsing the whole file to a PhpSpreadsheet object. + * + * @return string[] */ public function listWorksheetNames(string $filename): array { @@ -252,12 +286,24 @@ class Xls extends XlsBase /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ public function listWorksheetInfo(string $filename): array { return (new Xls\ListFunctions())->listWorksheetInfo2($filename, $this); } + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array + */ + public function listWorksheetDimensions(string $filename): array + { + return (new Xls\ListFunctions())->listWorksheetDimensions2($filename, $this); + } + /** * Loads PhpSpreadsheet from file. */ @@ -717,10 +763,18 @@ class Xls extends XlsBase $cbRuns = self::getUInt2d($recordData, 12); $text = $this->getSplicedRecordData(); - $textByte = $text['spliceOffsets'][1] - $text['spliceOffsets'][0] - 1; - $textStr = substr($text['recordData'], $text['spliceOffsets'][0] + 1, $textByte); + /** @var int[] */ + $tempSplice = $text['spliceOffsets']; + /** @var int */ + $temp = $tempSplice[0]; + /** @var int */ + $temp1 = $tempSplice[1]; + $textByte = $temp1 - $temp - 1; + /** @var string */ + $textRecordData = $text['recordData']; + $textStr = substr($textRecordData, $temp + 1, $textByte); // get 1 byte - $is16Bit = ord($text['recordData'][0]); + $is16Bit = ord($textRecordData[0]); // it is possible to use a compressed format, // which omits the high bytes of all characters, if they are all zero if (($is16Bit & 0x01) === 0) { @@ -731,7 +785,7 @@ class Xls extends XlsBase $this->textObjects[$this->textObjRef] = [ 'text' => $textStr, - 'format' => substr($text['recordData'], $text['spliceOffsets'][1], $cbRuns), + 'format' => substr($textRecordData, $tempSplice[1], $cbRuns), 'alignment' => $grbitOpts, 'rotation' => $rot, ]; @@ -776,6 +830,13 @@ class Xls extends XlsBase } } + public function setEncryptionPassword(string $encryptionPassword): self + { + $this->encryptionPassword = $encryptionPassword; + + return $this; + } + /** * FILEPASS. * @@ -795,7 +856,7 @@ class Xls extends XlsBase { $length = self::getUInt2d($this->data, $this->pos + 2); - if ($length != 54) { + if ($length < 54) { throw new Exception('Unexpected file pass record length'); } @@ -804,7 +865,10 @@ class Xls extends XlsBase // move stream pointer to next record $this->pos += 4 + $length; - if (!$this->verifyPassword('VelvetSweatshop', substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->md5Ctxt)) { + if (substr($recordData, 0, 2) !== "\x01\x00" || substr($recordData, 4, 2) !== "\x01\x00") { + throw new Exception('Unsupported encryption algorithm'); + } + if (!$this->verifyPassword($this->encryptionPassword, substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->md5Ctxt)) { throw new Exception('Decryption password incorrect'); } @@ -1042,6 +1106,7 @@ class Xls extends XlsBase } else { $string = $this->readByteStringShort(substr($recordData, 14)); } + /** @var string[] $string */ $objFont->setName($string['value']); $this->objFonts[] = $objFont; @@ -1138,7 +1203,9 @@ class Xls extends XlsBase // we set the general format code $numberFormat = ['formatCode' => NumberFormat::FORMAT_GENERAL]; } - $objStyle->getNumberFormat()->setFormatCode($numberFormat['formatCode']); + /** @var string[] $numberFormat */ + $objStyle->getNumberFormat() + ->setFormatCode($numberFormat['formatCode']); // offset: 4; size: 2; XF type, cell protection, and parent style XF // bit 2-0; mask 0x0007; XF_TYPE_PROT @@ -1197,6 +1264,8 @@ class Xls extends XlsBase break; } + $readOrder = (0xC0 & ord($recordData[8])) >> 6; + $objStyle->getAlignment()->setReadOrder($readOrder); // offset: 9; size: 1; Flags used for attribute groups @@ -1628,7 +1697,7 @@ class Xls extends XlsBase $string = $this->readByteStringShort(substr($recordData, 6)); $rec_name = $string['value']; } - + /** @var string $rec_name */ $this->sheets[] = [ 'name' => $rec_name, 'offset' => $rec_offset, @@ -1833,6 +1902,7 @@ class Xls extends XlsBase // get spliced record data $splicedRecordData = $this->getSplicedRecordData(); + /** @var string */ $recordData = $splicedRecordData['recordData']; $this->drawingGroupData .= $recordData; @@ -1861,12 +1931,14 @@ class Xls extends XlsBase $splicedRecordData = $this->getSplicedRecordData(); $recordData = $splicedRecordData['recordData']; + /** @var mixed[] */ $spliceOffsets = $splicedRecordData['spliceOffsets']; // offset: 0; size: 4; total number of strings in the workbook $pos += 4; // offset: 4; size: 4; number of following strings ($nm) + /** @var string $recordData */ $nm = self::getInt4d($recordData, 4); $pos += 4; @@ -1882,10 +1954,13 @@ class Xls extends XlsBase // loop through the Unicode strings (16-bit length) for ($i = 0; $i < $nm && $pos < $limitposSST; ++$i) { // number of characters in the Unicode string + /** @var int $pos */ $numChars = self::getUInt2d($recordData, $pos); + /** @var int $pos */ $pos += 2; // option flags + /** @var string $recordData */ $optionFlags = ord($recordData[$pos]); ++$pos; @@ -1927,6 +2002,7 @@ class Xls extends XlsBase } } + /** @var int $limitpos */ if ($pos + $len <= $limitpos) { // character array is not split between records @@ -1958,12 +2034,15 @@ class Xls extends XlsBase // repeated option flags // OpenOffice.org documentation 5.21 + /** @var int $pos */ $option = ord($recordData[$pos]); ++$pos; + /** @var int $limitpos */ if ($isCompressed && ($option == 0)) { // 1st fragment compressed // this fragment compressed + /** @var int */ $len = min($charsLeft, $limitpos - $pos); $retstr .= substr($recordData, $pos, $len); $charsLeft -= $len; @@ -1971,6 +2050,7 @@ class Xls extends XlsBase } elseif (!$isCompressed && ($option != 0)) { // 1st fragment uncompressed // this fragment uncompressed + /** @var int */ $len = min($charsLeft * 2, $limitpos - $pos); $retstr .= substr($recordData, $pos, $len); $charsLeft -= $len / 2; @@ -1994,6 +2074,7 @@ class Xls extends XlsBase $newstr .= $retstr[$j] . chr(0); } $retstr = $newstr; + /** @var int */ $len = min($charsLeft * 2, $limitpos - $pos); $retstr .= substr($recordData, $pos, $len); $charsLeft -= $len / 2; @@ -2013,6 +2094,7 @@ class Xls extends XlsBase // list of formatting runs for ($j = 0; $j < $formattingRuns; ++$j) { // first formatted character; zero-based + /** @var int $pos */ $charPos = self::getUInt2d($recordData, $pos + $j * 4); // index to font record @@ -2178,8 +2260,13 @@ class Xls extends XlsBase $string = $this->readByteStringShort($recordData); } - $this->phpSheet->getHeaderFooter()->setOddHeader($string['value']); - $this->phpSheet->getHeaderFooter()->setEvenHeader($string['value']); + /** @var string[] $string */ + $this->phpSheet + ->getHeaderFooter() + ->setOddHeader($string['value']); + $this->phpSheet + ->getHeaderFooter() + ->setEvenHeader($string['value']); } } } @@ -2204,8 +2291,14 @@ class Xls extends XlsBase } else { $string = $this->readByteStringShort($recordData); } - $this->phpSheet->getHeaderFooter()->setOddFooter($string['value']); - $this->phpSheet->getHeaderFooter()->setEvenFooter($string['value']); + /** @var string */ + $temp = $string['value']; + $this->phpSheet + ->getHeaderFooter() + ->setOddFooter($temp); + $this->phpSheet + ->getHeaderFooter() + ->setEvenFooter($temp); } } } @@ -2566,7 +2659,14 @@ class Xls extends XlsBase $useDefaultHeight = (0x8000 & self::getUInt2d($recordData, 6)) >> 15; if (!$useDefaultHeight) { - $this->phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); + if ( + $this->phpSheet->getDefaultRowDimension()->getRowHeight() > 0 + ) { + $this->phpSheet->getRowDimension($r + 1) + ->setCustomFormat(true, ($height === 255) ? -1 : ($height / 20)); + } else { + $this->phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); + } } // offset: 8; size: 2; not used @@ -2685,9 +2785,14 @@ class Xls extends XlsBase $charPos = 0; $sstCount = count($this->sst[$index]['fmtRuns']); for ($i = 0; $i <= $sstCount; ++$i) { + /** @var mixed[][] $fmtRuns */ if (isset($fmtRuns[$i])) { - $text = StringHelper::substring($this->sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos); - $charPos = $fmtRuns[$i]['charPos']; + /** @var int[] */ + $temp = $fmtRuns[$i]; + $temp = $temp['charPos']; + /** @var int $charPos */ + $text = StringHelper::substring($this->sst[$index]['value'], $charPos, $temp - $charPos); + $charPos = $temp; } else { $text = StringHelper::substring($this->sst[$index]['value'], $charPos, StringHelper::countCharacters($this->sst[$index]['value'])); } @@ -2697,13 +2802,16 @@ class Xls extends XlsBase $richText->createText($text); } else { $textRun = $richText->createTextRun($text); + /** @var int[][] $fmtRuns */ if (isset($fmtRuns[$i - 1])) { if ($fmtRuns[$i - 1]['fontIndex'] < 4) { $fontIndex = $fmtRuns[$i - 1]['fontIndex']; } else { // this has to do with that index 4 is omitted in all BIFF versions for some stra nge reason // check the OpenOffice documentation of the FONT record - $fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1; + /** @var int */ + $temp = $fmtRuns[$i - 1]['fontIndex']; + $fontIndex = $temp - 1; } if (array_key_exists($fontIndex, $this->objFonts) === false) { $fontIndex = count($this->objFonts) - 1; @@ -3011,6 +3119,7 @@ class Xls extends XlsBase $string = $this->readByteStringLong($recordData); $value = $string['value']; } + /** @var string $value */ return $value; } @@ -3154,6 +3263,7 @@ class Xls extends XlsBase $string = $this->readByteStringLong(substr($recordData, 6)); $value = $string['value']; } + /** @var string $value */ if ($this->readEmptyCells || trim($value) !== '') { $cell = $this->phpSheet->getCell($columnString . ($row + 1)); $cell->setValueExplicit($value, DataType::TYPE_STRING); @@ -3207,7 +3317,7 @@ class Xls extends XlsBase $splicedRecordData = $this->getSplicedRecordData(); $recordData = $splicedRecordData['recordData']; - $this->drawingData .= $recordData; + $this->drawingData .= StringHelper::convertToString($recordData); } /** @@ -3484,9 +3594,9 @@ class Xls extends XlsBase { $includeCellRange = false; $rangeBoundaries = Coordinate::getRangeBoundaries($cellRangeAddress); - ++$rangeBoundaries[1][0]; + StringHelper::stringIncrement($rangeBoundaries[1][0]); for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; ++$row) { - for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; ++$column) { + for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; StringHelper::stringIncrement($column)) { if ($this->getReadFilter()->readCell($column, $row, $this->phpSheet->getTitle())) { $includeCellRange = true; @@ -3518,6 +3628,7 @@ class Xls extends XlsBase if ($this->version == self::XLS_BIFF8 && !$this->readDataOnly) { $cellRangeAddressList = Xls\Biff8::readBIFF8CellRangeAddressList($recordData); foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { + /** @var string $cellRangeAddress */ if ( (str_contains($cellRangeAddress, ':')) && ($this->includeCellRangeFiltered($cellRangeAddress)) @@ -3746,6 +3857,7 @@ class Xls extends XlsBase case 0x14: // offset: 16; size: 2; color index for sheet tab $colorIndex = self::getUInt2d($recordData, 16); + /** @var string[] */ $color = Xls\Color::map($colorIndex, $this->palette, $this->version); $this->phpSheet->getTabColor()->setRGB($color['rgb']); @@ -3960,7 +4072,7 @@ class Xls extends XlsBase if (in_array($splitPoint, $validSplitPoints)) { // get spliced record data (and move pointer to next record) $splicedRecordData = $this->getSplicedRecordData(); - $this->drawingData .= $splicedRecordData['recordData']; + $this->drawingData .= StringHelper::convertToString($splicedRecordData['recordData']); return; } @@ -3974,6 +4086,8 @@ class Xls extends XlsBase * records are found. Splices the record data pieces and returns the combined string as if record data * is in one piece. * Moves to next current position in data stream to start of next record different from a CONtINUE record. + * + * @return mixed[] */ private function getSplicedRecordData(): array { @@ -4046,6 +4160,7 @@ class Xls extends XlsBase while ($formulaData !== '' && $token = $this->getNextToken($formulaData, $baseCell)) { $tokens[] = $token; + /** @var int[] $token */ $formulaData = substr($formulaData, $token['size']); } @@ -4057,6 +4172,7 @@ class Xls extends XlsBase /** * Take array of tokens together with additional data for formula and return human readable formula. * + * @param mixed[][] $tokens * @param string $additionalData Additional binary data going with the formula * * @return string Human readable formula @@ -4077,7 +4193,8 @@ class Xls extends XlsBase $space3 = $space3 ?? ''; // carriage returns before opening parenthesis $space4 = $space4 ?? ''; // spaces before closing parenthesis $space5 = $space5 ?? ''; // carriage returns before closing parenthesis - + /** @var string */ + $tokenData = $token['data'] ?? ''; switch ($token['name']) { case 'tAdd': // addition case 'tConcat': // addition @@ -4096,20 +4213,20 @@ class Xls extends XlsBase case 'tSub': // subtraction $op2 = array_pop($formulaStrings); $op1 = array_pop($formulaStrings); - $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2"; + $formulaStrings[] = "$op1$space1$space0{$tokenData}$op2"; unset($space0, $space1); break; case 'tUplus': // unary plus case 'tUminus': // unary minus $op = array_pop($formulaStrings); - $formulaStrings[] = "$space1$space0{$token['data']}$op"; + $formulaStrings[] = "$space1$space0{$tokenData}$op"; unset($space0, $space1); break; case 'tPercent': // percent sign $op = array_pop($formulaStrings); - $formulaStrings[] = "$op$space1$space0{$token['data']}"; + $formulaStrings[] = "$op$space1$space0{$tokenData}"; unset($space0, $space1); break; @@ -4122,29 +4239,30 @@ class Xls extends XlsBase break; case 'tAttrSpace': // space / carriage return // space will be used when next token arrives, do not alter formulaString stack + /** @var string[][] $token */ switch ($token['data']['spacetype']) { case 'type0': - $space0 = str_repeat(' ', $token['data']['spacecount']); + $space0 = str_repeat(' ', (int) $token['data']['spacecount']); break; case 'type1': - $space1 = str_repeat("\n", $token['data']['spacecount']); + $space1 = str_repeat("\n", (int) $token['data']['spacecount']); break; case 'type2': - $space2 = str_repeat(' ', $token['data']['spacecount']); + $space2 = str_repeat(' ', (int) $token['data']['spacecount']); break; case 'type3': - $space3 = str_repeat("\n", $token['data']['spacecount']); + $space3 = str_repeat("\n", (int) $token['data']['spacecount']); break; case 'type4': - $space4 = str_repeat(' ', $token['data']['spacecount']); + $space4 = str_repeat(' ', (int) $token['data']['spacecount']); break; case 'type5': - $space5 = str_repeat("\n", $token['data']['spacecount']); + $space5 = str_repeat("\n", (int) $token['data']['spacecount']); break; } @@ -4158,19 +4276,25 @@ class Xls extends XlsBase break; case 'tFunc': // function with fixed number of arguments case 'tFuncV': // function with variable number of arguments - if ($token['data']['function'] != '') { + /** @var string[] */ + $temp1 = $token['data']; + $temp2 = $temp1['function']; + if ($temp2 != '') { // normal function $ops = []; // array of operators - for ($i = 0; $i < $token['data']['args']; ++$i) { + $temp3 = (int) $temp1['args']; + for ($i = 0; $i < $temp3; ++$i) { $ops[] = array_pop($formulaStrings); } $ops = array_reverse($ops); - $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ')'; + $formulaStrings[] = "$space1$space0{$temp2}(" . implode(',', $ops) . ')'; unset($space0, $space1); } else { // add-in function $ops = []; // array of operators - for ($i = 0; $i < $token['data']['args'] - 1; ++$i) { + /** @var int[] */ + $temp = $token['data']; + for ($i = 0; $i < $temp['args'] - 1; ++$i) { $ops[] = array_pop($formulaStrings); } $ops = array_reverse($ops); @@ -4197,7 +4321,7 @@ class Xls extends XlsBase // bite off chunk of additional data $cellRangeAddressList = Xls\Biff8::readBIFF8CellRangeAddressList($additionalData); $additionalData = substr($additionalData, $cellRangeAddressList['size']); - $formulaStrings[] = "$space1$space0{$token['data']}"; + $formulaStrings[] = "$space1$space0{$tokenData}"; unset($space0, $space1); break; @@ -4217,7 +4341,7 @@ class Xls extends XlsBase case 'tRefN': case 'tAreaN': case 'tStr': // string - $formulaStrings[] = "$space1$space0{$token['data']}"; + $formulaStrings[] = "$space1$space0{$tokenData}"; unset($space0, $space1); break; @@ -4233,6 +4357,8 @@ class Xls extends XlsBase * * @param string $formulaData Formula data * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * + * @return mixed[] */ private function getNextToken(string $formulaData, string $baseCell = 'A1'): array { @@ -4506,7 +4632,8 @@ class Xls extends XlsBase // offset: 1; size: 2; one-based index to definedname record $definedNameIndex = self::getUInt2d($formulaData, 1) - 1; // offset: 2; size: 2; not used - $data = $this->definedname[$definedNameIndex]['name'] ?? ''; + /** @var string[] */ + $data = $this->definedname[$definedNameIndex]['name'] ?? ''; //* @phpstan-ignore-line break; case 0x24: // single cell reference e.g. A5 @@ -4690,6 +4817,8 @@ class Xls extends XlsBase /** * Read byte string (8-bit string length) * OpenOffice documentation: 2.5.2. + * + * @return array{value: mixed, size: int} */ protected function readByteStringShort(string $subData): array { @@ -4708,6 +4837,8 @@ class Xls extends XlsBase /** * Read byte string (16-bit string length) * OpenOffice documentation: 2.5.2. + * + * @return array{value: mixed, size: int} */ protected function readByteStringLong(string $subData): array { @@ -4738,6 +4869,8 @@ class Xls extends XlsBase * For now, however, this function makes it readable, * which satisfies Phpstan. * + * @return mixed[] + * * @codeCoverageIgnore */ public function getMapCellStyleXfIndex(): array @@ -4749,12 +4882,15 @@ class Xls extends XlsBase * Parse conditional formatting blocks. * * @see https://www.openoffice.org/sc/excelfileformat.pdf Search for CFHEADER followed by CFRULE + * + * @return mixed[] */ protected function readCFHeader(): array { return (new Xls\ConditionalFormatting())->readCFHeader2($this); } + /** @param string[] $cellRangeAddresses */ protected function readCFRule(array $cellRangeAddresses): void { (new Xls\ConditionalFormatting())->readCFRule2($cellRangeAddresses, $this); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Biff5.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Biff5.php index ef9619e..61ff9ee 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Biff5.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Biff5.php @@ -46,6 +46,8 @@ class Biff5 extends Xls /** * Read BIFF5 cell range address list * section 2.5.15. + * + * @return array{size: int, cellRangeAddresses: string[]} */ public static function readBIFF5CellRangeAddressList(string $subData): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Biff8.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Biff8.php index f95c0b5..2de9fb8 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Biff8.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Biff8.php @@ -12,6 +12,8 @@ class Biff8 extends Xls * read BIFF8 constant value array from array data * returns e.g. ['value' => '{1,2;3,4}', 'size' => 40] * section 2.5.8. + * + * @return array{value: string, size: int} */ protected static function readBIFF8ConstantArray(string $arrayData): array { @@ -47,6 +49,8 @@ class Biff8 extends Xls * read BIFF8 constant value which may be 'Empty Value', 'Number', 'String Value', 'Boolean Value', 'Error Value' * section 2.5.7 * returns e.g. ['value' => '5', 'size' => 9]. + * + * @return array{value: bool|float|int|string, size: int} */ private static function readBIFF8Constant(string $valueData): array { @@ -101,6 +105,8 @@ class Biff8 extends Xls /** * Read BIFF8 cell range address list * section 2.5.15. + * + * @return array{size: int, cellRangeAddresses: mixed[]} */ public static function readBIFF8CellRangeAddressList(string $subData): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color.php index 17b6e16..adbe1a2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color.php @@ -10,9 +10,9 @@ class Color * Read color. * * @param int $color Indexed color - * @param array $palette Color palette + * @param string[][] $palette Color palette * - * @return array RGB color value, example: ['rgb' => 'FF0000'] + * @return string[] RGB color value, example: ['rgb' => 'FF0000'] */ public static function map(int $color, array $palette, int $version): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BIFF5.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BIFF5.php index 2c0790c..ecc026c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BIFF5.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BIFF5.php @@ -65,6 +65,8 @@ class BIFF5 /** * Map color array from BIFF5 built-in color index. + * + * @return array{rgb: string} */ public static function lookup(int $color): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BIFF8.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BIFF8.php index 914034d..11745f7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BIFF8.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BIFF8.php @@ -65,6 +65,8 @@ class BIFF8 /** * Map color array from BIFF8 built-in color index. + * + * @return array{rgb: string} */ public static function lookup(int $color): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BuiltIn.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BuiltIn.php index a715b11..5752446 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BuiltIn.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Color/BuiltIn.php @@ -21,6 +21,8 @@ class BuiltIn * Map built-in color to RGB value. * * @param int $color Indexed color + * + * @return array{rgb: string} */ public static function lookup(int $color): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/ConditionalFormatting.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/ConditionalFormatting.php index 1c05c63..9f89d16 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/ConditionalFormatting.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/ConditionalFormatting.php @@ -48,6 +48,8 @@ class ConditionalFormatting extends Xls * Parse conditional formatting blocks. * * @see https://www.openoffice.org/sc/excelfileformat.pdf Search for CFHEADER followed by CFRULE + * + * @return mixed[] */ protected function readCFHeader2(Xls $xls): array { @@ -73,6 +75,7 @@ class ConditionalFormatting extends Xls return $cellRangeAddresses; } + /** @param string[] $cellRangeAddresses */ protected function readCFRule2(array $cellRangeAddresses, Xls $xls): void { $length = self::getUInt2d($xls->data, $xls->pos + 2); @@ -212,7 +215,9 @@ class ConditionalFormatting extends Xls $color = self::getInt4d($options, 80); if ($color !== -1) { - $style->getFont()->getColor()->setRGB(Color::map($color, $xls->palette, $xls->version)['rgb']); + $style->getFont() + ->getColor() + ->setRGB(Color::map($color, $xls->palette, $xls->version)['rgb']); } } @@ -222,6 +227,7 @@ class ConditionalFormatting extends Xls private function getCFBorderStyle(string $options, Style $style, bool $hasBorderLeft, bool $hasBorderRight, bool $hasBorderTop, bool $hasBorderBottom, Xls $xls): void { + /** @var false|int[] */ $valueArray = unpack('V', $options); $value = is_array($valueArray) ? $valueArray[1] : 0; $left = $value & 15; @@ -230,6 +236,7 @@ class ConditionalFormatting extends Xls $bottom = ($value >> 12) & 15; $leftc = ($value >> 16) & 0x7F; $rightc = ($value >> 23) & 0x7F; + /** @var false|int[] */ $valueArray = unpack('V', substr($options, 4)); $value = is_array($valueArray) ? $valueArray[1] : 0; $topc = $value & 0x7F; @@ -308,6 +315,7 @@ class ConditionalFormatting extends Xls } } + /** @param string[] $cellRanges */ private function setCFRules(array $cellRanges, string $type, string $operator, null|float|int|string $formula1, null|float|int|string $formula2, Style $style, bool $noFormatSet, Xls $xls): void { foreach ($cellRanges as $cellRange) { @@ -324,10 +332,14 @@ class ConditionalFormatting extends Xls } $conditional->setStyle($style); - $conditionalStyles = $xls->phpSheet->getStyle($cellRange)->getConditionalStyles(); + $conditionalStyles = $xls->phpSheet + ->getStyle($cellRange) + ->getConditionalStyles(); $conditionalStyles[] = $conditional; - $xls->phpSheet->getStyle($cellRange)->setConditionalStyles($conditionalStyles); + $xls->phpSheet + ->getStyle($cellRange) + ->setConditionalStyles($conditionalStyles); } } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/DataValidationHelper.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/DataValidationHelper.php index e3a8d98..b5a9454 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/DataValidationHelper.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/DataValidationHelper.php @@ -176,6 +176,7 @@ class DataValidationHelper extends Xls // offset: var; size: var; cell range address list with $cellRangeAddressList = Biff8::readBIFF8CellRangeAddressList(substr($recordData, $offset)); + /** @var string[] */ $cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses']; $maxRow = (string) AddressRange::MAX_ROW; $maxCol = AddressRange::MAX_COLUMN; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Escher.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Escher.php index 094c19e..018c171 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Escher.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/Escher.php @@ -12,6 +12,9 @@ use PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer; use PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE; use PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE\Blip; +/** + * @template T of BSE|BstoreContainer|DgContainer|DggContainer|\PhpOffice\PhpSpreadsheet\Shared\Escher|SpContainer|SpgrContainer + */ class Escher { const DGGCONTAINER = 0xF000; @@ -50,11 +53,15 @@ class Escher /** * The object to be returned by the reader. Modified during load. + * + * @var T */ private BSE|BstoreContainer|DgContainer|DggContainer|\PhpOffice\PhpSpreadsheet\Shared\Escher|SpContainer|SpgrContainer $object; /** * Create a new Escher instance. + * + * @param T $object */ public function __construct(BSE|BstoreContainer|DgContainer|DggContainer|\PhpOffice\PhpSpreadsheet\Shared\Escher|SpContainer|SpgrContainer $object) { @@ -84,6 +91,8 @@ class Escher /** * Load Escher stream data. May be a partial Escher stream. + * + * @return T */ public function load(string $data): BSE|BstoreContainer|DgContainer|DggContainer|\PhpOffice\PhpSpreadsheet\Shared\Escher|SpContainer|SpgrContainer { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/ListFunctions.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/ListFunctions.php index ab9849a..9856989 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/ListFunctions.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/ListFunctions.php @@ -5,12 +5,15 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xls; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Reader\Xls; use PhpOffice\PhpSpreadsheet\Shared\File; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class ListFunctions extends Xls { /** * Reads names of the worksheets from a file, without parsing the whole file to a PhpSpreadsheet object. + * + * @return string[] */ protected function listWorksheetNames2(string $filename, Xls $xls): array { @@ -56,6 +59,8 @@ class ListFunctions extends Xls /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ protected function listWorksheetInfo2(string $filename, Xls $xls): array { @@ -100,12 +105,12 @@ class ListFunctions extends Xls } $tmpInfo = []; - $tmpInfo['worksheetName'] = $sheet['name']; + $tmpInfo['worksheetName'] = StringHelper::convertToString($sheet['name']); $tmpInfo['lastColumnLetter'] = 'A'; $tmpInfo['lastColumnIndex'] = 0; $tmpInfo['totalRows'] = 0; $tmpInfo['totalColumns'] = 0; - $tmpInfo['sheetState'] = $sheet['sheetState']; + $tmpInfo['sheetState'] = StringHelper::convertToString($sheet['sheetState']); $xls->pos = $sheet['offset']; @@ -119,6 +124,7 @@ class ListFunctions extends Xls case self::XLS_TYPE_FORMULA: case self::XLS_TYPE_BOOLERR: case self::XLS_TYPE_LABEL: + case self::XLS_TYPE_MULRK: $length = self::getUInt2d($xls->data, $xls->pos + 2); $recordData = $xls->readRecordData($xls->data, $xls->pos + 4, $length); @@ -126,7 +132,11 @@ class ListFunctions extends Xls $xls->pos += 4 + $length; $rowIndex = self::getUInt2d($recordData, 0) + 1; - $columnIndex = self::getUInt2d($recordData, 2); + if ($code === self::XLS_TYPE_MULRK) { + $columnIndex = self::getUInt2d($recordData, $length - 2); + } else { + $columnIndex = self::getUInt2d($recordData, 2); + } $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); @@ -155,4 +165,103 @@ class ListFunctions extends Xls return $worksheetInfo; } + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array + */ + protected function listWorksheetDimensions2(string $filename, Xls $xls): array + { + File::assertFile($filename); + + $worksheetInfo = []; + + // Read the OLE file + $xls->loadOLE($filename); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $xls->dataSize = strlen($xls->data); + + // initialize + $xls->pos = 0; + $xls->sheets = []; + + // Parse Workbook Global Substream + while ($xls->pos < $xls->dataSize) { + $code = self::getUInt2d($xls->data, $xls->pos); + + match ($code) { + self::XLS_TYPE_BOF => $xls->readBof(), + self::XLS_TYPE_SHEET => $xls->readSheet(), + self::XLS_TYPE_EOF => $xls->readDefault(), + self::XLS_TYPE_CODEPAGE => $xls->readCodepage(), + default => $xls->readDefault(), + }; + + if ($code === self::XLS_TYPE_EOF) { + break; + } + } + + // Parse the individual sheets + foreach ($xls->sheets as $sheet) { + if ($sheet['sheetType'] !== 0x00) { + // 0x00: Worksheet + // 0x02: Chart + // 0x06: Visual Basic module + continue; + } + + $tmpInfo = []; + $tmpInfo['worksheetName'] = StringHelper::convertToString($sheet['name']); + $tmpInfo['dimensionsMinR'] = -1; + $tmpInfo['dimensionsMaxR'] = -1; + $tmpInfo['dimensionsMinC'] = -1; + $tmpInfo['dimensionsMaxC'] = -1; + $tmpInfo['lastColumnLetter'] = ''; + + $xls->pos = $sheet['offset']; + + while ($xls->pos <= $xls->dataSize - 4) { + $code = self::getUInt2d($xls->data, $xls->pos); + + switch ($code) { + case self::XLS_TYPE_BOF: + $xls->readBof(); + + break; + case self::XLS_TYPE_EOF: + $xls->readDefault(); + + break 2; + case self::XLS_TYPE_DIMENSION: + $length = self::getUInt2d($xls->data, $xls->pos + 2); + if ($length === 14) { + $dimensionsData = substr($xls->data, $xls->pos + 4, $length); + $data = unpack('VrwMic/VrwMac/vcolMic/vcolMac/vreserved', $dimensionsData); + if (is_array($data)) { + /** @var int[] $data */ + $tmpInfo['dimensionsMinR'] = $data['rwMic']; + $tmpInfo['dimensionsMaxR'] = $data['rwMac']; + $tmpInfo['dimensionsMinC'] = $data['colMic']; + $tmpInfo['dimensionsMaxC'] = $data['colMac']; + $tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['dimensionsMaxC']); + } + } + $xls->readDefault(); + + break; + default: + $xls->readDefault(); + + break; + } + } + + $worksheetInfo[] = $tmpInfo; + } + + return $worksheetInfo; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php index 4683ec2..5c27b0c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php @@ -26,8 +26,8 @@ class LoadSpreadsheet extends Xls $xls->loadOLE($filename); // Initialisations - $xls->spreadsheet = new Spreadsheet(); - $xls->spreadsheet->setValueBinder($this->valueBinder); + $xls->spreadsheet = $this->newSpreadsheet(); + $xls->spreadsheet->setValueBinder($xls->valueBinder); $xls->spreadsheet->removeSheetByIndex(0); // remove 1st sheet if (!$xls->readDataOnly) { $xls->spreadsheet->removeCellStyleXfByIndex(0); // remove the default style @@ -52,7 +52,7 @@ class LoadSpreadsheet extends Xls $xls->sheets = []; $xls->externalBooks = []; $xls->ref = []; - $xls->definedname = []; + $xls->definedname = []; //* @phpstan-ignore-line $xls->sst = []; $xls->drawingGroupData = ''; $xls->xfIndex = 0; @@ -153,6 +153,7 @@ class LoadSpreadsheet extends Xls // Parse the individual sheets $xls->activeSheetSet = false; + $sheetCreated = false; foreach ($xls->sheets as $sheet) { $selectedCells = ''; if ($sheet['sheetType'] != 0x00) { @@ -167,6 +168,7 @@ class LoadSpreadsheet extends Xls // add sheet to PhpSpreadsheet object $xls->phpSheet = $xls->spreadsheet->createSheet(); + $sheetCreated = true; // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet // name in line with the formula, not the reverse @@ -382,6 +384,7 @@ class LoadSpreadsheet extends Xls break; case self::XLS_TYPE_CFHEADER: + /** @var string[] */ $cellRangeAddresses = $xls->readCFHeader(); break; @@ -432,7 +435,7 @@ class LoadSpreadsheet extends Xls // get all spContainers in one long array, so they can be mapped to OBJ records /** @var SpContainer[] $allSpContainers */ - $allSpContainers = method_exists($escherWorksheet, 'getDgContainer') ? $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers() : []; + $allSpContainers = $escherWorksheet->getDgContainerOrThrow()->getSpgrContainerOrThrow()->getAllSpContainers(); } // treat OBJ records @@ -464,6 +467,7 @@ class LoadSpreadsheet extends Xls $offsetX = (int) ($startOffsetX * SharedXls::sizeCol($xls->phpSheet, $startColumn) / 1024); $offsetY = (int) ($startOffsetY * SharedXls::sizeRow($xls->phpSheet, $startRow) / 256); + /** @var int[] $obj */ switch ($obj['otObjType']) { case 0x19: // Note @@ -472,7 +476,7 @@ class LoadSpreadsheet extends Xls if (isset($xls->textObjects[$obj['idObjID']])) { $textObject = $xls->textObjects[$obj['idObjID']]; - $xls->cellNotes[$obj['idObjID']]['objTextData'] = $textObject; + $xls->cellNotes[$obj['idObjID']]['objTextData'] = $textObject; //* @phpstan-ignore-line } } @@ -480,6 +484,7 @@ class LoadSpreadsheet extends Xls case 0x08: // picture // get index to BSE entry (1-based) + /** @var int */ $BSEindex = $spContainer->getOPT(0x0104); // If there is no BSE Index, we will fail here and other fields are not read. @@ -491,7 +496,8 @@ class LoadSpreadsheet extends Xls } if ($escherWorkbook) { - $BSECollection = method_exists($escherWorkbook, 'getDggContainer') ? $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection() : []; + /** @var BSE[] */ + $BSECollection = $escherWorkbook->getDggContainerOrThrow()->getBstoreContainerOrThrow()->getBSECollection(); $BSE = $BSECollection[$BSEindex - 1]; $blipType = $BSE->getBlipType(); @@ -543,8 +549,11 @@ class LoadSpreadsheet extends Xls foreach ($xls->sharedFormulaParts as $cell => $baseCell) { /** @var int $row */ [$column, $row] = Coordinate::coordinateFromString($cell); + /** @var string $baseCell */ if ($xls->getReadFilter()->readCell($column, $row, $xls->phpSheet->getTitle())) { - $formula = $xls->getFormulaFromStructure($xls->sharedFormulas[$baseCell], $cell); + /** @var string */ + $temp = $xls->sharedFormulas[$baseCell]; + $formula = $xls->getFormulaFromStructure($temp, $cell); $xls->phpSheet->getCell($cell)->setValueExplicit('=' . $formula, DataType::TYPE_FORMULA); } } @@ -552,6 +561,7 @@ class LoadSpreadsheet extends Xls if (!empty($xls->cellNotes)) { foreach ($xls->cellNotes as $note => $noteDetails) { + /** @var array{author: string, cellRef: string, objTextData?: mixed[]} $noteDetails */ if (!isset($noteDetails['objTextData'])) { if (isset($xls->textObjects[$note])) { $textObject = $xls->textObjects[$note]; @@ -561,19 +571,30 @@ class LoadSpreadsheet extends Xls } } $cellAddress = str_replace('$', '', $noteDetails['cellRef']); - $xls->phpSheet->getComment($cellAddress)->setAuthor($noteDetails['author'])->setText($xls->parseRichText($noteDetails['objTextData']['text'])); + /** @var string */ + $tempDetails = $noteDetails['objTextData']['text']; + $xls->phpSheet + ->getComment($cellAddress) + ->setAuthor($noteDetails['author']) + ->setText( + $xls->parseRichText($tempDetails) + ); } } if ($selectedCells !== '') { $xls->phpSheet->setSelectedCells($selectedCells); } } + if ($xls->createBlankSheetIfNoneRead && !$sheetCreated) { + $xls->spreadsheet->createSheet(); + } if ($xls->activeSheetSet === false) { $xls->spreadsheet->setActiveSheetIndex(0); } // add the named ranges (defined names) foreach ($xls->definedname as $definedName) { + /** @var array{isBuiltInName: int, name: string, formula: string, scope: int} $definedName */ if ($definedName['isBuiltInName']) { switch ($definedName['name']) { case pack('C', 0x06): @@ -627,6 +648,8 @@ class LoadSpreadsheet extends Xls if (count($coordinateStrings) == 2) { [$firstColumn, $firstRow] = Coordinate::coordinateFromString($coordinateStrings[0]); [$lastColumn, $lastRow] = Coordinate::coordinateFromString($coordinateStrings[1]); + $firstRow = (int) $firstRow; + $lastRow = (int) $lastRow; if ($firstColumn == 'A' && $lastColumn == 'IV') { // then we have repeating rows @@ -644,7 +667,6 @@ class LoadSpreadsheet extends Xls } } else { // Extract range - /** @var non-empty-string $formula */ $formula = $definedName['formula']; if (str_contains($formula, '!')) { $explodes = Worksheet::extractSheetTitle($formula, true, true); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/MD5.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/MD5.php index 7da2eee..56dd4a3 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/MD5.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls/MD5.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xls; +use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException; + class MD5 { private int $a; @@ -58,8 +60,9 @@ class MD5 */ public function add(string $data): void { - // @phpstan-ignore-next-line - $words = array_values(unpack('V16', $data)); + $unpacked = unpack('V16', $data) ?: throw new ReaderException('unable to unpack data'); + /** @var int[] */ + $words = array_values($unpacked); $A = $this->a; $B = $this->b; @@ -173,7 +176,9 @@ class MD5 private static function step(callable $func, int &$A, int $B, int $C, int $D, int $M, int $s, $t): void { $t = self::signedInt($t); - $A = (int) ($A + call_user_func($func, $B, $C, $D) + $M + $t) & self::$allOneBits; + /** @var int */ + $temp = call_user_func($func, $B, $C, $D); + $A = (int) ($A + $temp + $M + $t) & self::$allOneBits; $A = self::rotate($A, $s); $A = (int) ($B + $A) & self::$allOneBits; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/XlsBase.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/XlsBase.php index e6969db..eedd185 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/XlsBase.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/XlsBase.php @@ -25,8 +25,6 @@ class XlsBase extends BaseReader final const XLS_TYPE_FORMULA = 0x0006; final const XLS_TYPE_EOF = 0x000A; final const XLS_TYPE_PROTECT = 0x0012; - final const XLS_TYPE_OBJECTPROTECT = 0x0063; - final const XLS_TYPE_SCENPROTECT = 0x00DD; final const XLS_TYPE_PASSWORD = 0x0013; final const XLS_TYPE_HEADER = 0x0014; final const XLS_TYPE_FOOTER = 0x0015; @@ -50,6 +48,7 @@ class XlsBase extends BaseReader final const XLS_TYPE_CODEPAGE = 0x0042; final const XLS_TYPE_DEFCOLWIDTH = 0x0055; final const XLS_TYPE_OBJ = 0x005D; + final const XLS_TYPE_OBJECTPROTECT = 0x0063; final const XLS_TYPE_COLINFO = 0x007D; final const XLS_TYPE_IMDATA = 0x007F; final const XLS_TYPE_SHEETPR = 0x0081; @@ -62,6 +61,7 @@ class XlsBase extends BaseReader final const XLS_TYPE_MULRK = 0x00BD; final const XLS_TYPE_MULBLANK = 0x00BE; final const XLS_TYPE_DBCELL = 0x00D7; + final const XLS_TYPE_SCENPROTECT = 0x00DD; final const XLS_TYPE_XF = 0x00E0; final const XLS_TYPE_MERGEDCELLS = 0x00E5; final const XLS_TYPE_MSODRAWINGGROUP = 0x00EB; @@ -70,6 +70,8 @@ class XlsBase extends BaseReader final const XLS_TYPE_LABELSST = 0x00FD; final const XLS_TYPE_EXTSST = 0x00FF; final const XLS_TYPE_EXTERNALBOOK = 0x01AE; + final const XLS_TYPE_CFHEADER = 0x01B0; + final const XLS_TYPE_CFRULE = 0x01B1; final const XLS_TYPE_DATAVALIDATIONS = 0x01B2; final const XLS_TYPE_TXO = 0x01B6; final const XLS_TYPE_HYPERLINK = 0x01B8; @@ -90,13 +92,11 @@ class XlsBase extends BaseReader final const XLS_TYPE_FORMAT = 0x041E; final const XLS_TYPE_SHAREDFMLA = 0x04BC; final const XLS_TYPE_BOF = 0x0809; + final const XLS_TYPE_SHEETLAYOUT = 0x0862; final const XLS_TYPE_SHEETPROTECTION = 0x0867; final const XLS_TYPE_RANGEPROTECTION = 0x0868; - final const XLS_TYPE_SHEETLAYOUT = 0x0862; final const XLS_TYPE_XFEXT = 0x087D; final const XLS_TYPE_PAGELAYOUTVIEW = 0x088B; - final const XLS_TYPE_CFHEADER = 0x01B0; - final const XLS_TYPE_CFRULE = 0x01B1; final const XLS_TYPE_UNKNOWN = 0xFFFF; // Encryption type @@ -177,6 +177,8 @@ class XlsBase extends BaseReader * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.4. * * @param string $rgb Encoded RGB value (4 bytes) + * + * @return array{rgb: string} */ protected static function readRGB(string $rgb): array { @@ -199,6 +201,8 @@ class XlsBase extends BaseReader * Extracts an Excel Unicode short string (8-bit string length) * OpenOffice documentation: 2.5.3 * function will automatically find out where the Unicode string ends. + * + * @return array{value: string, size: int} */ protected static function readUnicodeStringShort(string $subData): array { @@ -217,6 +221,8 @@ class XlsBase extends BaseReader * Extracts an Excel Unicode long string (16-bit string length) * OpenOffice documentation: 2.5.3 * this function is under construction, needs to support rich text, and Asian phonetic settings. + * + * @return array{value: string, size: int} */ protected static function readUnicodeStringLong(string $subData): array { @@ -235,6 +241,8 @@ class XlsBase extends BaseReader * Read Unicode string with no string length field, but with known character count * this function is under construction, needs to support rich text, and Asian phonetic settings * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.3. + * + * @return array{value: string, size: int} */ protected static function readUnicodeString(string $subData, int $characterCount): array { @@ -360,11 +368,20 @@ class XlsBase extends BaseReader return StringHelper::convertEncoding($string, 'UTF-8', $this->codepage); } + protected static function confirmPos(string $data, int $pos): void + { + if ($pos >= strlen($data)) { + throw new PhpSpreadsheetException('File appears to be corrupt'); // @codeCoverageIgnore + } + } + /** * Read 16-bit unsigned integer. */ public static function getUInt2d(string $data, int $pos): int { + self::confirmPos($data, $pos + 1); + return ord($data[$pos]) | (ord($data[$pos + 1]) << 8); } @@ -373,6 +390,8 @@ class XlsBase extends BaseReader */ public static function getInt2d(string $data, int $pos): int { + self::confirmPos($data, $pos + 1); + return unpack('s', $data[$pos] . $data[$pos + 1])[1]; // @phpstan-ignore-line } @@ -381,6 +400,8 @@ class XlsBase extends BaseReader */ public static function getInt4d(string $data, int $pos): int { + self::confirmPos($data, $pos + 3); + // FIX: represent numbers correctly on 64-bit system // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 // Changed by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php index af10d8b..829f81f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php @@ -38,9 +38,9 @@ use PhpOffice\PhpSpreadsheet\Style\Font as StyleFont; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing; +use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableDxfsStyle; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use SimpleXMLElement; -use Stringable; use Throwable; use XMLReader; use ZipArchive; @@ -58,8 +58,22 @@ class Xlsx extends BaseReader private Styles $styleReader; + /** @var SharedFormula[] */ private array $sharedFormulae = []; + private bool $parseHuge = false; + + /** + * Allow use of LIBXML_PARSEHUGE. + * This option can lead to memory leaks and failures, + * and is not recommended. But some very large spreadsheets + * seem to require it. + */ + public function setParseHuge(bool $parseHuge): void + { + $this->parseHuge = $parseHuge; + } + /** * Create a new Xlsx Reader instance. */ @@ -103,11 +117,13 @@ class Xlsx extends BaseReader } // Phpstan thinks, correctly, that xpath can return false. + /** @return mixed[] */ private static function xpathNoFalse(SimpleXMLElement $sxml, string $path): array { return self::falseToArray($sxml->xpath($path)); } + /** @return mixed[] */ public static function falseToArray(mixed $value): array { return is_array($value) ? $value : []; @@ -121,8 +137,8 @@ class Xlsx extends BaseReader } $rels = @simplexml_load_string( $this->getSecurityScannerOrThrow()->scan($contents), - 'SimpleXMLElement', - 0, + SimpleXMLElement::class, + $this->parseHuge ? LIBXML_PARSEHUGE : 0, $ns ); @@ -136,8 +152,8 @@ class Xlsx extends BaseReader $contents = $this->getFromZipArchive($this->zip, $filename); $rels = simplexml_load_string( $this->getSecurityScannerOrThrow()->scan($contents), - 'SimpleXMLElement', - 0, + SimpleXMLElement::class, + $this->parseHuge ? LIBXML_PARSEHUGE : 0, ($ns === '' ? $ns : '') ); @@ -159,6 +175,8 @@ class Xlsx extends BaseReader /** * Reads names of the worksheets from a file, without parsing the whole file to a Spreadsheet object. + * + * @return string[] */ public function listWorksheetNames(string $filename): array { @@ -194,6 +212,8 @@ class Xlsx extends BaseReader /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ public function listWorksheetInfo(string $filename): array { @@ -252,7 +272,9 @@ class Xlsx extends BaseReader $this->zip, $fileWorksheetPath ) - ) + ), + null, + $this->parseHuge ? LIBXML_PARSEHUGE : 0 ); $xml->setParserProperty(2, true); @@ -401,12 +423,13 @@ class Xlsx extends BaseReader File::assertFile($filename, self::INITIAL_FILE); // Initialisations - $excel = new Spreadsheet(); + $excel = $this->newSpreadsheet(); $excel->setValueBinder($this->valueBinder); $excel->removeSheetByIndex(0); $addingFirstCellStyleXf = true; $addingFirstCellXf = true; + /** @var mixed[][][][] */ $unparsedLoadedData = []; $this->zip = $zip = new ZipArchive(); @@ -426,6 +449,12 @@ class Xlsx extends BaseReader $relTarget = substr($relTarget, 4); } switch ($rel['Type']) { + case "$xmlNamespaceBase/sheetMetadata": + if ($this->fileExistsInArchive($zip, "xl/{$relTarget}")) { + $excel->returnArrayAsArray(); + } + + break; case "$xmlNamespaceBase/theme": if (!$this->fileExistsInArchive($zip, "xl/{$relTarget}")) { break; // issue3770 @@ -601,11 +630,13 @@ class Xlsx extends BaseReader $numFmts = $xmlStyles->numFmts[0]; } if (isset($numFmts)) { + /** @var SimpleXMLElement $numFmts */ $numFmts->registerXPathNamespace('sml', $mainNS); } $this->styleReader->setNamespace($mainNS); if (!$this->readDataOnly/* && $xmlStyles*/) { foreach ($xfTags as $xfTag) { + /** @var SimpleXMLElement $xfTag */ $xf = self::getAttributes($xfTag); $numFmt = null; @@ -645,7 +676,11 @@ class Xlsx extends BaseReader // add style to cellXf collection $objStyle = new Style(); - $this->styleReader->readStyle($objStyle, $style); + $this->styleReader + ->readStyle($objStyle, $style); + foreach ($this->styleReader->getFontCharsets() as $fontName => $charset) { + $excel->addFontCharset($fontName, $charset); + } if ($addingFirstCellXf) { $excel->removeCellXfByIndex(0); // remove the default style $addingFirstCellXf = false; @@ -654,6 +689,7 @@ class Xlsx extends BaseReader } foreach ($cellXfTags as $xfTag) { + /** @var SimpleXMLElement $xfTag */ $xf = self::getAttributes($xfTag); $numFmt = NumberFormat::FORMAT_GENERAL; if ($numFmts && $xf['numFmtId']) { @@ -693,6 +729,7 @@ class Xlsx extends BaseReader $this->styleReader->setNamespace($mainNS); $this->styleReader->setStyleBaseData($theme, $styles, $cellStyles); $dxfs = $this->styleReader->dxfs($this->readDataOnly); + $tableStyles = $this->styleReader->tableStyles($this->readDataOnly); $styles = $this->styleReader->styles(); // Read content after setting the styles @@ -747,6 +784,7 @@ class Xlsx extends BaseReader $charts = $chartDetails = []; + $sheetCreated = false; if ($xmlWorkbookNS->sheets) { foreach ($xmlWorkbookNS->sheets->sheet as $eleSheet) { $eleSheetAttr = self::getAttributes($eleSheet); @@ -773,6 +811,7 @@ class Xlsx extends BaseReader // Load sheet $docSheet = $excel->createSheet(); + $sheetCreated = true; // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet // references in formula cells... during the load, all formulae should be correct, // and we're simply bringing the worksheet name in line with the formula, not the @@ -965,7 +1004,7 @@ class Xlsx extends BaseReader $cAttrS = isset($styles[$cAttrS]) ? $cAttrS : 0; $cell->setXfIndex($cAttrS); // issue 3495 - if ($cellDataType === DataType::TYPE_FORMULA && $styles[$cAttrS]->quotePrefix === true) { + if ($cellDataType === DataType::TYPE_FORMULA && $styles[$cAttrS]->quotePrefix === true) { //* @phpstan-ignore-line $holdSelected = $docSheet->getSelectedCells(); $cell->getStyle()->setQuotePrefix(false); $docSheet->setSelectedCells($holdSelected); @@ -1001,7 +1040,7 @@ class Xlsx extends BaseReader $this->readBackgroundImage($xmlSheetNS, $docSheet, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels'); } - $this->readTables($xmlSheetNS, $docSheet, $dir, $fileWorksheet, $zip, $mainNS); + $this->readTables($xmlSheetNS, $docSheet, $dir, $fileWorksheet, $zip, $mainNS, $tableStyles, $dxfs); if ($xmlSheetNS && $xmlSheetNS->mergeCells && $xmlSheetNS->mergeCells->mergeCell && !$this->readDataOnly) { foreach ($xmlSheetNS->mergeCells->mergeCell as $mergeCellx) { @@ -1040,7 +1079,8 @@ class Xlsx extends BaseReader $childNode = $node->addChild('formula1'); if ($childNode !== null) { // null should never happen // see https://github.com/phpstan/phpstan/issues/8236 - $childNode[0] = (string) $item->formula1->children(Namespaces::DATA_VALIDATIONS2)->f; // @phpstan-ignore-line + // resolved with Phpstan 2.1.23 + $childNode[0] = (string) $item->formula1->children(Namespaces::DATA_VALIDATIONS2)->f; } } } @@ -1057,6 +1097,7 @@ class Xlsx extends BaseReader if ($mc->AlternateContent) { foreach ($mc->AlternateContent as $alternateContent) { $alternateContent = self::testSimpleXml($alternateContent); + /** @var mixed[][][][] $unparsedLoadedData */ $unparsedLoadedData['sheets'][$docSheet->getCodeName()]['AlternateContents'][] = $alternateContent->asXML(); } } @@ -1109,18 +1150,23 @@ class Xlsx extends BaseReader $commentsFile->registerXpathNamespace('com', $mainNS); $authorPath = self::xpathNoFalse($commentsFile, 'com:authors/com:author'); foreach ($authorPath as $author) { + /** @var SimpleXMLElement $author */ $authors[] = (string) $author; } // Loop through contents $contentPath = self::xpathNoFalse($commentsFile, 'com:commentList/com:comment'); foreach ($contentPath as $comment) { + /** @var SimpleXMLElement $comment */ $commentx = $comment->attributes(); + /** @var array{ref: scalar, authorId?: scalar} $commentx */ $commentModel = $docSheet->getComment((string) $commentx['ref']); if (isset($commentx['authorId'])) { $commentModel->setAuthor($authors[(int) $commentx['authorId']]); } - $commentModel->setText($this->parseRichText($comment->children($mainNS)->text)); + /** @var SimpleXMLElement */ + $temp = $comment->children($mainNS); + $commentModel->setText($this->parseRichText($temp->text)); } } @@ -1158,7 +1204,11 @@ class Xlsx extends BaseReader $shapes = self::xpathNoFalse($vmlCommentsFile, '//v:shape'); foreach ($shapes as $shape) { - $shape->registerXPathNamespace('v', Namespaces::URN_VML); + /** @var SimpleXMLElement $shape */ + $vmlNamespaces = $shape->getNamespaces(); + $shape->registerXPathNamespace('v', $vmlNamespaces['v'] ?? Namespaces::URN_VML); + $shape->registerXPathNamespace('x', $vmlNamespaces['x'] ?? Namespaces::URN_EXCEL); + $shape->registerXPathNamespace('o', $vmlNamespaces['o'] ?? Namespaces::URN_MSOFFICE); if (isset($shape['style'])) { $style = (string) $shape['style']; @@ -1179,9 +1229,11 @@ class Xlsx extends BaseReader $textboxDirection = Comment::TEXTBOX_DIRECTION_LTR; } if (is_array($clientData) && !empty($clientData)) { + /** @var SimpleXMLElement */ $clientData = $clientData[0]; if (isset($clientData['ObjectType']) && (string) $clientData['ObjectType'] == 'Note') { + $clientData->registerXPathNamespace('x', $vmlNamespaces['x'] ?? Namespaces::URN_EXCEL); $temp = $clientData->xpath('.//x:Row'); if (is_array($temp)) { $row = $temp[0]; @@ -1208,6 +1260,7 @@ class Xlsx extends BaseReader $fillImageRelNode = $shape->xpath('.//v:fill/@o:relid'); if (is_array($fillImageRelNode) && !empty($fillImageRelNode)) { + /** @var SimpleXMLElement */ $fillImageRelNode = $fillImageRelNode[0]; if (isset($fillImageRelNode['relid'])) { @@ -1217,6 +1270,7 @@ class Xlsx extends BaseReader $fillImageTitleNode = $shape->xpath('.//v:fill/@o:title'); if (is_array($fillImageTitleNode) && !empty($fillImageTitleNode)) { + /** @var SimpleXMLElement */ $fillImageTitleNode = $fillImageTitleNode[0]; if (isset($fillImageTitleNode['title'])) { @@ -1226,9 +1280,9 @@ class Xlsx extends BaseReader if (($column !== null) && ($row !== null)) { // Set comment properties - $comment = $docSheet->getComment([$column + 1, $row + 1]); + $comment = $docSheet->getComment([(int) $column + 1, (int) $row + 1]); $comment->getFillColor()->setRGB($fillColor); - if (isset($drowingImages[$fillImageRelId])) { + if (isset($fillImageRelId, $drowingImages[$fillImageRelId])) { $objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing(); $objDrawing->setName($fillImageTitle); $imagePath = str_replace(['../', '/xl/'], 'xl/', $drowingImages[$fillImageRelId]); @@ -1271,7 +1325,9 @@ class Xlsx extends BaseReader // unparsed vmlDrawing if ($unparsedVmlDrawings) { foreach ($unparsedVmlDrawings as $rId => $relPath) { + /** @var mixed[][][] $unparsedLoadedData */ $rId = substr($rId, 3); // rIdXXX + /** @var mixed[][] */ $unparsedVmlDrawing = &$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['vmlDrawings']; $unparsedVmlDrawing[$rId] = []; $unparsedVmlDrawing[$rId]['filePath'] = self::dirAdd("$dir/$fileWorksheet", $relPath); @@ -1319,6 +1375,7 @@ class Xlsx extends BaseReader $shapes = self::xpathNoFalse($vmlDrawing, '//v:shape'); foreach ($shapes as $idx => $shape) { + /** @var SimpleXMLElement $shape */ $shape->registerXPathNamespace('v', Namespaces::URN_VML); $imageData = $shape->xpath('//v:imagedata'); @@ -1329,6 +1386,7 @@ class Xlsx extends BaseReader $imageData = $imageData[$idx]; $imageData = self::getAttributes($imageData, Namespaces::URN_MSOFFICE); + /** @var array{width: int, height: int, margin-left?: int, margin-top: int} */ $style = self::toCSSArray((string) $shape['style']); if (array_key_exists((string) $imageData['relid'], $drawings)) { @@ -1463,7 +1521,7 @@ class Xlsx extends BaseReader ); if (isset($images[$linkImageKey])) { $url = str_replace('xl/drawings/', '', $images[$linkImageKey]); - $objDrawing->setPath($url, false); + $objDrawing->setPath($url, false, allowExternal: $this->allowExternalImages); } if ($objDrawing->getPath() === '') { continue; @@ -1490,7 +1548,13 @@ class Xlsx extends BaseReader $shadow->setAlignment(self::getArrayItemString(self::getAttributes($outerShdw), 'algn')); $clr = $outerShdw->srgbClr ?? $outerShdw->prstClr; $shadow->getColor()->setRGB(self::getArrayItemString(self::getAttributes($clr), 'val')); - $shadow->setAlpha(self::getArrayItem(self::getAttributes($clr->alpha), 'val') / 1000); + if ($clr->alpha) { + $alpha = StringHelper::convertToString(self::getArrayItem(self::getAttributes($clr->alpha), 'val')); + if (is_numeric($alpha)) { + $alpha = (int) ($alpha / 1000); + $shadow->setAlpha($alpha); + } + } } $this->readHyperLinkDrawing($objDrawing, $oneCellAnchor, $hyperlinks); @@ -1561,7 +1625,7 @@ class Xlsx extends BaseReader ); if (isset($images[$linkImageKey])) { $url = str_replace('xl/drawings/', '', $images[$linkImageKey]); - $objDrawing->setPath($url, false); + $objDrawing->setPath($url, false, allowExternal: $this->allowExternalImages); } if ($objDrawing->getPath() === '') { continue; @@ -1595,7 +1659,13 @@ class Xlsx extends BaseReader $shadow->setAlignment(self::getArrayItemString(self::getAttributes($outerShdw), 'algn')); $clr = $outerShdw->srgbClr ?? $outerShdw->prstClr; $shadow->getColor()->setRGB(self::getArrayItemString(self::getAttributes($clr), 'val')); - $shadow->setAlpha(self::getArrayItem(self::getAttributes($clr->alpha), 'val') / 1000); + if ($clr->alpha) { + $alpha = StringHelper::convertToString(self::getArrayItem(self::getAttributes($clr->alpha), 'val')); + if (is_numeric($alpha)) { + $alpha = (int) ($alpha / 1000); + $shadow->setAlpha($alpha); + } + } } $this->readHyperLinkDrawing($objDrawing, $twoCellAnchor, $hyperlinks); @@ -1651,6 +1721,7 @@ class Xlsx extends BaseReader } // store original rId of drawing files + /** @var mixed[][][][] $unparsedLoadedData */ $unparsedLoadedData['sheets'][$docSheet->getCodeName()]['drawingOriginalIds'] = []; foreach ($relsWorksheet->Relationship as $elex) { $ele = self::getAttributes($elex); @@ -1679,12 +1750,14 @@ class Xlsx extends BaseReader if ($xmlAltDrawing->AlternateContent) { foreach ($xmlAltDrawing->AlternateContent as $alternateContent) { $alternateContent = self::testSimpleXml($alternateContent); + /** @var mixed[][][][][] $unparsedLoadedData */ $unparsedLoadedData['sheets'][$docSheet->getCodeName()]['drawingAlternateContents'][] = $alternateContent->asXML(); } } } } + /** @var mixed[][][][] $unparsedLoadedData */ $this->readFormControlProperties($excel, $dir, $fileWorksheet, $docSheet, $unparsedLoadedData); $this->readPrinterSettings($excel, $dir, $fileWorksheet, $docSheet, $unparsedLoadedData); @@ -1734,7 +1807,7 @@ class Xlsx extends BaseReader $docSheet->getPageSetup()->setColumnsToRepeatAtLeft([$matches[1], $matches[2]]); } elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) { // check for repeating rows, e.g. '1:1' or '1:5' - $docSheet->getPageSetup()->setRowsToRepeatAtTop([$matches[1], $matches[2]]); + $docSheet->getPageSetup()->setRowsToRepeatAtTop([(int) $matches[1], (int) $matches[2]]); } } @@ -1831,6 +1904,9 @@ class Xlsx extends BaseReader } } } + if ($this->createBlankSheetIfNoneRead && !$sheetCreated) { + $excel->createSheet(); + } (new WorkbookView($excel))->viewSettings($xmlWorkbook, $mainNS, $mapSheetId, $this->readDataOnly); @@ -1894,6 +1970,7 @@ class Xlsx extends BaseReader } } + /** @var array|string>>> $unparsedLoadedData */ $excel->setUnparsedLoadedData($unparsedLoadedData); $zip->close(); @@ -2001,7 +2078,9 @@ class Xlsx extends BaseReader // exists and not empty if the ribbon have some pictures (other than internal MSO) $UIRels = simplexml_load_string( $this->getSecurityScannerOrThrow() - ->scan($dataRels) + ->scan($dataRels), + SimpleXMLElement::class, + $this->parseHuge ? LIBXML_PARSEHUGE : 0 ); if (false !== $UIRels) { // we need to save id and target to avoid parsing customUI.xml and "guess" if it's a pseudo callback who load the image @@ -2027,18 +2106,21 @@ class Xlsx extends BaseReader } } + /** @param null|bool|mixed[]|SimpleXMLElement $array */ private static function getArrayItem(null|array|bool|SimpleXMLElement $array, int|string $key = 0): mixed { return ($array === null || is_bool($array)) ? null : ($array[$key] ?? null); } + /** @param null|bool|mixed[]|SimpleXMLElement $array */ private static function getArrayItemString(null|array|bool|SimpleXMLElement $array, int|string $key = 0): string { $retVal = self::getArrayItem($array, $key); - return ($retVal === null || is_scalar($retVal) || $retVal instanceof Stringable) ? ((string) $retVal) : ''; + return StringHelper::convertToString($retVal, false); } + /** @param null|bool|mixed[]|SimpleXMLElement $array */ private static function getArrayItemIntOrSxml(null|array|bool|SimpleXMLElement $array, int|string $key = 0): int|SimpleXMLElement { $retVal = self::getArrayItem($array, $key); @@ -2054,6 +2136,7 @@ class Xlsx extends BaseReader return (string) preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add"); } + /** @return mixed[] */ private static function toCSSArray(string $style): array { $style = self::stripWhiteSpaceFromStyleString($style); @@ -2099,6 +2182,7 @@ class Xlsx extends BaseReader return $value === 'true' || $value === 'TRUE'; } + /** @param string[] $hyperlinks */ private function readHyperLinkDrawing(\PhpOffice\PhpSpreadsheet\Worksheet\Drawing $objDrawing, SimpleXMLElement $cellAnchor, array $hyperlinks): void { $hlinkClick = $cellAnchor->pic->nvPicPr->cNvPr->children(Namespaces::DRAWINGML)->hlinkClick; @@ -2121,23 +2205,79 @@ class Xlsx extends BaseReader return; } - $excel->getSecurity()->setLockRevision(self::getLockValue($xmlWorkbook->workbookProtection, 'lockRevision')); - $excel->getSecurity()->setLockStructure(self::getLockValue($xmlWorkbook->workbookProtection, 'lockStructure')); - $excel->getSecurity()->setLockWindows(self::getLockValue($xmlWorkbook->workbookProtection, 'lockWindows')); + $security = $excel->getSecurity(); + $security->setLockRevision( + self::getLockValue($xmlWorkbook->workbookProtection, 'lockRevision') + ); + $security->setLockStructure( + self::getLockValue($xmlWorkbook->workbookProtection, 'lockStructure') + ); + $security->setLockWindows( + self::getLockValue($xmlWorkbook->workbookProtection, 'lockWindows') + ); if ($xmlWorkbook->workbookProtection['revisionsPassword']) { - $excel->getSecurity()->setRevisionsPassword( + $security->setRevisionsPassword( (string) $xmlWorkbook->workbookProtection['revisionsPassword'], true ); } + if ($xmlWorkbook->workbookProtection['revisionsAlgorithmName']) { + $security->setRevisionsAlgorithmName( + (string) $xmlWorkbook->workbookProtection['revisionsAlgorithmName'] + ); + } + if ($xmlWorkbook->workbookProtection['revisionsSaltValue']) { + $security->setRevisionsSaltValue( + (string) $xmlWorkbook->workbookProtection['revisionsSaltValue'], + false + ); + } + if ($xmlWorkbook->workbookProtection['revisionsSpinCount']) { + $security->setRevisionsSpinCount( + (int) $xmlWorkbook->workbookProtection['revisionsSpinCount'] + ); + } + if ($xmlWorkbook->workbookProtection['revisionsHashValue']) { + if ($security->advancedRevisionsPassword()) { + $security->setRevisionsPassword( + (string) $xmlWorkbook->workbookProtection['revisionsHashValue'], + true + ); + } + } if ($xmlWorkbook->workbookProtection['workbookPassword']) { - $excel->getSecurity()->setWorkbookPassword( + $security->setWorkbookPassword( (string) $xmlWorkbook->workbookProtection['workbookPassword'], true ); } + + if ($xmlWorkbook->workbookProtection['workbookAlgorithmName']) { + $security->setWorkbookAlgorithmName( + (string) $xmlWorkbook->workbookProtection['workbookAlgorithmName'] + ); + } + if ($xmlWorkbook->workbookProtection['workbookSaltValue']) { + $security->setWorkbookSaltValue( + (string) $xmlWorkbook->workbookProtection['workbookSaltValue'], + false + ); + } + if ($xmlWorkbook->workbookProtection['workbookSpinCount']) { + $security->setWorkbookSpinCount( + (int) $xmlWorkbook->workbookProtection['workbookSpinCount'] + ); + } + if ($xmlWorkbook->workbookProtection['workbookHashValue']) { + if ($security->advancedPassword()) { + $security->setWorkbookPassword( + (string) $xmlWorkbook->workbookProtection['workbookHashValue'], + true + ); + } + } } private static function getLockValue(SimpleXMLElement $protection, string $key): ?bool @@ -2152,6 +2292,7 @@ class Xlsx extends BaseReader return $returnValue; } + /** @param mixed[][][][] $unparsedLoadedData */ private function readFormControlProperties(Spreadsheet $excel, string $dir, string $fileWorksheet, Worksheet $docSheet, array &$unparsedLoadedData): void { $zip = $this->zip; @@ -2168,6 +2309,7 @@ class Xlsx extends BaseReader } } + /** @var mixed[][] */ $unparsedCtrlProps = &$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['ctrlProps']; foreach ($ctrlProps as $rId => $ctrlProp) { $rId = substr($rId, 3); // rIdXXX @@ -2179,8 +2321,12 @@ class Xlsx extends BaseReader unset($unparsedCtrlProps); } + /** @param mixed[][][][] $unparsedLoadedData */ private function readPrinterSettings(Spreadsheet $excel, string $dir, string $fileWorksheet, Worksheet $docSheet, array &$unparsedLoadedData): void { + if ($this->readDataOnly) { + return; + } $zip = $this->zip; if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels') === false) { return; @@ -2195,6 +2341,7 @@ class Xlsx extends BaseReader } } + /** @var mixed[][] */ $unparsedPrinterSettings = &$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['printerSettings']; foreach ($sheetPrinterSettings as $rId => $printerSettings) { $rId = substr($rId, 3); // rIdXXX @@ -2210,6 +2357,7 @@ class Xlsx extends BaseReader unset($unparsedPrinterSettings); } + /** @return array{string, string} */ private function getWorkbookBaseName(): array { $workbookBasename = ''; @@ -2291,29 +2439,42 @@ class Xlsx extends BaseReader } } + /** + * @param TableDxfsStyle[] $tableStyles + * @param Style[] $dxfs + */ private function readTables( SimpleXMLElement $xmlSheet, Worksheet $docSheet, string $dir, string $fileWorksheet, ZipArchive $zip, - string $namespaceTable + string $namespaceTable, + array $tableStyles, + array $dxfs ): void { if ($xmlSheet && $xmlSheet->tableParts) { + /** @var array{count: scalar} */ $attributes = $xmlSheet->tableParts->attributes() ?? ['count' => 0]; if (((int) $attributes['count']) > 0) { - $this->readTablesInTablesFile($xmlSheet, $dir, $fileWorksheet, $zip, $docSheet, $namespaceTable); + $this->readTablesInTablesFile($xmlSheet, $dir, $fileWorksheet, $zip, $docSheet, $namespaceTable, $tableStyles, $dxfs); } } } + /** + * @param TableDxfsStyle[] $tableStyles + * @param Style[] $dxfs + */ private function readTablesInTablesFile( SimpleXMLElement $xmlSheet, string $dir, string $fileWorksheet, ZipArchive $zip, Worksheet $docSheet, - string $namespaceTable + string $namespaceTable, + array $tableStyles, + array $dxfs ): void { foreach ($xmlSheet->tableParts->tablePart as $tablePart) { $relation = self::getAttributes($tablePart, Namespaces::SCHEMA_OFFICE_DOCUMENT); @@ -2332,7 +2493,7 @@ class Xlsx extends BaseReader if ($this->fileExistsInArchive($this->zip, $relationshipFilePath)) { $tableXml = $this->loadZip($relationshipFilePath, $namespaceTable); - (new TableReader($docSheet, $tableXml))->load(); + (new TableReader($docSheet, $tableXml))->load($tableStyles, $dxfs); } } } @@ -2340,11 +2501,14 @@ class Xlsx extends BaseReader } } + /** @return mixed[] */ private static function extractStyles(?SimpleXMLElement $sxml, string $node1, string $node2): array { $array = []; if ($sxml && $sxml->{$node1}->{$node2}) { - foreach ($sxml->{$node1}->{$node2} as $node) { + /** @var SimpleXMLElement */ + $temp = $sxml->{$node1}->{$node2}; + foreach ($temp as $node) { $array[] = $node; } } @@ -2352,6 +2516,7 @@ class Xlsx extends BaseReader return $array; } + /** @return string[] */ private static function extractPalette(?SimpleXMLElement $sxml): array { $array = []; @@ -2374,6 +2539,7 @@ class Xlsx extends BaseReader $sqref = (string) ($attributes['sqref'] ?? ''); $numberStoredAsText = (string) ($attributes['numberStoredAsText'] ?? ''); $formula = (string) ($attributes['formula'] ?? ''); + $formulaRange = (string) ($attributes['formulaRange'] ?? ''); $twoDigitTextYear = (string) ($attributes['twoDigitTextYear'] ?? ''); $evalError = (string) ($attributes['evalError'] ?? ''); if (!empty($sqref)) { @@ -2384,16 +2550,15 @@ class Xlsx extends BaseReader $firstRow = $matches[2]; $firstCol = $matches[1]; if (array_key_exists(3, $matches)) { - // https://github.com/phpstan/phpstan/issues/11602 - $lastCol = $matches[4]; // @phpstan-ignore-line - $lastRow = $matches[5]; // @phpstan-ignore-line + $lastCol = $matches[4]; + $lastRow = $matches[5]; } else { $lastCol = $firstCol; $lastRow = $firstRow; } - ++$lastCol; + StringHelper::stringIncrement($lastCol); for ($row = $firstRow; $row <= $lastRow; ++$row) { - for ($col = $firstCol; $col !== $lastCol; ++$col) { + for ($col = $firstCol; $col !== $lastCol; StringHelper::stringIncrement($col)) { if (!$cellCollection->has2("$col$row")) { continue; } @@ -2403,6 +2568,9 @@ class Xlsx extends BaseReader if ($formula === '1') { $sheet->getCell("$col$row")->getIgnoredErrors()->setFormula(true); } + if ($formulaRange === '1') { + $sheet->getCell("$col$row")->getIgnoredErrors()->setFormulaRange(true); + } if ($twoDigitTextYear === '1') { $sheet->getCell("$col$row")->getIgnoredErrors()->setTwoDigitTextYear(true); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php index 49fe360..88a0831 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php @@ -51,6 +51,7 @@ class AutoFilter // Entries can be either filter elements foreach ($filterColumn->filters->filter as $filterRule) { // Operator is undefined, but always treated as EQUAL + /** @var SimpleXMLElement */ $attr2 = $filterRule->attributes() ?? ['val' => '']; $column->createRule()->setRule('', (string) $attr2['val'])->setRuleType(Rule::AUTOFILTER_RULETYPE_FILTER); } @@ -103,6 +104,7 @@ class AutoFilter $column->setJoin(Column::AUTOFILTER_COLUMN_JOIN_AND); } foreach ($customFilters->customFilter as $filterRule) { + /** @var SimpleXMLElement */ $attr2 = $filterRule->attributes() ?? ['operator' => '', 'val' => '']; $column->createRule()->setRule( (string) $attr2['operator'], diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php index beca090..eb79ea7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php @@ -858,6 +858,7 @@ class Chart $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize"); if (isset($seriesDetail->strRef->strCache)) { + /** @var array{formatCode: string, dataValues: mixed[]} */ $seriesData = $this->chartDataSeriesValues($seriesDetail->strRef->strCache->children($this->cNamespace), 's'); $seriesValues ->setFormatCode($seriesData['formatCode']) @@ -869,6 +870,7 @@ class Chart $seriesSource = (string) $seriesDetail->numRef->f; $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize"); if (isset($seriesDetail->numRef->numCache)) { + /** @var array{formatCode: string, dataValues: mixed[]} */ $seriesData = $this->chartDataSeriesValues($seriesDetail->numRef->numCache->children($this->cNamespace)); $seriesValues ->setFormatCode($seriesData['formatCode']) @@ -881,6 +883,7 @@ class Chart $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize"); if (isset($seriesDetail->multiLvlStrRef->multiLvlStrCache)) { + /** @var array{formatCode: string, dataValues: mixed[]} */ $seriesData = $this->chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($this->cNamespace), 's'); $seriesValues ->setFormatCode($seriesData['formatCode']) @@ -893,6 +896,7 @@ class Chart $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize"); if (isset($seriesDetail->multiLvlNumRef->multiLvlNumCache)) { + /** @var array{formatCode: string, dataValues: mixed[]} */ $seriesData = $this->chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($this->cNamespace), 's'); $seriesValues ->setFormatCode($seriesData['formatCode']) @@ -915,6 +919,7 @@ class Chart return null; } + /** @return mixed[] */ private function chartDataSeriesValues(SimpleXMLElement $seriesValueSet, string $dataType = 'n'): array { $seriesVal = []; @@ -953,6 +958,7 @@ class Chart ]; } + /** @return mixed[] */ private function chartDataSeriesValuesMultiLevel(SimpleXMLElement $seriesValueSet, string $dataType = 'n'): array { $seriesVal = []; @@ -1195,31 +1201,42 @@ class Chart if ($fontArray['size'] !== null && $fontArray['size'] >= 100) { $fontArray['size'] /= 100.0; } - $fontArray['bold'] = self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'b'); - $fontArray['italic'] = self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'i'); + if ($fontArray['size'] !== null) { + $fontArray['size'] = (int) ($fontArray['size']); + } + $fontArray['bold'] = (bool) self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'b'); + $fontArray['italic'] = (bool) self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'i'); $fontArray['underscore'] = self::getAttributeString($titleDetailPart->pPr->defRPr, 'u'); - $fontArray['strikethrough'] = self::getAttributeString($titleDetailPart->pPr->defRPr, 'strike'); - $fontArray['cap'] = self::getAttributeString($titleDetailPart->pPr->defRPr, 'cap'); + $strikethrough = self::getAttributeString($titleDetailPart->pPr->defRPr, 'strike'); + if ($strikethrough !== null) { + if ($strikethrough == 'noStrike') { + $fontArray['strikethrough'] = false; + } else { + $fontArray['strikethrough'] = true; + } + } + $fontArray['cap'] = (string) self::getAttributeString($titleDetailPart->pPr->defRPr, 'cap'); if (isset($titleDetailPart->pPr->defRPr->latin)) { - $fontArray['latin'] = self::getAttributeString($titleDetailPart->pPr->defRPr->latin, 'typeface'); + $fontArray['latin'] = (string) self::getAttributeString($titleDetailPart->pPr->defRPr->latin, 'typeface'); } if (isset($titleDetailPart->pPr->defRPr->ea)) { - $fontArray['eastAsian'] = self::getAttributeString($titleDetailPart->pPr->defRPr->ea, 'typeface'); + $fontArray['eastAsian'] = (string) self::getAttributeString($titleDetailPart->pPr->defRPr->ea, 'typeface'); } if (isset($titleDetailPart->pPr->defRPr->cs)) { - $fontArray['complexScript'] = self::getAttributeString($titleDetailPart->pPr->defRPr->cs, 'typeface'); + $fontArray['complexScript'] = (string) self::getAttributeString($titleDetailPart->pPr->defRPr->cs, 'typeface'); } if (isset($titleDetailPart->pPr->defRPr->solidFill)) { $fontArray['chartColor'] = new ChartColor($this->readColor($titleDetailPart->pPr->defRPr->solidFill)); } $font = new Font(); - $font->setSize(null, true); + //$font->setSize(null, true); $font->applyFromArray($fontArray); return $font; } + /** @return mixed[] */ private function readChartAttributes(?SimpleXMLElement $chartDetail): array { $plotAttributes = []; @@ -1277,9 +1294,11 @@ class Chart return $plotAttributes; } + /** @param array $plotAttributes */ private function setChartAttributes(Layout $plotArea, array $plotAttributes): void { foreach ($plotAttributes as $plotAttributeKey => $plotAttributeValue) { + /** @var ?bool $plotAttributeValue */ switch ($plotAttributeKey) { case 'showLegendKey': $plotArea->setShowLegendKey($plotAttributeValue); @@ -1310,6 +1329,7 @@ class Chart break; case 'labelFont': + /** @var ?Font $plotAttributeValue */ $plotArea->setLabelFont($plotAttributeValue); break; @@ -1397,6 +1417,7 @@ class Chart 'innerShdw', ]; + /** @return array{type: ?string, value: ?string, alpha: ?int, brightness: ?int} */ private function readColor(SimpleXMLElement $colorXml): array { $result = [ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php index cf9046c..347b1b4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter; use PhpOffice\PhpSpreadsheet\Reader\IReadFilter; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use SimpleXMLElement; @@ -24,8 +25,7 @@ class ColumnAndRowAttributes extends BaseParserClass * Set Worksheet column attributes by attributes array passed. * * @param string $columnAddress A, B, ... DX, ... - * @param array $columnAttributes array of attributes (indexes are attribute name, values are value) - * 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'width', ... ? + * @param array{xfIndex?: int, visible?: bool, collapsed?: bool, collapsed?: bool, outlineLevel?: int, rowHeight?: float, width?: int} $columnAttributes array of attributes (indexes are attribute name, values are value) */ private function setColumnAttributes(string $columnAddress, array $columnAttributes): void { @@ -50,32 +50,43 @@ class ColumnAndRowAttributes extends BaseParserClass * Set Worksheet row attributes by attributes array passed. * * @param int $rowNumber 1, 2, 3, ... 99, ... - * @param array $rowAttributes array of attributes (indexes are attribute name, values are value) + * @param array{xfIndex?: int, visible?: bool, collapsed?: bool, collapsed?: bool, outlineLevel?: int, rowHeight?: float, customFormat?: bool, ht?: float} $rowAttributes array of attributes (indexes are attribute name, values are value) * 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'rowHeight', ... ? */ private function setRowAttributes(int $rowNumber, array $rowAttributes): void { if (isset($rowAttributes['xfIndex'])) { - $this->worksheet->getRowDimension($rowNumber)->setXfIndex($rowAttributes['xfIndex']); + $this->worksheet->getRowDimension($rowNumber) + ->setXfIndex($rowAttributes['xfIndex']); } if (isset($rowAttributes['visible'])) { - $this->worksheet->getRowDimension($rowNumber)->setVisible($rowAttributes['visible']); + $this->worksheet->getRowDimension($rowNumber) + ->setVisible($rowAttributes['visible']); } if (isset($rowAttributes['collapsed'])) { - $this->worksheet->getRowDimension($rowNumber)->setCollapsed($rowAttributes['collapsed']); + $this->worksheet->getRowDimension($rowNumber) + ->setCollapsed($rowAttributes['collapsed']); } if (isset($rowAttributes['outlineLevel'])) { - $this->worksheet->getRowDimension($rowNumber)->setOutlineLevel($rowAttributes['outlineLevel']); + $this->worksheet->getRowDimension($rowNumber) + ->setOutlineLevel($rowAttributes['outlineLevel']); } - if (isset($rowAttributes['rowHeight'])) { - $this->worksheet->getRowDimension($rowNumber)->setRowHeight($rowAttributes['rowHeight']); + if (isset($rowAttributes['customFormat'], $rowAttributes['rowHeight'])) { + $this->worksheet->getRowDimension($rowNumber) + ->setCustomFormat($rowAttributes['customFormat'], $rowAttributes['rowHeight']); + } elseif (isset($rowAttributes['rowHeight'])) { + $this->worksheet->getRowDimension($rowNumber) + ->setRowHeight($rowAttributes['rowHeight']); } } - public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false, bool $ignoreRowsWithNoCells = false): void + public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false, bool $ignoreRowsWithNoCells = false): bool { if ($this->worksheetXml === null) { - return; + return false; + } + if ($readFilter !== null && $readFilter::class === DefaultReadFilter::class) { + $readFilter = null; } $columnsAttributes = []; @@ -85,11 +96,7 @@ class ColumnAndRowAttributes extends BaseParserClass } if ($this->worksheetXml->sheetData && $this->worksheetXml->sheetData->row) { - $rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly, $ignoreRowsWithNoCells); - } - - if ($readFilter !== null && $readFilter::class === DefaultReadFilter::class) { - $readFilter = null; + $rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly, $ignoreRowsWithNoCells, $readFilter !== null); } // set columns/rows attributes @@ -100,6 +107,7 @@ class ColumnAndRowAttributes extends BaseParserClass || !$this->isFilteredColumn($readFilter, $columnCoordinate, $rowsAttributes) ) { if (!isset($columnsAttributesAreSet[$columnCoordinate])) { + /** @var array{xfIndex?: int, visible?: bool, collapsed?: bool, collapsed?: bool, outlineLevel?: int, rowHeight?: float, width?: int} $columnAttributes */ $this->setColumnAttributes($columnCoordinate, $columnAttributes); $columnsAttributesAreSet[$columnCoordinate] = true; } @@ -113,24 +121,29 @@ class ColumnAndRowAttributes extends BaseParserClass || !$this->isFilteredRow($readFilter, $rowCoordinate, $columnsAttributes) ) { if (!isset($rowsAttributesAreSet[$rowCoordinate])) { + /** @var array{xfIndex?: int, visible?: bool, collapsed?: bool, collapsed?: bool, outlineLevel?: int, rowHeight?: float} $rowAttributes */ $this->setRowAttributes($rowCoordinate, $rowAttributes); $rowsAttributesAreSet[$rowCoordinate] = true; } } } + + return true; } + /** @param mixed[] $rowsAttributes */ private function isFilteredColumn(IReadFilter $readFilter, string $columnCoordinate, array $rowsAttributes): bool { foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) { - if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) { - return true; + if ($readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) { + return false; } } - return false; + return true; } + /** @return mixed[] */ private function readColumnAttributes(SimpleXMLElement $worksheetCols, bool $readDataOnly): array { $columnAttributes = []; @@ -140,8 +153,8 @@ class ColumnAndRowAttributes extends BaseParserClass if ($column !== null) { $startColumn = Coordinate::stringFromColumnIndex((int) $column['min']); $endColumn = Coordinate::stringFromColumnIndex((int) $column['max']); - ++$endColumn; - for ($columnAddress = $startColumn; $columnAddress !== $endColumn; ++$columnAddress) { + StringHelper::stringIncrement($endColumn); + for ($columnAddress = $startColumn; $columnAddress !== $endColumn; StringHelper::stringIncrement($columnAddress)) { $columnAttributes[$columnAddress] = $this->readColumnRangeAttributes($column, $readDataOnly); if ((int) ($column['max']) == 16384) { @@ -154,6 +167,7 @@ class ColumnAndRowAttributes extends BaseParserClass return $columnAttributes; } + /** @return mixed[] */ private function readColumnRangeAttributes(?SimpleXMLElement $column, bool $readDataOnly): array { $columnAttributes = []; @@ -178,6 +192,7 @@ class ColumnAndRowAttributes extends BaseParserClass return $columnAttributes; } + /** @param mixed[] $columnsAttributes */ private function isFilteredRow(IReadFilter $readFilter, int $rowCoordinate, array $columnsAttributes): bool { foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) { @@ -189,27 +204,37 @@ class ColumnAndRowAttributes extends BaseParserClass return false; } - private function readRowAttributes(SimpleXMLElement $worksheetRow, bool $readDataOnly, bool $ignoreRowsWithNoCells): array + /** @return mixed[] */ + private function readRowAttributes(SimpleXMLElement $worksheetRow, bool $readDataOnly, bool $ignoreRowsWithNoCells, bool $readFilterIsNotNull): array { $rowAttributes = []; foreach ($worksheetRow as $rowx) { $row = $rowx->attributes(); if ($row !== null && (!$ignoreRowsWithNoCells || isset($rowx->c))) { - if (isset($row['ht']) && !$readDataOnly) { - $rowAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht']; + $rowIndex = (int) $row['r']; + if (!$readDataOnly) { + if (isset($row['ht'])) { + $rowAttributes[$rowIndex]['rowHeight'] = (float) $row['ht']; + } + if (isset($row['customFormat']) && self::boolean($row['customFormat'])) { + $rowAttributes[$rowIndex]['customFormat'] = true; + } + if (isset($row['hidden']) && self::boolean($row['hidden'])) { + $rowAttributes[$rowIndex]['visible'] = false; + } + if (isset($row['collapsed']) && self::boolean($row['collapsed'])) { + $rowAttributes[$rowIndex]['collapsed'] = true; + } + if (isset($row['outlineLevel']) && (int) $row['outlineLevel'] > 0) { + $rowAttributes[$rowIndex]['outlineLevel'] = (int) $row['outlineLevel']; + } + if (isset($row['s'])) { + $rowAttributes[$rowIndex]['xfIndex'] = (int) $row['s']; + } } - if (isset($row['hidden']) && self::boolean($row['hidden'])) { - $rowAttributes[(int) $row['r']]['visible'] = false; - } - if (isset($row['collapsed']) && self::boolean($row['collapsed'])) { - $rowAttributes[(int) $row['r']]['collapsed'] = true; - } - if (isset($row['outlineLevel']) && (int) $row['outlineLevel'] > 0) { - $rowAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel']; - } - if (isset($row['s']) && !$readDataOnly) { - $rowAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s']; + if ($readFilterIsNotNull && empty($rowAttributes[$rowIndex])) { + $rowAttributes[$rowIndex]['exists'] = true; } } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php index a03fa71..e2cf3b2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php @@ -9,6 +9,8 @@ use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalColorScale; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormatValueObject; +use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalIconSet; +use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\IconSetValues; use PhpOffice\PhpSpreadsheet\Style\Style as Style; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use SimpleXMLElement; @@ -20,12 +22,15 @@ class ConditionalStyles private SimpleXMLElement $worksheetXml; + /** @var string[] */ private array $ns; + /** @var Style[] */ private array $dxfs; private StyleReader $styleReader; + /** @param Style[] $dxfs */ public function __construct(Worksheet $workSheet, SimpleXMLElement $worksheetXml, array $dxfs, StyleReader $styleReader) { $this->worksheet = $workSheet; @@ -59,17 +64,24 @@ class ConditionalStyles $this->worksheet->setSelectedCells($selectedCells); } + /** @param Conditional[][] $conditionals */ private function setConditionalsFromExt(array $conditionals): void { foreach ($conditionals as $conditionalRange => $cfRules) { ksort($cfRules); // Priority is used as the key for sorting; but may not start at 0, // so we use array_values to reset the index after sorting. + $existing = $this->worksheet->getConditionalStylesCollection(); + if (array_key_exists($conditionalRange, $existing)) { + $conditionalStyle = $existing[$conditionalRange]; + $cfRules = array_merge($conditionalStyle, $cfRules); + } $this->worksheet->getStyle($conditionalRange) ->setConditionalStyles(array_values($cfRules)); } } + /** @return array> */ private function readConditionalsFromExt(SimpleXMLElement $extLst): array { $conditionals = []; @@ -126,6 +138,7 @@ class ConditionalStyles $conditionType = (string) $attributes->type; $operatorType = (string) $attributes->operator; $priority = (int) (string) $attributes->priority; + $stopIfTrue = (int) (string) $attributes->stopIfTrue; $operands = []; foreach ($cfRuleXml->children($this->ns['xm']) as $cfRuleOperandsXml) { @@ -136,6 +149,7 @@ class ConditionalStyles $conditional->setConditionType($conditionType); $conditional->setOperatorType($operatorType); $conditional->setPriority($priority); + $conditional->setStopIfTrue($stopIfTrue === 1); if ( $conditionType === Conditional::CONDITION_CONTAINSTEXT || $conditionType === Conditional::CONDITION_NOTCONTAINSTEXT @@ -162,11 +176,15 @@ class ConditionalStyles if ($styleXML->fill) { $this->styleReader->readFillStyle($cfStyle->getFill(), $styleXML->fill); } + if ($styleXML->font) { + $this->styleReader->readFontStyle($cfStyle->getFont(), $styleXML->font); + } } return $cfStyle; } + /** @return mixed[] */ private function readConditionalStyles(SimpleXMLElement $xmlSheet): array { $conditionals = []; @@ -183,9 +201,11 @@ class ConditionalStyles return $conditionals; } + /** @param mixed[] $conditionals */ private function setConditionalStyles(Worksheet $worksheet, array $conditionals, SimpleXMLElement $xmlExtLst): void { foreach ($conditionals as $cellRangeReference => $cfRules) { + /** @var mixed[] $cfRules */ ksort($cfRules); // no longer needed for Xlsx, but helps Xls $conditionalStyles = $this->readStyleRules($cfRules, $xmlExtLst); @@ -193,12 +213,25 @@ class ConditionalStyles // N.B. In Excel UI, intersection is space and union is comma. // But in Xml, intersection is comma and union is space. $cellRangeReference = str_replace(['$', ' ', ',', '^'], ['', '^', ' ', ','], strtoupper($cellRangeReference)); + + foreach ($conditionalStyles as $cs) { + $scale = $cs->getColorScale(); + if ($scale !== null) { + $scale->setSqRef($cellRangeReference, $worksheet); + } + } $worksheet->getStyle($cellRangeReference)->setConditionalStyles($conditionalStyles); } } + /** + * @param mixed[] $cfRules + * + * @return Conditional[] + */ private function readStyleRules(array $cfRules, SimpleXMLElement $extLst): array { + /** @var ConditionalFormattingRuleExtension[] */ $conditionalFormattingRuleExtensions = ConditionalFormattingRuleExtension::parseExtLstXml($extLst); $conditionalStyles = []; @@ -244,6 +277,8 @@ class ConditionalStyles $objConditional->setColorScale( $this->readColorScale($cfRule) ); + } elseif (isset($cfRule->iconSet)) { + $objConditional->setIconSet($this->readIconSet($cfRule)); } elseif (isset($cfRule['dxfId'])) { $objConditional->setStyle(clone $this->dxfs[(int) ($cfRule['dxfId'])]); } @@ -254,6 +289,7 @@ class ConditionalStyles return $conditionalStyles; } + /** @param ConditionalFormattingRuleExtension[] $conditionalFormattingRuleExtensions */ private function readDataBarOfConditionalRule(SimpleXMLElement $cfRule, array $conditionalFormattingRuleExtensions): ConditionalDataBar { $dataBar = new ConditionalDataBar(); @@ -267,6 +303,7 @@ class ConditionalStyles $cfvoXml = $cfRule->dataBar->cfvo; $cfvoIndex = 0; foreach ((count($cfvoXml) > 1 ? $cfvoXml : [$cfvoXml]) as $cfvo) { //* @phpstan-ignore-line + /** @var SimpleXMLElement $cfvo */ if ($cfvoIndex === 0) { $dataBar->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo['type'], (string) $cfvo['val'])); } @@ -289,6 +326,7 @@ class ConditionalStyles private function readColorScale(SimpleXMLElement|stdClass $cfRule): ConditionalColorScale { $colorScale = new ConditionalColorScale(); + /** @var SimpleXMLElement $cfRule */ $count = count($cfRule->colorScale->cfvo); $idx = 0; foreach ($cfRule->colorScale->cfvo as $cfvoXml) { @@ -325,11 +363,47 @@ class ConditionalStyles return $colorScale; } + private function readIconSet(SimpleXMLElement $cfRule): ConditionalIconSet + { + $iconSet = new ConditionalIconSet(); + + if (isset($cfRule->iconSet['iconSet'])) { + $iconSet->setIconSetType(IconSetValues::from($cfRule->iconSet['iconSet'])); + } + if (isset($cfRule->iconSet['reverse'])) { + $iconSet->setReverse('1' === (string) $cfRule->iconSet['reverse']); + } + if (isset($cfRule->iconSet['showValue'])) { + $iconSet->setShowValue('1' === (string) $cfRule->iconSet['showValue']); + } + if (isset($cfRule->iconSet['custom'])) { + $iconSet->setCustom('1' === (string) $cfRule->iconSet['custom']); + } + + $cfvos = []; + foreach ($cfRule->iconSet->cfvo as $cfvoXml) { + $type = (string) $cfvoXml['type']; + $value = (string) ($cfvoXml['val'] ?? ''); + $cfvo = new ConditionalFormatValueObject($type, $value); + if (isset($cfvoXml['gte'])) { + $cfvo->setGreaterThanOrEqual('1' === (string) $cfvoXml['gte']); + } + $cfvos[] = $cfvo; + } + $iconSet->setCfvos($cfvos); + + // TODO: The cfIcon element is not implemented yet. + + return $iconSet; + } + + /** @param ConditionalFormattingRuleExtension[] $conditionalFormattingRuleExtensions */ private function readDataBarExtLstOfConditionalRule(ConditionalDataBar $dataBar, SimpleXMLElement $cfRule, array $conditionalFormattingRuleExtensions): void { if (isset($cfRule->extLst)) { $ns = $cfRule->extLst->getNamespaces(true); foreach ((count($cfRule->extLst) > 0 ? $cfRule->extLst->ext : [$cfRule->extLst->ext]) as $ext) { //* @phpstan-ignore-line + /** @var SimpleXMLElement $ext */ $extId = (string) $ext->children($ns['x14'])->id; if (isset($conditionalFormattingRuleExtensions[$extId]) && (string) $ext['uri'] === '{B025F937-C7B1-47D3-B67F-A62EFF666E3E}') { $dataBar->setConditionalFormattingRuleExt($conditionalFormattingRuleExtensions[$extId]); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php index 3eae5bb..2c2d4af 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php @@ -11,6 +11,7 @@ class Hyperlinks { private Worksheet $worksheet; + /** @var string[] */ private array $hyperlinks = []; public function __construct(Worksheet $workSheet) @@ -44,7 +45,7 @@ class Hyperlinks foreach (Coordinate::extractAllCellReferencesInRange($attributes->ref) as $cellReference) { $cell = $worksheet->getCell($cellReference); if (isset($linkRel['id'])) { - $hyperlinkUrl = $this->hyperlinks[(string) $linkRel['id']] ?? null; + $hyperlinkUrl = $this->hyperlinks[(string) $linkRel['id']] ?? ''; if (isset($attributes['location'])) { $hyperlinkUrl .= '#' . (string) $attributes['location']; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php index 5e6cc88..766154e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php @@ -18,6 +18,11 @@ class PageSetup extends BaseParserClass $this->worksheetXml = $worksheetXml; } + /** + * @param mixed[] $unparsedLoadedData + * + * @return mixed[] + */ public function load(array $unparsedLoadedData): array { $worksheetXml = $this->worksheetXml; @@ -46,6 +51,11 @@ class PageSetup extends BaseParserClass } } + /** + * @param mixed[] $unparsedLoadedData + * + * @return mixed[] + */ private function pageSetup(SimpleXMLElement $xmlSheet, Worksheet $worksheet, array $unparsedLoadedData): array { if ($xmlSheet->pageSetup) { @@ -82,6 +92,7 @@ class PageSetup extends BaseParserClass if (!str_ends_with($relid, 'ps')) { $relid .= 'ps'; } + /** @var mixed[][][] $unparsedLoadedData */ $unparsedLoadedData['sheets'][$worksheet->getCodeName()]['pageSetupRelId'] = $relid; } } @@ -149,7 +160,7 @@ class PageSetup extends BaseParserClass private function rowBreaks(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void { foreach ($xmlSheet->rowBreaks->brk as $brk) { - $rowBreakMax = isset($brk['max']) ? ((int) $brk['max']) : -1; + $rowBreakMax = /*isset($brk['max']) ? ((int) $brk['max']) :*/ -1; if ($brk['man']) { $worksheet->setBreak("A{$brk['id']}", Worksheet::BREAK_ROW, $rowBreakMax); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Properties.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Properties.php index 1a0517b..a792235 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Properties.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Properties.php @@ -79,7 +79,9 @@ class Properties $cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); $attributeType = $cellDataOfficeChildren->getName(); - $attributeValue = (string) $cellDataOfficeChildren->{$attributeType}; + /** @var SimpleXMLElement */ + $attributeValue = $cellDataOfficeChildren->{$attributeType}; + $attributeValue = (string) $attributeValue; $attributeValue = DocumentProperties::convertProperty($attributeValue, $attributeType); $attributeType = DocumentProperties::convertPropertyType($attributeType); $this->docProps->setCustomProperty($propertyName, $attributeValue, $attributeType); @@ -88,6 +90,7 @@ class Properties } } + /** @param null|false|scalar[] $array */ private function getArrayItem(null|array|false $array): string { return is_array($array) ? (string) ($array[0] ?? '') : ''; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Styles.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Styles.php index 4b1a7d3..54e26e7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Styles.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Styles.php @@ -12,6 +12,7 @@ use PhpOffice\PhpSpreadsheet\Style\Font; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\Protection; use PhpOffice\PhpSpreadsheet\Style\Style; +use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableDxfsStyle; use SimpleXMLElement; use stdClass; @@ -22,21 +23,34 @@ class Styles extends BaseParserClass */ private ?Theme $theme = null; + /** @var string[] */ private array $workbookPalette = []; + /** @var mixed[] */ private array $styles = []; + /** @var array */ private array $cellStyles = []; private SimpleXMLElement $styleXml; private string $namespace = ''; + /** @var array */ + private array $fontCharsets = []; + + /** @return array */ + public function getFontCharsets(): array + { + return $this->fontCharsets; + } + public function setNamespace(string $namespace): void { $this->namespace = $namespace; } + /** @param string[] $palette */ public function setWorkbookPalette(array $palette): void { $this->workbookPalette = $palette; @@ -62,6 +76,10 @@ class Styles extends BaseParserClass $this->theme = $theme; } + /** + * @param mixed[] $styles + * @param array $cellStyles + */ public function setStyleBaseData(?Theme $theme = null, array $styles = [], array $cellStyles = []): void { $this->theme = $theme; @@ -76,6 +94,13 @@ class Styles extends BaseParserClass if (isset($attr['val'])) { $fontStyle->setName((string) $attr['val']); } + if (isset($fontStyleXml->charset)) { + $charsetAttr = $this->getStyleAttributes($fontStyleXml->charset); + if (isset($charsetAttr['val'])) { + $charsetVal = (int) $charsetAttr['val']; + $this->fontCharsets[$fontStyle->getName()] = $charsetVal; + } + } } if (isset($fontStyleXml->sz)) { $attr = $this->getStyleAttributes($fontStyleXml->sz); @@ -95,7 +120,14 @@ class Styles extends BaseParserClass $attr = $this->getStyleAttributes($fontStyleXml->strike); $fontStyle->setStrikethrough(!isset($attr['val']) || self::boolean((string) $attr['val'])); } - $fontStyle->getColor()->setARGB($this->readColor($fontStyleXml->color)); + $fontStyle->getColor() + ->setARGB( + $this->readColor($fontStyleXml->color) + ); + $theme = $this->readColorTheme($fontStyleXml->color); + if ($theme >= 0) { + $fontStyle->getColor()->setTheme($theme); + } if (isset($fontStyleXml->u)) { $attr = $this->getStyleAttributes($fontStyleXml->u); @@ -120,6 +152,12 @@ class Styles extends BaseParserClass $attr = $this->getStyleAttributes($fontStyleXml->scheme); $fontStyle->setScheme((string) $attr['val']); } + if (isset($fontStyleXml->auto)) { + $attr = $this->getStyleAttributes($fontStyleXml->auto); + if (isset($attr['val'])) { + $fontStyle->setAutoColor(self::boolean((string) $attr['val'])); + } + } } private function readNumberFormat(NumberFormat $numfmtStyle, SimpleXMLElement $numfmtStyleXml): void @@ -309,9 +347,12 @@ class Styles extends BaseParserClass if ($style instanceof SimpleXMLElement) { $this->readNumberFormat($docStyle->getNumberFormat(), $style->numFmt); } else { - $docStyle->getNumberFormat()->setFormatCode(self::formatGeneral((string) $style->numFmt)); + /** @var SimpleXMLElement */ + $temp = $style->numFmt; + $docStyle->getNumberFormat()->setFormatCode(self::formatGeneral((string) $temp)); } + /** @var SimpleXMLElement $style */ if (isset($style->font)) { $this->readFontStyle($docStyle->getFont(), $style->font); } @@ -386,6 +427,17 @@ class Styles extends BaseParserClass } } + public function readColorTheme(SimpleXMLElement $color): int + { + $attr = $this->getStyleAttributes($color); + $retVal = -1; + if (isset($attr['theme']) && is_numeric((string) $attr['theme']) && !isset($attr['tint'])) { + $retVal = (int) $attr['theme']; + } + + return $retVal; + } + public function readColor(SimpleXMLElement $color, bool $background = false): string { $attr = $this->getStyleAttributes($color); @@ -415,6 +467,7 @@ class Styles extends BaseParserClass return ($background) ? 'FFFFFFFF' : 'FF000000'; } + /** @return Style[] */ public function dxfs(bool $readDataOnly = false): array { $dxfs = []; @@ -447,6 +500,47 @@ class Styles extends BaseParserClass return $dxfs; } + /** @return TableDxfsStyle[] */ + public function tableStyles(bool $readDataOnly = false): array + { + $tableStyles = []; + if (!$readDataOnly && $this->styleXml) { + // Conditional Styles + if ($this->styleXml->tableStyles) { + foreach ($this->styleXml->tableStyles->tableStyle as $s) { + $attrs = Xlsx::getAttributes($s); + if (isset($attrs['name'][0])) { + $style = new TableDxfsStyle((string) ($attrs['name'][0])); + foreach ($s->tableStyleElement as $e) { + $a = Xlsx::getAttributes($e); + if (isset($a['dxfId'][0], $a['type'][0])) { + switch ($a['type'][0]) { + case 'headerRow': + $style->setHeaderRow((int) ($a['dxfId'][0])); + + break; + case 'firstRowStripe': + $style->setFirstRowStripe((int) ($a['dxfId'][0])); + + break; + case 'secondRowStripe': + $style->setSecondRowStripe((int) ($a['dxfId'][0])); + + break; + default: + } + } + } + $tableStyles[] = $style; + } + } + } + } + + return $tableStyles; + } + + /** @return mixed[] */ public function styles(): array { return $this->styles; @@ -455,10 +549,10 @@ class Styles extends BaseParserClass /** * Get array item. * - * @param mixed $array (usually array, in theory can be false) + * @param false|mixed[] $array (usually array, in theory can be false) */ private static function getArrayItem(mixed $array): ?SimpleXMLElement { - return is_array($array) ? ($array[0] ?? null) : null; + return is_array($array) ? ($array[0] ?? null) : null; // @phpstan-ignore-line } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php index a63c817..121697c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php @@ -2,7 +2,9 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx; +use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Table; +use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableDxfsStyle; use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableStyle; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use SimpleXMLElement; @@ -13,7 +15,7 @@ class TableReader private SimpleXMLElement $tableXml; - /** @var array|SimpleXMLElement */ + /** @var mixed[]|SimpleXMLElement */ private $tableAttributes; public function __construct(Worksheet $workSheet, SimpleXMLElement $tableXml) @@ -24,30 +26,38 @@ class TableReader /** * Loads Table into the Worksheet. + * + * @param TableDxfsStyle[] $tableStyles + * @param Style[] $dxfs */ - public function load(): void + public function load(array $tableStyles, array $dxfs): void { $this->tableAttributes = $this->tableXml->attributes() ?? []; // Remove all "$" in the table range $tableRange = (string) preg_replace('/\$/', '', $this->tableAttributes['ref'] ?? ''); if (str_contains($tableRange, ':')) { - $this->readTable($tableRange); + $this->readTable($tableRange, $tableStyles, $dxfs); } } /** * Read Table from xml. + * + * @param TableDxfsStyle[] $tableStyles + * @param Style[] $dxfs */ - private function readTable(string $tableRange): void + private function readTable(string $tableRange, array $tableStyles, array $dxfs): void { $table = new Table($tableRange); - $table->setName((string) ($this->tableAttributes['displayName'] ?? '')); - $table->setShowHeaderRow(((string) ($this->tableAttributes['headerRowCount'] ?? '')) !== '0'); - $table->setShowTotalsRow(((string) ($this->tableAttributes['totalsRowCount'] ?? '')) === '1'); + /** @var string[] */ + $attributes = $this->tableAttributes; + $table->setName((string) ($attributes['displayName'] ?? '')); + $table->setShowHeaderRow(((string) ($attributes['headerRowCount'] ?? '')) !== '0'); + $table->setShowTotalsRow(((string) ($attributes['totalsRowCount'] ?? '')) === '1'); $this->readTableAutoFilter($table, $this->tableXml->autoFilter); $this->readTableColumns($table, $this->tableXml->tableColumns); - $this->readTableStyle($table, $this->tableXml->tableStyleInfo); + $this->readTableStyle($table, $this->tableXml->tableStyleInfo, $tableStyles, $dxfs); (new AutoFilter($table, $this->tableXml))->load(); $this->worksheet->addTable($table); @@ -65,6 +75,7 @@ class TableReader } foreach ($autoFilterXml->filterColumn as $filterColumn) { + /** @var SimpleXMLElement */ $attributes = $filterColumn->attributes() ?? ['colId' => 0, 'hiddenButton' => 0]; $column = $table->getColumnByOffset((int) $attributes['colId']); $column->setShowFilterButton(((string) $attributes['hiddenButton']) !== '1'); @@ -78,6 +89,7 @@ class TableReader { $offset = 0; foreach ($tableColumnsXml->tableColumn as $tableColumn) { + /** @var SimpleXMLElement */ $attributes = $tableColumn->attributes() ?? ['totalsRowLabel' => 0, 'totalsRowFunction' => 0]; $column = $table->getColumnByOffset($offset++); @@ -99,8 +111,11 @@ class TableReader /** * Reads TableStyle from xml. + * + * @param TableDxfsStyle[] $tableStyles + * @param Style[] $dxfs */ - private function readTableStyle(Table $table, SimpleXMLElement $tableStyleInfoXml): void + private function readTableStyle(Table $table, SimpleXMLElement $tableStyleInfoXml, array $tableStyles, array $dxfs): void { $tableStyle = new TableStyle(); $attributes = $tableStyleInfoXml->attributes(); @@ -110,6 +125,12 @@ class TableReader $tableStyle->setShowColumnStripes((string) $attributes['showColumnStripes'] === '1'); $tableStyle->setShowFirstColumn((string) $attributes['showFirstColumn'] === '1'); $tableStyle->setShowLastColumn((string) $attributes['showLastColumn'] === '1'); + + foreach ($tableStyles as $style) { + if ($style->getName() === (string) $attributes['name']) { + $tableStyle->setTableDxfsStyle($style, $dxfs); + } + } } $table->setStyle($tableStyle); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php index f02de9a..429efb0 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php @@ -14,6 +14,7 @@ class WorkbookView $this->spreadsheet = $spreadsheet; } + /** @param array $mapSheetId */ public function viewSettings(SimpleXMLElement $xmlWorkbook, string $mainNS, array $mapSheetId, bool $readDataOnly): void { // Default active sheet index to the first loaded worksheet from the file diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php index df370b2..08aa7f4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php @@ -17,6 +17,7 @@ use PhpOffice\PhpSpreadsheet\Reader\Xml\Style; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\File; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\SheetView; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; @@ -32,6 +33,8 @@ class Xml extends BaseReader /** * Formats. + * + * @var mixed[] */ protected array $styles = []; @@ -60,6 +63,7 @@ class Xml extends BaseReader private string $xmlFailMessage = ''; + /** @return mixed[] */ public static function xmlMappings(): array { return array_merge( @@ -145,6 +149,8 @@ class Xml extends BaseReader /** * Reads names of the worksheets from a file, without parsing the whole file to a Spreadsheet object. + * + * @return string[] */ public function listWorksheetNames(string $filename): array { @@ -171,6 +177,8 @@ class Xml extends BaseReader /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). + * + * @return array */ public function listWorksheetInfo(string $filename): array { @@ -243,8 +251,7 @@ class Xml extends BaseReader */ public function loadSpreadsheetFromString(string $contents): Spreadsheet { - // Create new Spreadsheet - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->newSpreadsheet(); $spreadsheet->setValueBinder($this->valueBinder); $spreadsheet->removeSheetByIndex(0); @@ -257,8 +264,7 @@ class Xml extends BaseReader */ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet { - // Create new Spreadsheet - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->newSpreadsheet(); $spreadsheet->setValueBinder($this->valueBinder); $spreadsheet->removeSheetByIndex(0); @@ -294,13 +300,14 @@ class Xml extends BaseReader (new Properties($spreadsheet))->readProperties($xml, $namespaces); $this->styles = (new Style())->parseStyles($xml, $namespaces); - if (isset($this->styles['Default'])) { + if (isset($this->styles['Default']) && is_array($this->styles['Default'])) { $spreadsheet->getCellXfCollection()[0]->applyFromArray($this->styles['Default']); } $worksheetID = 0; $xml_ss = $xml->children(self::NAMESPACES_SS); + $sheetCreated = false; /** @var null|SimpleXMLElement $worksheetx */ foreach ($xml_ss->Worksheet as $worksheetx) { $worksheet = $worksheetx ?? new SimpleXMLElement(''); @@ -315,6 +322,7 @@ class Xml extends BaseReader // Create new Worksheet $spreadsheet->createSheet(); + $sheetCreated = true; $spreadsheet->setActiveSheetIndex($worksheetID); $worksheetName = ''; if (isset($worksheet_ss['Name'])) { @@ -366,13 +374,14 @@ class Xml extends BaseReader $columnVisible = ((string) $columnData_ss['Hidden']) !== '1'; } while ($colspan >= 0) { + /** @var string $columnID */ if (isset($columnWidth)) { $spreadsheet->getActiveSheet()->getColumnDimension($columnID)->setWidth($columnWidth / 5.4); } if (isset($columnVisible)) { $spreadsheet->getActiveSheet()->getColumnDimension($columnID)->setVisible($columnVisible); } - ++$columnID; + StringHelper::stringIncrement($columnID); --$colspan; } } @@ -406,7 +415,7 @@ class Xml extends BaseReader } if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { - ++$columnID; + StringHelper::stringIncrement($columnID); continue; } @@ -514,14 +523,14 @@ class Xml extends BaseReader if (isset($cell_ss['StyleID'])) { $style = (string) $cell_ss['StyleID']; - if ((isset($this->styles[$style])) && (!empty($this->styles[$style]))) { + if ((isset($this->styles[$style])) && is_array($this->styles[$style]) && (!empty($this->styles[$style]))) { $spreadsheet->getActiveSheet()->getStyle($cellRange) ->applyFromArray($this->styles[$style]); } } - ++$columnID; + StringHelper::stringIncrement($columnID); while ($additionalMergedCells > 0) { - ++$columnID; + StringHelper::stringIncrement($columnID); --$additionalMergedCells; } } @@ -661,6 +670,9 @@ class Xml extends BaseReader } ++$worksheetID; } + if ($this->createBlankSheetIfNoneRead && !$sheetCreated) { + $spreadsheet->createSheet(); + } // Globally scoped defined names $activeSheetIndex = 0; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/DataValidations.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/DataValidations.php index faa2fb2..74d7ec4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/DataValidations.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/DataValidations.php @@ -30,6 +30,7 @@ class DataValidations private int $thisColumn = 0; + /** @param string[] $matches */ private function replaceR1C1(array $matches): string { return AddressHelper::convertToA1($matches[0], $this->thisRow, $this->thisColumn, false); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/PageSettings.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/PageSettings.php index 8f9d464..2434e86 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/PageSettings.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/PageSettings.php @@ -10,12 +10,16 @@ use stdClass; class PageSettings { + /** @var (object{orientation: string, scale: ?int, printOrder: ?string, + * paperSize: int, + * horizontalCentered: bool, verticalCentered: bool, leftMargin: float, rightMargin: float, topMargin: float, + * bottomMargin: float, headerMargin: float, footerMargin: float}&stdClass) */ private stdClass $printSettings; public function __construct(SimpleXMLElement $xmlX) { $printSettings = $this->pageSetup($xmlX, $this->getPrintDefaults()); - $this->printSettings = $this->printSetup($xmlX, $printSettings); + $this->printSettings = $this->printSetup($xmlX, $printSettings); //* @phpstan-ignore-line } public function loadPageSettings(Spreadsheet $spreadsheet): void diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Properties.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Properties.php index 17e1121..83116ba 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Properties.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Properties.php @@ -15,6 +15,7 @@ class Properties $this->spreadsheet = $spreadsheet; } + /** @param string[] $namespaces */ public function readProperties(SimpleXMLElement $xml, array $namespaces): void { $this->readStandardProperties($xml); @@ -34,6 +35,7 @@ class Properties } } + /** @param string[] $namespaces */ protected function readCustomProperties(SimpleXMLElement $xml, array $namespaces): void { if (isset($xml->CustomDocumentProperties) && is_iterable($xml->CustomDocumentProperties[0])) { @@ -143,6 +145,7 @@ class Properties $docProps->setCustomProperty($propertyName, $propertyValue, $propertyType); } + /** @param string[] $hex */ protected function hex2str(array $hex): string { return mb_chr((int) hexdec($hex[1]), 'UTF-8'); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style.php index c6b5149..699d718 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style.php @@ -9,14 +9,21 @@ class Style { /** * Formats. + * + * @var mixed[] */ protected array $styles = []; + /** + * @param string[] $namespaces + * + * @return mixed[] + */ public function parseStyles(SimpleXMLElement $xml, array $namespaces): array { $children = $xml->children('urn:schemas-microsoft-com:office:spreadsheet'); $stylesXml = $children->Styles[0]; - if (!isset($stylesXml) || !is_iterable($stylesXml)) { + if (!isset($stylesXml)) { return []; } @@ -27,6 +34,7 @@ class Style $numberFormatStyleParser = new Style\NumberFormat(); foreach ($stylesXml as $style) { + /** @var SimpleXMLElement $style */ $style_ss = self::getAttributes($style, $namespaces['ss']); $styleID = (string) $style_ss['ID']; $this->styles[$styleID] = $this->styles['Default'] ?? []; @@ -68,7 +76,7 @@ class Style break; case 'Protection': $locked = $hidden = null; - $styleAttributesP = $styleData->attributes($namespaces['x']); + $styleAttributesP = array_key_exists('x', $namespaces) ? $styleData->attributes($namespaces['x']) : []; if (isset($styleAttributes['Protected'])) { $locked = ((bool) (string) $styleAttributes['Protected']) ? Protection::PROTECTION_PROTECTED : Protection::PROTECTION_UNPROTECTED; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Alignment.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Alignment.php index d136354..b4afcde 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Alignment.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Alignment.php @@ -23,6 +23,7 @@ class Alignment extends StyleBase AlignmentStyles::HORIZONTAL_JUSTIFY, ]; + /** @return mixed[] */ public function parseStyle(SimpleXMLElement $styleAttributes): array { $style = []; @@ -49,6 +50,18 @@ class Alignment extends StyleBase case 'Rotate': $style['alignment']['textRotation'] = $styleAttributeValue; + break; + case 'Indent': + $style['alignment']['indent'] = $styleAttributeValue; + + break; + case 'ReadingOrder': + if ($styleAttributeValue === 'RightToLeft') { + $style['alignment']['readOrder'] = AlignmentStyles::READORDER_RTL; + } elseif ($styleAttributeValue === 'LeftToRight') { + $style['alignment']['readOrder'] = AlignmentStyles::READORDER_LTR; + } + break; } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Border.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Border.php index dfde17a..8a5407d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Border.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Border.php @@ -15,9 +15,6 @@ class Border extends StyleBase 'right', ]; - /** - * @var array - */ public const BORDER_MAPPINGS = [ 'borderStyle' => [ 'continuous' => BorderStyle::BORDER_HAIR, @@ -53,6 +50,11 @@ class Border extends StyleBase ], ]; + /** + * @param string[] $namespaces + * + * @return mixed[] + */ public function parseStyle(SimpleXMLElement $styleData, array $namespaces): array { $style = []; @@ -70,6 +72,7 @@ class Border extends StyleBase $borderStyleValue = (string) $borderStyleValuex; switch ($borderStyleKey) { case 'Position': + /** @var string $diagonalDirection */ [$borderPosition, $diagonalDirection] = $this->parsePosition($borderStyleValue, $diagonalDirection); @@ -82,6 +85,7 @@ class Border extends StyleBase } } + /** @var int|string $borderPosition */ if ($borderPosition) { $style['borders'][$borderPosition] = $thisBorder; } elseif ($diagonalDirection) { @@ -93,8 +97,10 @@ class Border extends StyleBase return $style; } + /** @return mixed[] */ protected function parsePosition(string $borderStyleValue, string $diagonalDirection): array { + // TODO diagonalDirection seems to return int not string $borderStyleValue = strtolower($borderStyleValue); if (in_array($borderStyleValue, self::BORDER_POSITIONS)) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Fill.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Fill.php index 9a61215..8dc7232 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Fill.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Fill.php @@ -7,9 +7,6 @@ use SimpleXMLElement; class Fill extends StyleBase { - /** - * @var array - */ public const FILL_MAPPINGS = [ 'fillType' => [ 'solid' => FillStyles::FILL_SOLID, @@ -33,6 +30,7 @@ class Fill extends StyleBase ], ]; + /** @return mixed[] */ public function parseStyle(SimpleXMLElement $styleAttributes): array { $style = []; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Font.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Font.php index 5f82488..4a5243a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Font.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/Font.php @@ -15,6 +15,11 @@ class Font extends StyleBase FontUnderline::UNDERLINE_SINGLEACCOUNTING, ]; + /** + * @param mixed[][] $style + * + * @return mixed[][] + */ protected function parseUnderline(array $style, string $styleAttributeValue): array { if (self::identifyFixedStyleValue(self::UNDERLINE_STYLES, $styleAttributeValue)) { @@ -24,6 +29,11 @@ class Font extends StyleBase return $style; } + /** + * @param mixed[][] $style + * + * @return mixed[][] + */ protected function parseVerticalAlign(array $style, string $styleAttributeValue): array { if ($styleAttributeValue == 'Superscript') { @@ -36,6 +46,7 @@ class Font extends StyleBase return $style; } + /** @return mixed[] */ public function parseStyle(SimpleXMLElement $styleAttributes): array { $style = []; @@ -52,6 +63,7 @@ class Font extends StyleBase break; case 'Color': + /** @var string[][][] $style */ $style['font']['color']['rgb'] = substr($styleAttributeValue, 1); break; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/NumberFormat.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/NumberFormat.php index a31aa9e..1ca825a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/NumberFormat.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/NumberFormat.php @@ -6,6 +6,7 @@ use SimpleXMLElement; class NumberFormat extends StyleBase { + /** @return mixed[] */ public function parseStyle(SimpleXMLElement $styleAttributes): array { $style = []; @@ -14,7 +15,7 @@ class NumberFormat extends StyleBase $toFormats = ['-', ' ']; foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { - $styleAttributeValue = str_replace($fromFormats, $toFormats, $styleAttributeValue); + $styleAttributeValue = str_replace($fromFormats, $toFormats, (string) $styleAttributeValue); switch ($styleAttributeValue) { case 'Short Date': diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/StyleBase.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/StyleBase.php index 8103a71..4217cae 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/StyleBase.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml/Style/StyleBase.php @@ -6,6 +6,7 @@ use SimpleXMLElement; abstract class StyleBase { + /** @param string[] $styleList */ protected static function identifyFixedStyleValue(array $styleList, string &$styleAttributeValue): bool { $returnValue = false; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/ReferenceHelper.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/ReferenceHelper.php index 24ae60e..be65398 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/ReferenceHelper.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/ReferenceHelper.php @@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Cell\AddressRange; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\DataType; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter; use PhpOffice\PhpSpreadsheet\Worksheet\Table; @@ -450,7 +451,7 @@ class ReferenceHelper } $highColumn = Coordinate::columnIndexFromString($highestDataColumn); for ($row = $startRow; $row <= $highestDataRow; ++$row) { - for ($col = $startCol, $colString = $startColString; $col <= $highColumn; ++$col, ++$colString) { + for ($col = $startCol, $colString = $startColString; $col <= $highColumn; ++$col, StringHelper::stringIncrement($colString)) { $worksheet->getCell("$colString$row"); // create cell if it doesn't exist } } @@ -505,7 +506,7 @@ class ReferenceHelper $highestColumn = $worksheet->getHighestColumn(); $highestRow = $worksheet->getHighestRow(); - if ($numberOfColumns > 0 && $beforeColumn - 2 > 0) { + if ($numberOfColumns > 0 && $beforeColumn > 1) { $this->duplicateStylesByColumn($worksheet, $beforeColumn, $beforeRow, $highestRow, $numberOfColumns); } @@ -557,12 +558,7 @@ class ReferenceHelper $worksheet->freezePane($splitCell, $topLeftCell); } - // Page setup - if ($worksheet->getPageSetup()->isPrintAreaSet()) { - $worksheet->getPageSetup()->setPrintArea( - $this->updateCellReference($worksheet->getPageSetup()->getPrintArea()) - ); - } + $this->updatePrintAreas($worksheet, $beforeCellAddress, $numberOfColumns, $numberOfRows); // Update worksheet: drawings $aDrawings = $worksheet->getDrawingCollection(); @@ -588,6 +584,93 @@ class ReferenceHelper $worksheet->garbageCollect(); } + private function updatePrintAreas(Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void + { + $pageSetup = $worksheet->getPageSetup(); + if (!$pageSetup->isPrintAreaSet()) { + return; + } + $printAreas = explode(',', $pageSetup->getPrintArea()); + $newPrintAreas = []; + foreach ($printAreas as $printArea) { + $result = $this->updatePrintArea($printArea, $beforeCellAddress, $numberOfColumns, $numberOfRows); + if ($result !== '') { + $newPrintAreas[] = $result; + } + } + $result = implode(',', $newPrintAreas); + if ($result === '') { + $pageSetup->clearPrintArea(); + } else { + $pageSetup->setPrintArea($result); + } + } + + private function updatePrintArea(string $printArea, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): string + { + $coordinates = Coordinate::indexesFromString($beforeCellAddress); + if (preg_match('/^([A-Z]{1,3})(\d{1,7}):([A-Z]{1,3})(\d{1,7})$/i', $printArea, $matches) === 1) { + $firstRow = (int) $matches[2]; + $lastRow = (int) $matches[4]; + $firstColumnString = $matches[1]; + $lastColumnString = $matches[3]; + if ($numberOfRows < 0) { + $affectedRow = $coordinates[1] + $numberOfRows - 1; + $lastAffectedRow = $coordinates[1] - 1; + if ($affectedRow >= $firstRow && $affectedRow <= $lastRow) { + $newLastRow = max($affectedRow, $lastRow + $numberOfRows); + if ($newLastRow >= $firstRow) { + return $matches[1] . $matches[2] . ':' . $matches[3] . $newLastRow; + } + + return ''; + } + if ($lastAffectedRow >= $firstRow && $affectedRow <= $lastRow) { + $newFirstRow = $affectedRow + 1; + $newLastRow = $lastRow + $numberOfRows; + if ($newFirstRow >= 1 && $newLastRow >= $newFirstRow) { + return $matches[1] . $newFirstRow . ':' . $matches[3] . $newLastRow; + } + + return ''; + } + } + if ($numberOfColumns < 0) { + $firstColumnInt = Coordinate::columnIndexFromString($firstColumnString); + $lastColumnInt = Coordinate::columnIndexFromString($lastColumnString); + $affectedColumn = $coordinates[0] + $numberOfColumns - 1; + $lastAffectedColumn = $coordinates[0] - 1; + if ($affectedColumn >= $firstColumnInt && $affectedColumn <= $lastColumnInt) { + $newLastColumnInt = max($affectedColumn, $lastColumnInt + $numberOfColumns); + if ($newLastColumnInt >= $firstColumnInt) { + $newLastColumnString = Coordinate::stringFromColumnIndex($newLastColumnInt); + + return $matches[1] . $matches[2] . ':' . $newLastColumnString . $matches[4]; + } + + return ''; + } + if ($affectedColumn < $firstColumnInt && $lastAffectedColumn > $lastColumnInt) { + return ''; + } + if ($lastAffectedColumn >= $firstColumnInt && $lastAffectedColumn <= $lastColumnInt) { + $newFirstColumn = $affectedColumn + 1; + $newLastColumn = $lastColumnInt + $numberOfColumns; + if ($newFirstColumn >= 1 && $newLastColumn >= $newFirstColumn) { + $firstString = Coordinate::stringFromColumnIndex($newFirstColumn); + $lastString = Coordinate::stringFromColumnIndex($newLastColumn); + + return $firstString . $matches[2] . ':' . $lastString . $matches[4]; + } + + return ''; + } + } + } + + return $this->updateCellReference($printArea); + } + private static function matchSheetName(?string $match, string $worksheetName): bool { return $match === null || $match === '' || $match === "'\u{fffc}'" || $match === "'\u{fffb}'" || strcasecmp(trim($match, "'"), $worksheetName) === 0; @@ -962,7 +1045,7 @@ class ReferenceHelper { $cellAddress = $definedName->getValue(); $asFormula = ($cellAddress[0] === '='); - if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashInt() === $worksheet->getHashInt()) { + if ($definedName->getWorksheet() === $worksheet) { /** * If we delete the entire range that is referenced by a Named Range, MS Excel sets the value to #REF! * PhpSpreadsheet still only does a basic adjustment, so the Named Range will still reference Cells. @@ -981,7 +1064,7 @@ class ReferenceHelper private function updateNamedFormula(DefinedName $definedName, Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void { - if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashInt() === $worksheet->getHashInt()) { + if ($definedName->getWorksheet() === $worksheet) { /** * If we delete the entire range that is referenced by a Named Formula, MS Excel sets the value to #REF! * PhpSpreadsheet still only does a basic adjustment, so the Named Formula will still reference Cells. @@ -1040,7 +1123,7 @@ class ReferenceHelper $endColumnId = Coordinate::stringFromColumnIndex($beforeColumn); for ($row = 1; $row <= $highestRow - 1; ++$row) { - for ($column = $startColumnId; $column !== $endColumnId; ++$column) { + for ($column = $startColumnId; $column !== $endColumnId; StringHelper::stringIncrement($column)) { $coordinate = $column . $row; $this->clearStripCell($worksheet, $coordinate); } @@ -1050,9 +1133,9 @@ class ReferenceHelper private function clearRowStrips(string $highestColumn, int $beforeColumn, int $beforeRow, int $numberOfRows, Worksheet $worksheet): void { $startColumnId = Coordinate::stringFromColumnIndex($beforeColumn); - ++$highestColumn; + StringHelper::stringIncrement($highestColumn); - for ($column = $startColumnId; $column !== $highestColumn; ++$column) { + for ($column = $startColumnId; $column !== $highestColumn; StringHelper::stringIncrement($column)) { for ($row = $beforeRow + $numberOfRows; $row <= $beforeRow - 1; ++$row) { $coordinate = $column . $row; $this->clearStripCell($worksheet, $coordinate); @@ -1108,6 +1191,7 @@ class ReferenceHelper } } + /** @param mixed[] $autoFilterColumns */ private function adjustAutoFilterDeleteRules(int $columnIndex, int $numberOfColumns, array $autoFilterColumns, AutoFilter $autoFilter): void { // If we're actually deleting any columns that fall within the autofilter range, @@ -1131,7 +1215,10 @@ class ReferenceHelper $toColRef = $rangeEnd + $numberOfColumns; do { - $autoFilter->shiftColumn(Coordinate::stringFromColumnIndex($endColRef), Coordinate::stringFromColumnIndex($toColRef)); + $autoFilter->shiftColumn( + Coordinate::stringFromColumnIndex($endColRef), + Coordinate::stringFromColumnIndex($toColRef) + ); --$endColRef; --$toColRef; } while ($startColRef <= $endColRef); @@ -1146,9 +1233,9 @@ class ReferenceHelper do { $autoFilter->shiftColumn($startColID, $toColID); - ++$toColID; - ++$startColID; // this confuses phpstan into thinking startColID is int/float - } while ($startColID !== $endColID); // @phpstan-ignore-line + StringHelper::stringIncrement($toColID); + StringHelper::stringIncrement($startColID); + } while ($startColID !== $endColID); } private function adjustTable(Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns): void @@ -1187,6 +1274,7 @@ class ReferenceHelper } } + /** @param mixed[] $tableColumns */ private function adjustTableDeleteRules(int $columnIndex, int $numberOfColumns, array $tableColumns, Table $table): void { // If we're actually deleting any columns that fall within the table range, @@ -1210,7 +1298,10 @@ class ReferenceHelper $toColRef = $rangeEnd + $numberOfColumns; do { - $table->shiftColumn(Coordinate::stringFromColumnIndex($endColRef), Coordinate::stringFromColumnIndex($toColRef)); + $table->shiftColumn( + Coordinate::stringFromColumnIndex($endColRef), + Coordinate::stringFromColumnIndex($toColRef) + ); --$endColRef; --$toColRef; } while ($startColRef <= $endColRef); @@ -1225,15 +1316,15 @@ class ReferenceHelper do { $table->shiftColumn($startColID, $toColID); - ++$toColID; - ++$startColID; // this confuses phpstan into thinking startColID is int/float - } while ($startColID !== $endColID); // @phpstan-ignore-line + StringHelper::stringIncrement($toColID); + StringHelper::stringIncrement($startColID); + } while ($startColID !== $endColID); } private function duplicateStylesByColumn(Worksheet $worksheet, int $beforeColumn, int $beforeRow, int $highestRow, int $numberOfColumns): void { $beforeColumnName = Coordinate::stringFromColumnIndex($beforeColumn - 1); - for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) { + for ($i = $beforeRow; $i <= $highestRow; ++$i) { // Style $coordinate = $beforeColumnName . $i; if ($worksheet->cellExists($coordinate)) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php index 5f2308f..b4c49d4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php @@ -57,7 +57,8 @@ class Settings */ public static function setChartRenderer(string $rendererClassName): void { - if (!is_a($rendererClassName, IRenderer::class, true)) { + // We want phpstan to validate caller, but still need this test + if (!is_a($rendererClassName, IRenderer::class, true)) { //* @phpstan-ignore-line throw new Exception('Chart renderer must implement ' . IRenderer::class); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/CodePage.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/CodePage.php index 307f8d9..de6529c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/CodePage.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/CodePage.php @@ -8,6 +8,7 @@ class CodePage { public const DEFAULT_CODE_PAGE = 'CP1252'; + /** @var array|string> */ private static array $pageArray = [ 0 => 'CP1252', // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program 367 => 'ASCII', // ASCII @@ -106,6 +107,7 @@ class CodePage throw new PhpSpreadsheetException('Unknown codepage: ' . $codePage); } + /** @return array|string> */ public static function getEncodings(): array { return self::$pageArray; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Date.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Date.php index 5e0235f..3dc1696 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Date.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Date.php @@ -172,10 +172,7 @@ class Date throw new Exception("Invalid string $value supplied for datatype Date"); } - $newValue = self::PHPToExcel($date); - if ($newValue === false) { - throw new Exception("Invalid string $value supplied for datatype Date"); - } + $newValue = self::dateTimeToExcel($date); if (preg_match('/^\s*\d?\d:\d\d(:\d\d([.]\d+)?)?\s*(am|pm)?\s*$/i', $value) == 1) { $newValue = fmod($newValue, 1.0); @@ -214,6 +211,13 @@ class Date $baseDate = new DateTime('1899-12-30', $timeZone); } + if (is_int($excelTimestamp)) { + if ($excelTimestamp >= 0) { + return $baseDate->modify("+ $excelTimestamp days"); + } + + return $baseDate->modify("$excelTimestamp days"); + } $days = floor($excelTimestamp); $partDay = $excelTimestamp - $days; $hms = 86400 * $partDay; @@ -367,7 +371,12 @@ class Date $selected = $worksheet->getSelectedCells(); try { - $result = is_numeric($value ?? $cell->getCalculatedValue()) + if ($value === null) { + $value = Functions::flattenSingleValue( + $cell->getCalculatedValue() + ); + } + $result = is_numeric($value) && self::isDateTimeFormat( $worksheet->getStyle( $cell->getCoordinate() @@ -464,7 +473,7 @@ class Date if (strlen($dateValue) < 2) { return false; } - if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) { + if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2}([.]\d+)?)?)?$/iu', $dateValue)) { return false; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher.php index 9eb9956..00180f6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheet\Shared; +use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; + class Escher { /** @@ -22,6 +24,14 @@ class Escher return $this->dggContainer; } + /** + * Get Drawing Group Container. + */ + public function getDggContainerOrThrow(): Escher\DggContainer + { + return $this->dggContainer ?? throw new SpreadsheetException('dggContainer is unexpectedly null'); + } + /** * Set Drawing Group Container. */ @@ -38,6 +48,14 @@ class Escher return $this->dgContainer; } + /** + * Get Drawing Container. + */ + public function getDgContainerOrThrow(): Escher\DgContainer + { + return $this->dgContainer ?? throw new SpreadsheetException('dgContainer is unexpectedly null'); + } + /** * Set Drawing Container. */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DgContainer/SpgrContainer.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DgContainer/SpgrContainer.php index 84363ab..0670a2c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DgContainer/SpgrContainer.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DgContainer/SpgrContainer.php @@ -11,6 +11,8 @@ class SpgrContainer /** * Shape Container collection. + * + * @var mixed[] */ private array $children = []; @@ -43,6 +45,8 @@ class SpgrContainer /** * Get collection of Shape Containers. + * + * @return mixed[] */ public function getChildren(): array { @@ -65,6 +69,7 @@ class SpgrContainer $allSpContainers[] = $child; } } + /** @var SpgrContainer\SpContainer[] $allSpContainers */ return $allSpContainers; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php index c462d45..45a2738 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php @@ -33,6 +33,8 @@ class SpContainer /** * Array of options. + * + * @var mixed[] */ private array $OPT = []; @@ -172,6 +174,8 @@ class SpContainer /** * Get the collection of options. + * + * @return mixed[] */ public function getOPTCollection(): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DggContainer.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DggContainer.php index d0bf1bb..e5d831f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DggContainer.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Escher/DggContainer.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheet\Shared\Escher; +use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; + class DggContainer { /** @@ -26,11 +28,15 @@ class DggContainer /** * Array of options for the drawing group. + * + * @var mixed[] */ private array $OPT = []; /** * Array of identifier clusters containg information about the maximum shape identifiers. + * + * @var mixed[] */ private array $IDCLs = []; @@ -90,6 +96,14 @@ class DggContainer return $this->bstoreContainer; } + /** + * Get BLIP Store Container. + */ + public function getBstoreContainerOrThrow(): DggContainer\BstoreContainer + { + return $this->bstoreContainer ?? throw new SpreadsheetException('bstoreContainer is unexpectedly null'); + } + /** * Set BLIP Store Container. */ @@ -124,6 +138,8 @@ class DggContainer /** * Get identifier clusters. + * + * @return mixed[] */ public function getIDCLs(): array { @@ -132,6 +148,8 @@ class DggContainer /** * Set identifier clusters. [ => , ...]. + * + * @param mixed[] $IDCLs */ public function setIDCLs(array $IDCLs): void { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Font.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Font.php index f9370b4..27490e3 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Font.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Font.php @@ -436,6 +436,7 @@ class Font } // Get corners positions + /** @var int[] $textBox */ $lowerLeftCornerX = $textBox[0]; $lowerRightCornerX = $textBox[2]; $upperRightCornerX = $textBox[4]; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE.php index dbf6df8..09a3ace 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE.php @@ -58,6 +58,8 @@ class OLE /** * Array of PPS's found on the OLE container. + * + * @var array */ public array $_list = []; @@ -69,21 +71,21 @@ class OLE /** * Big Block Allocation Table. * - * @var array (blockId => nextBlockId) + * @var mixed[] (blockId => nextBlockId) */ public array $bbat; /** * Short Block Allocation Table. * - * @var array (blockId => nextBlockId) + * @var mixed[] (blockId => nextBlockId) */ public array $sbat; /** * Size of big blocks. This is usually 512. * - * @var int number of octets per block + * @var int<1, max> number of octets per block */ public int $bigBlockSize; @@ -124,7 +126,9 @@ class OLE throw new ReaderException('Only Little-Endian encoding is supported.'); } // Size of blocks and short blocks in bytes - $this->bigBlockSize = 2 ** self::readInt2($fh); + /** @var int<1, max> */ + $temp = 2 ** self::readInt2($fh); + $this->bigBlockSize = $temp; $this->smallBlockSize = 2 ** self::readInt2($fh); // Skip UID, revision number and version number @@ -217,8 +221,8 @@ class OLE // Store current instance in global array, so that it can be accessed // in OLE_ChainedBlockStream::stream_open(). // Object is removed from self::$instances in OLE_Stream::close(). - $GLOBALS['_OLE_INSTANCES'][] = $this; - $keys = array_keys($GLOBALS['_OLE_INSTANCES']); + $GLOBALS['_OLE_INSTANCES'][] = $this; //* @phpstan-ignore-line + $keys = array_keys($GLOBALS['_OLE_INSTANCES']); //* @phpstan-ignore-line $instanceId = end($keys); $path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId; @@ -245,6 +249,7 @@ class OLE private static function readInt1($fileHandle): int { [, $tmp] = unpack('c', fread($fileHandle, 1) ?: '') ?: [0, 0]; + /** @var int $tmp */ return $tmp; } @@ -257,6 +262,7 @@ class OLE private static function readInt2($fileHandle): int { [, $tmp] = unpack('v', fread($fileHandle, 2) ?: '') ?: [0, 0]; + /** @var int $tmp */ return $tmp; } @@ -273,6 +279,7 @@ class OLE private static function readInt4($fileHandle): int { [, $tmp] = unpack('V', fread($fileHandle, 4) ?: '') ?: [0, 0]; + /** @var int $tmp */ if ($tmp >= self::SIGNED_4OCTET_LIMIT) { $tmp -= self::SIGNED_4OCTET_SUBTRACT; } @@ -367,9 +374,13 @@ class OLE */ private function ppsTreeComplete(int $index): bool { - return isset($this->_list[$index]) - && ($pps = $this->_list[$index]) - && ($pps->PrevPps == -1 + if (!isset($this->_list[$index])) { + return false; + } + $pps = $this->_list[$index]; + + return + ($pps->PrevPps == -1 || $this->ppsTreeComplete($pps->PrevPps)) && ($pps->NextPps == -1 || $this->ppsTreeComplete($pps->NextPps)) @@ -533,6 +544,7 @@ class OLE } // convert to units of 100 ns since 1601: + /** @var int[] */ $unpackedTimestamp = unpack('v4', $oleTimestamp) ?: []; $timestampHigh = (float) $unpackedTimestamp[4] * 65536 + (float) $unpackedTimestamp[3]; $timestampLow = (float) $unpackedTimestamp[2] * 65536 + (float) $unpackedTimestamp[1]; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php index 5210216..76f1be7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Shared\OLE; +use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Shared\OLE; class ChainedBlockStream @@ -16,6 +17,8 @@ class ChainedBlockStream /** * Parameters specified by fopen(). + * + * @var mixed[] */ public array $params = []; @@ -55,21 +58,25 @@ class ChainedBlockStream // 25 is length of "ole-chainedblockstream://" parse_str(substr($path, 25), $this->params); - if (!isset($this->params['oleInstanceId'], $this->params['blockId'], $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { + if (!isset($this->params['oleInstanceId'], $this->params['blockId'], $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { //* @phpstan-ignore-line if ($options & STREAM_REPORT_ERRORS) { trigger_error('OLE stream not found', E_USER_WARNING); } return false; } - $this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']]; + $this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']]; //* @phpstan-ignore-line + if (!($this->ole instanceof OLE)) { //* @phpstan-ignore-line + throw new Exception('class is not OLE'); + } $blockId = $this->params['blockId']; $this->data = ''; if (isset($this->params['size']) && $this->params['size'] < $this->ole->bigBlockThreshold && $blockId != $this->ole->root->startBlock) { // Block id refers to small blocks - $rootPos = $this->ole->getBlockOffset($this->ole->root->startBlock); + $rootPos = $this->ole->getBlockOffset((int) $this->ole->root->startBlock); while ($blockId != -2) { + /** @var int $blockId */ $pos = $rootPos + $blockId * $this->ole->bigBlockSize; $blockId = $this->ole->sbat[$blockId]; fseek($this->ole->_file_handle, $pos); @@ -78,6 +85,7 @@ class ChainedBlockStream } else { // Block id refers to big blocks while ($blockId != -2) { + /** @var int $blockId */ $pos = $this->ole->getBlockOffset($blockId); fseek($this->ole->_file_handle, $pos); $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize); @@ -165,6 +173,8 @@ class ChainedBlockStream /** * Implements support for fstat(). Currently the only supported field is * "size". + * + * @return array{size: int} */ public function stream_stat(): array // @codingStandardsIgnoreLine { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/PPS.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/PPS.php index 3a77c78..dae381b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/PPS.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/PPS.php @@ -88,6 +88,8 @@ class PPS /** * Array of child PPS's (only used by Root and Dir PPS's). + * + * @var mixed[] */ public array $children = []; @@ -108,7 +110,7 @@ class PPS * @param null|float|int $time_1st A timestamp * @param null|float|int $time_2nd A timestamp * @param ?string $data The (usually binary) source data of the PPS - * @param array $children Array containing children PPS for this PPS + * @param mixed[] $children Array containing children PPS for this PPS */ public function __construct(?int $No, ?string $name, ?int $type, ?int $prev, ?int $next, ?int $dir, $time_1st, $time_2nd, ?string $data, array $children) { @@ -172,7 +174,7 @@ class PPS * Updates index and pointers to previous, next and children PPS's for this * PPS. I don't think it'll work with Dir PPS's. * - * @param array $raList Reference to the array of PPS's for the whole OLE + * @param self[] $raList Reference to the array of PPS's for the whole OLE * container * * @return int The index for this PPS @@ -181,7 +183,9 @@ class PPS { if (!is_array($to_save) || (empty($to_save))) { return self::ALL_ONE_BITS; - } elseif (count($to_save) == 1) { + } + /** @var self[] $to_save */ + if (count($to_save) == 1) { $cnt = count($raList); // If the first entry, it's the root... Don't clone it! $raList[$cnt] = ($depth == 0) ? $to_save[0] : clone $to_save[0]; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/PPS/Root.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/PPS/Root.php index 64de77f..eb03f8c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/PPS/Root.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLE/PPS/Root.php @@ -96,7 +96,7 @@ class Root extends PPS /** * Calculate some numbers. * - * @param array $raList Reference to an array of PPS's + * @param PPS[] $raList Reference to an array of PPS's * * @return float[] The array of numbers */ @@ -223,7 +223,7 @@ class Root extends PPS /** * Saving big data (PPS's with data bigger than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL). * - * @param array $raList Reference to array of PPS's + * @param PPS[] $raList Reference to array of PPS's */ private function saveBigData(int $iStBlk, array &$raList): void { @@ -243,7 +243,7 @@ class Root extends PPS // Set For PPS $raList[$i]->startBlock = $iStBlk; $iStBlk - += (floor($raList[$i]->Size / $this->bigBlockSize) + += ((int) floor($raList[$i]->Size / $this->bigBlockSize) + (($raList[$i]->Size % $this->bigBlockSize) ? 1 : 0)); } } @@ -253,7 +253,7 @@ class Root extends PPS /** * get small data (PPS's with data smaller than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL). * - * @param array $raList Reference to array of PPS's + * @param PPS[] $raList Reference to array of PPS's */ private function makeSmallData(array &$raList): string { @@ -269,7 +269,7 @@ class Root extends PPS continue; } if ($raList[$i]->Size < OLE::OLE_DATA_SIZE_SMALL) { - $iSmbCnt = floor($raList[$i]->Size / $this->smallBlockSize) + $iSmbCnt = (int) floor($raList[$i]->Size / $this->smallBlockSize) + (($raList[$i]->Size % $this->smallBlockSize) ? 1 : 0); // Add to SBD $jB = $iSmbCnt - 1; @@ -303,7 +303,7 @@ class Root extends PPS /** * Saves all the PPS's WKs. * - * @param array $raList Reference to an array with all PPS's + * @param PPS[] $raList Reference to an array with all PPS's */ private function savePps(array &$raList): void { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLERead.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLERead.php index 645dbf7..aa4224b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLERead.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/OLERead.php @@ -58,6 +58,7 @@ class OLERead private int $rootentry; + /** @var mixed[][] */ private array $props = []; /** @@ -164,8 +165,11 @@ class OLERead $streamData = ''; if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) { - $rootdata = $this->readData($this->props[$this->rootentry]['startBlock']); + /** @var int */ + $temp = $this->props[$this->rootentry]['startBlock']; + $rootdata = $this->readData($temp); + /** @var int */ $block = $this->props[$stream]['startBlock']; while ($block != -2) { @@ -177,8 +181,10 @@ class OLERead return $streamData; } - $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE; - if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) { + /** @var int */ + $temp = $this->props[$stream]['size']; + $numBlocks = $temp / self::BIG_BLOCK_SIZE; + if ($temp % self::BIG_BLOCK_SIZE != 0) { ++$numBlocks; } @@ -186,6 +192,7 @@ class OLERead return ''; } + /** @var int */ $block = $this->props[$stream]['startBlock']; while ($block != -2) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/PasswordHasher.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/PasswordHasher.php index fcdbc98..4d1103a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/PasswordHasher.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/PasswordHasher.php @@ -78,7 +78,7 @@ class PasswordHasher * * @param string $password Password to hash * @param string $algorithm Hash algorithm used to compute the password hash value - * @param string $salt Pseudorandom string + * @param string $salt Pseudorandom base64-encoded string * @param int $spinCount Number of times to iterate on a hash of a password * * @return string Hashed password diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/StringHelper.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/StringHelper.php index d84e9fe..6398b61 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/StringHelper.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/StringHelper.php @@ -2,19 +2,237 @@ namespace PhpOffice\PhpSpreadsheet\Shared; +use Composer\Pcre\Preg; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; +use Stringable; + class StringHelper { - /** - * Control characters array. - * - * @var string[] - */ - private static array $controlCharacters = []; + private const CONTROL_CHARACTERS_KEYS = [ + "\x00", + "\x01", + "\x02", + "\x03", + "\x04", + "\x05", + "\x06", + "\x07", + "\x08", + "\x0b", + "\x0c", + "\x0e", + "\x0f", + "\x10", + "\x11", + "\x12", + "\x13", + "\x14", + "\x15", + "\x16", + "\x17", + "\x18", + "\x19", + "\x1a", + "\x1b", + "\x1c", + "\x1d", + "\x1e", + "\x1f", + ]; + private const CONTROL_CHARACTERS_VALUES = [ + '_x0000_', + '_x0001_', + '_x0002_', + '_x0003_', + '_x0004_', + '_x0005_', + '_x0006_', + '_x0007_', + '_x0008_', + '_x000B_', + '_x000C_', + '_x000E_', + '_x000F_', + '_x0010_', + '_x0011_', + '_x0012_', + '_x0013_', + '_x0014_', + '_x0015_', + '_x0016_', + '_x0017_', + '_x0018_', + '_x0019_', + '_x001A_', + '_x001B_', + '_x001C_', + '_x001D_', + '_x001E_', + '_x001F_', + ]; /** * SYLK Characters array. */ - private static array $SYLKCharacters = []; + private const SYLK_CHARACTERS = [ + "\x1B 0" => "\x00", + "\x1B 1" => "\x01", + "\x1B 2" => "\x02", + "\x1B 3" => "\x03", + "\x1B 4" => "\x04", + "\x1B 5" => "\x05", + "\x1B 6" => "\x06", + "\x1B 7" => "\x07", + "\x1B 8" => "\x08", + "\x1B 9" => "\x09", + "\x1B :" => "\x0a", + "\x1B ;" => "\x0b", + "\x1B <" => "\x0c", + "\x1B =" => "\x0d", + "\x1B >" => "\x0e", + "\x1B ?" => "\x0f", + "\x1B!0" => "\x10", + "\x1B!1" => "\x11", + "\x1B!2" => "\x12", + "\x1B!3" => "\x13", + "\x1B!4" => "\x14", + "\x1B!5" => "\x15", + "\x1B!6" => "\x16", + "\x1B!7" => "\x17", + "\x1B!8" => "\x18", + "\x1B!9" => "\x19", + "\x1B!:" => "\x1a", + "\x1B!;" => "\x1b", + "\x1B!<" => "\x1c", + "\x1B!=" => "\x1d", + "\x1B!>" => "\x1e", + "\x1B!?" => "\x1f", + "\x1B'?" => "\x7f", + "\x1B(0" => '€', // 128 in CP1252 + "\x1B(2" => '‚', // 130 in CP1252 + "\x1B(3" => 'ƒ', // 131 in CP1252 + "\x1B(4" => '„', // 132 in CP1252 + "\x1B(5" => '…', // 133 in CP1252 + "\x1B(6" => '†', // 134 in CP1252 + "\x1B(7" => '‡', // 135 in CP1252 + "\x1B(8" => 'ˆ', // 136 in CP1252 + "\x1B(9" => '‰', // 137 in CP1252 + "\x1B(:" => 'Š', // 138 in CP1252 + "\x1B(;" => '‹', // 139 in CP1252 + "\x1BNj" => 'Œ', // 140 in CP1252 + "\x1B(>" => 'Ž', // 142 in CP1252 + "\x1B)1" => '‘', // 145 in CP1252 + "\x1B)2" => '’', // 146 in CP1252 + "\x1B)3" => '“', // 147 in CP1252 + "\x1B)4" => '”', // 148 in CP1252 + "\x1B)5" => '•', // 149 in CP1252 + "\x1B)6" => '–', // 150 in CP1252 + "\x1B)7" => '—', // 151 in CP1252 + "\x1B)8" => '˜', // 152 in CP1252 + "\x1B)9" => '™', // 153 in CP1252 + "\x1B):" => 'š', // 154 in CP1252 + "\x1B);" => '›', // 155 in CP1252 + "\x1BNz" => 'œ', // 156 in CP1252 + "\x1B)>" => 'ž', // 158 in CP1252 + "\x1B)?" => 'Ÿ', // 159 in CP1252 + "\x1B*0" => ' ', // 160 in CP1252 + "\x1BN!" => '¡', // 161 in CP1252 + "\x1BN\"" => '¢', // 162 in CP1252 + "\x1BN#" => '£', // 163 in CP1252 + "\x1BN(" => '¤', // 164 in CP1252 + "\x1BN%" => '¥', // 165 in CP1252 + "\x1B*6" => '¦', // 166 in CP1252 + "\x1BN'" => '§', // 167 in CP1252 + "\x1BNH " => '¨', // 168 in CP1252 + "\x1BNS" => '©', // 169 in CP1252 + "\x1BNc" => 'ª', // 170 in CP1252 + "\x1BN+" => '«', // 171 in CP1252 + "\x1B*<" => '¬', // 172 in CP1252 + "\x1B*=" => '­', // 173 in CP1252 + "\x1BNR" => '®', // 174 in CP1252 + "\x1B*?" => '¯', // 175 in CP1252 + "\x1BN0" => '°', // 176 in CP1252 + "\x1BN1" => '±', // 177 in CP1252 + "\x1BN2" => '²', // 178 in CP1252 + "\x1BN3" => '³', // 179 in CP1252 + "\x1BNB " => '´', // 180 in CP1252 + "\x1BN5" => 'µ', // 181 in CP1252 + "\x1BN6" => '¶', // 182 in CP1252 + "\x1BN7" => '·', // 183 in CP1252 + "\x1B+8" => '¸', // 184 in CP1252 + "\x1BNQ" => '¹', // 185 in CP1252 + "\x1BNk" => 'º', // 186 in CP1252 + "\x1BN;" => '»', // 187 in CP1252 + "\x1BN<" => '¼', // 188 in CP1252 + "\x1BN=" => '½', // 189 in CP1252 + "\x1BN>" => '¾', // 190 in CP1252 + "\x1BN?" => '¿', // 191 in CP1252 + "\x1BNAA" => 'À', // 192 in CP1252 + "\x1BNBA" => 'Á', // 193 in CP1252 + "\x1BNCA" => 'Â', // 194 in CP1252 + "\x1BNDA" => 'Ã', // 195 in CP1252 + "\x1BNHA" => 'Ä', // 196 in CP1252 + "\x1BNJA" => 'Å', // 197 in CP1252 + "\x1BNa" => 'Æ', // 198 in CP1252 + "\x1BNKC" => 'Ç', // 199 in CP1252 + "\x1BNAE" => 'È', // 200 in CP1252 + "\x1BNBE" => 'É', // 201 in CP1252 + "\x1BNCE" => 'Ê', // 202 in CP1252 + "\x1BNHE" => 'Ë', // 203 in CP1252 + "\x1BNAI" => 'Ì', // 204 in CP1252 + "\x1BNBI" => 'Í', // 205 in CP1252 + "\x1BNCI" => 'Î', // 206 in CP1252 + "\x1BNHI" => 'Ï', // 207 in CP1252 + "\x1BNb" => 'Ð', // 208 in CP1252 + "\x1BNDN" => 'Ñ', // 209 in CP1252 + "\x1BNAO" => 'Ò', // 210 in CP1252 + "\x1BNBO" => 'Ó', // 211 in CP1252 + "\x1BNCO" => 'Ô', // 212 in CP1252 + "\x1BNDO" => 'Õ', // 213 in CP1252 + "\x1BNHO" => 'Ö', // 214 in CP1252 + "\x1B-7" => '×', // 215 in CP1252 + "\x1BNi" => 'Ø', // 216 in CP1252 + "\x1BNAU" => 'Ù', // 217 in CP1252 + "\x1BNBU" => 'Ú', // 218 in CP1252 + "\x1BNCU" => 'Û', // 219 in CP1252 + "\x1BNHU" => 'Ü', // 220 in CP1252 + "\x1B-=" => 'Ý', // 221 in CP1252 + "\x1BNl" => 'Þ', // 222 in CP1252 + "\x1BN{" => 'ß', // 223 in CP1252 + "\x1BNAa" => 'à', // 224 in CP1252 + "\x1BNBa" => 'á', // 225 in CP1252 + "\x1BNCa" => 'â', // 226 in CP1252 + "\x1BNDa" => 'ã', // 227 in CP1252 + "\x1BNHa" => 'ä', // 228 in CP1252 + "\x1BNJa" => 'å', // 229 in CP1252 + "\x1BNq" => 'æ', // 230 in CP1252 + "\x1BNKc" => 'ç', // 231 in CP1252 + "\x1BNAe" => 'è', // 232 in CP1252 + "\x1BNBe" => 'é', // 233 in CP1252 + "\x1BNCe" => 'ê', // 234 in CP1252 + "\x1BNHe" => 'ë', // 235 in CP1252 + "\x1BNAi" => 'ì', // 236 in CP1252 + "\x1BNBi" => 'í', // 237 in CP1252 + "\x1BNCi" => 'î', // 238 in CP1252 + "\x1BNHi" => 'ï', // 239 in CP1252 + "\x1BNs" => 'ð', // 240 in CP1252 + "\x1BNDn" => 'ñ', // 241 in CP1252 + "\x1BNAo" => 'ò', // 242 in CP1252 + "\x1BNBo" => 'ó', // 243 in CP1252 + "\x1BNCo" => 'ô', // 244 in CP1252 + "\x1BNDo" => 'õ', // 245 in CP1252 + "\x1BNHo" => 'ö', // 246 in CP1252 + "\x1B/7" => '÷', // 247 in CP1252 + "\x1BNy" => 'ø', // 248 in CP1252 + "\x1BNAu" => 'ù', // 249 in CP1252 + "\x1BNBu" => 'ú', // 250 in CP1252 + "\x1BNCu" => 'û', // 251 in CP1252 + "\x1BNHu" => 'ü', // 252 in CP1252 + "\x1B/=" => 'ý', // 253 in CP1252 + "\x1BN|" => 'þ', // 254 in CP1252 + "\x1BNHy" => 'ÿ', // 255 in CP1252 + ]; /** * Decimal separator. @@ -41,185 +259,6 @@ class StringHelper */ private static string $iconvOptions = '//IGNORE//TRANSLIT'; - /** - * Build control characters array. - */ - private static function buildControlCharacters(): void - { - for ($i = 0; $i <= 31; ++$i) { - if ($i != 9 && $i != 10 && $i != 13) { - $find = '_x' . sprintf('%04s', strtoupper(dechex($i))) . '_'; - $replace = chr($i); - self::$controlCharacters[$find] = $replace; - } - } - } - - /** - * Build SYLK characters array. - */ - private static function buildSYLKCharacters(): void - { - self::$SYLKCharacters = [ - "\x1B 0" => chr(0), - "\x1B 1" => chr(1), - "\x1B 2" => chr(2), - "\x1B 3" => chr(3), - "\x1B 4" => chr(4), - "\x1B 5" => chr(5), - "\x1B 6" => chr(6), - "\x1B 7" => chr(7), - "\x1B 8" => chr(8), - "\x1B 9" => chr(9), - "\x1B :" => chr(10), - "\x1B ;" => chr(11), - "\x1B <" => chr(12), - "\x1B =" => chr(13), - "\x1B >" => chr(14), - "\x1B ?" => chr(15), - "\x1B!0" => chr(16), - "\x1B!1" => chr(17), - "\x1B!2" => chr(18), - "\x1B!3" => chr(19), - "\x1B!4" => chr(20), - "\x1B!5" => chr(21), - "\x1B!6" => chr(22), - "\x1B!7" => chr(23), - "\x1B!8" => chr(24), - "\x1B!9" => chr(25), - "\x1B!:" => chr(26), - "\x1B!;" => chr(27), - "\x1B!<" => chr(28), - "\x1B!=" => chr(29), - "\x1B!>" => chr(30), - "\x1B!?" => chr(31), - "\x1B'?" => chr(127), - "\x1B(0" => '€', // 128 in CP1252 - "\x1B(2" => '‚', // 130 in CP1252 - "\x1B(3" => 'ƒ', // 131 in CP1252 - "\x1B(4" => '„', // 132 in CP1252 - "\x1B(5" => '…', // 133 in CP1252 - "\x1B(6" => '†', // 134 in CP1252 - "\x1B(7" => '‡', // 135 in CP1252 - "\x1B(8" => 'ˆ', // 136 in CP1252 - "\x1B(9" => '‰', // 137 in CP1252 - "\x1B(:" => 'Š', // 138 in CP1252 - "\x1B(;" => '‹', // 139 in CP1252 - "\x1BNj" => 'Œ', // 140 in CP1252 - "\x1B(>" => 'Ž', // 142 in CP1252 - "\x1B)1" => '‘', // 145 in CP1252 - "\x1B)2" => '’', // 146 in CP1252 - "\x1B)3" => '“', // 147 in CP1252 - "\x1B)4" => '”', // 148 in CP1252 - "\x1B)5" => '•', // 149 in CP1252 - "\x1B)6" => '–', // 150 in CP1252 - "\x1B)7" => '—', // 151 in CP1252 - "\x1B)8" => '˜', // 152 in CP1252 - "\x1B)9" => '™', // 153 in CP1252 - "\x1B):" => 'š', // 154 in CP1252 - "\x1B);" => '›', // 155 in CP1252 - "\x1BNz" => 'œ', // 156 in CP1252 - "\x1B)>" => 'ž', // 158 in CP1252 - "\x1B)?" => 'Ÿ', // 159 in CP1252 - "\x1B*0" => ' ', // 160 in CP1252 - "\x1BN!" => '¡', // 161 in CP1252 - "\x1BN\"" => '¢', // 162 in CP1252 - "\x1BN#" => '£', // 163 in CP1252 - "\x1BN(" => '¤', // 164 in CP1252 - "\x1BN%" => '¥', // 165 in CP1252 - "\x1B*6" => '¦', // 166 in CP1252 - "\x1BN'" => '§', // 167 in CP1252 - "\x1BNH " => '¨', // 168 in CP1252 - "\x1BNS" => '©', // 169 in CP1252 - "\x1BNc" => 'ª', // 170 in CP1252 - "\x1BN+" => '«', // 171 in CP1252 - "\x1B*<" => '¬', // 172 in CP1252 - "\x1B*=" => '­', // 173 in CP1252 - "\x1BNR" => '®', // 174 in CP1252 - "\x1B*?" => '¯', // 175 in CP1252 - "\x1BN0" => '°', // 176 in CP1252 - "\x1BN1" => '±', // 177 in CP1252 - "\x1BN2" => '²', // 178 in CP1252 - "\x1BN3" => '³', // 179 in CP1252 - "\x1BNB " => '´', // 180 in CP1252 - "\x1BN5" => 'µ', // 181 in CP1252 - "\x1BN6" => '¶', // 182 in CP1252 - "\x1BN7" => '·', // 183 in CP1252 - "\x1B+8" => '¸', // 184 in CP1252 - "\x1BNQ" => '¹', // 185 in CP1252 - "\x1BNk" => 'º', // 186 in CP1252 - "\x1BN;" => '»', // 187 in CP1252 - "\x1BN<" => '¼', // 188 in CP1252 - "\x1BN=" => '½', // 189 in CP1252 - "\x1BN>" => '¾', // 190 in CP1252 - "\x1BN?" => '¿', // 191 in CP1252 - "\x1BNAA" => 'À', // 192 in CP1252 - "\x1BNBA" => 'Á', // 193 in CP1252 - "\x1BNCA" => 'Â', // 194 in CP1252 - "\x1BNDA" => 'Ã', // 195 in CP1252 - "\x1BNHA" => 'Ä', // 196 in CP1252 - "\x1BNJA" => 'Å', // 197 in CP1252 - "\x1BNa" => 'Æ', // 198 in CP1252 - "\x1BNKC" => 'Ç', // 199 in CP1252 - "\x1BNAE" => 'È', // 200 in CP1252 - "\x1BNBE" => 'É', // 201 in CP1252 - "\x1BNCE" => 'Ê', // 202 in CP1252 - "\x1BNHE" => 'Ë', // 203 in CP1252 - "\x1BNAI" => 'Ì', // 204 in CP1252 - "\x1BNBI" => 'Í', // 205 in CP1252 - "\x1BNCI" => 'Î', // 206 in CP1252 - "\x1BNHI" => 'Ï', // 207 in CP1252 - "\x1BNb" => 'Ð', // 208 in CP1252 - "\x1BNDN" => 'Ñ', // 209 in CP1252 - "\x1BNAO" => 'Ò', // 210 in CP1252 - "\x1BNBO" => 'Ó', // 211 in CP1252 - "\x1BNCO" => 'Ô', // 212 in CP1252 - "\x1BNDO" => 'Õ', // 213 in CP1252 - "\x1BNHO" => 'Ö', // 214 in CP1252 - "\x1B-7" => '×', // 215 in CP1252 - "\x1BNi" => 'Ø', // 216 in CP1252 - "\x1BNAU" => 'Ù', // 217 in CP1252 - "\x1BNBU" => 'Ú', // 218 in CP1252 - "\x1BNCU" => 'Û', // 219 in CP1252 - "\x1BNHU" => 'Ü', // 220 in CP1252 - "\x1B-=" => 'Ý', // 221 in CP1252 - "\x1BNl" => 'Þ', // 222 in CP1252 - "\x1BN{" => 'ß', // 223 in CP1252 - "\x1BNAa" => 'à', // 224 in CP1252 - "\x1BNBa" => 'á', // 225 in CP1252 - "\x1BNCa" => 'â', // 226 in CP1252 - "\x1BNDa" => 'ã', // 227 in CP1252 - "\x1BNHa" => 'ä', // 228 in CP1252 - "\x1BNJa" => 'å', // 229 in CP1252 - "\x1BNq" => 'æ', // 230 in CP1252 - "\x1BNKc" => 'ç', // 231 in CP1252 - "\x1BNAe" => 'è', // 232 in CP1252 - "\x1BNBe" => 'é', // 233 in CP1252 - "\x1BNCe" => 'ê', // 234 in CP1252 - "\x1BNHe" => 'ë', // 235 in CP1252 - "\x1BNAi" => 'ì', // 236 in CP1252 - "\x1BNBi" => 'í', // 237 in CP1252 - "\x1BNCi" => 'î', // 238 in CP1252 - "\x1BNHi" => 'ï', // 239 in CP1252 - "\x1BNs" => 'ð', // 240 in CP1252 - "\x1BNDn" => 'ñ', // 241 in CP1252 - "\x1BNAo" => 'ò', // 242 in CP1252 - "\x1BNBo" => 'ó', // 243 in CP1252 - "\x1BNCo" => 'ô', // 244 in CP1252 - "\x1BNDo" => 'õ', // 245 in CP1252 - "\x1BNHo" => 'ö', // 246 in CP1252 - "\x1B/7" => '÷', // 247 in CP1252 - "\x1BNy" => 'ø', // 248 in CP1252 - "\x1BNAu" => 'ù', // 249 in CP1252 - "\x1BNBu" => 'ú', // 250 in CP1252 - "\x1BNCu" => 'û', // 251 in CP1252 - "\x1BNHu" => 'ü', // 252 in CP1252 - "\x1B/=" => 'ý', // 253 in CP1252 - "\x1BN|" => 'þ', // 254 in CP1252 - "\x1BNHy" => 'ÿ', // 255 in CP1252 - ]; - } - /** * Get whether iconv extension is available. */ @@ -251,17 +290,6 @@ class StringHelper return self::$isIconvEnabled; } - private static function buildCharacterSets(): void - { - if (empty(self::$controlCharacters)) { - self::buildControlCharacters(); - } - - if (empty(self::$SYLKCharacters)) { - self::buildSYLKCharacters(); - } - } - /** * Convert from OpenXML escaped control character to PHP control character. * @@ -277,9 +305,7 @@ class StringHelper */ public static function controlCharacterOOXML2PHP(string $textValue): string { - self::buildCharacterSets(); - - return str_replace(array_keys(self::$controlCharacters), array_values(self::$controlCharacters), $textValue); + return str_replace(self::CONTROL_CHARACTERS_VALUES, self::CONTROL_CHARACTERS_KEYS, $textValue); } /** @@ -297,9 +323,7 @@ class StringHelper */ public static function controlCharacterPHP2OOXML(string $textValue): string { - self::buildCharacterSets(); - - return str_replace(array_values(self::$controlCharacters), array_keys(self::$controlCharacters), $textValue); + return str_replace(self::CONTROL_CHARACTERS_KEYS, self::CONTROL_CHARACTERS_VALUES, $textValue); } /** @@ -310,8 +334,7 @@ class StringHelper $textValue = str_replace(["\xef\xbf\xbe", "\xef\xbf\xbf"], "\xef\xbf\xbd", $textValue); $subst = mb_substitute_character(); // default is question mark mb_substitute_character(65533); // Unicode substitution character - // Phpstan does not think this can return false. - $returnValue = mb_convert_encoding($textValue, 'UTF-8', 'UTF-8'); + $returnValue = (string) mb_convert_encoding($textValue, 'UTF-8', 'UTF-8'); mb_substitute_character($subst); return $returnValue; @@ -397,14 +420,14 @@ class StringHelper */ public static function convertEncoding(string $textValue, string $to, string $from): string { - if (self::getIsIconvEnabled()) { + if (static::getIsIconvEnabled()) { $result = iconv($from, $to . self::$iconvOptions, $textValue); if (false !== $result) { return $result; } } - return mb_convert_encoding($textValue, $to, $from); + return (string) mb_convert_encoding($textValue, $to, $from); } /** @@ -481,14 +504,16 @@ class StringHelper /** * Splits a UTF-8 string into an array of individual characters. + * + * @return string[] */ public static function mbStrSplit(string $string): array { // Split at all position not after the start: ^ // and not before the end: $ - $split = preg_split('/(? $v) { + foreach (self::SYLK_CHARACTERS as $k => $v) { $textValue = str_replace($k, $v, $textValue); } @@ -643,4 +668,72 @@ class StringHelper { return strlen("$string"); } + + /** + * @param bool $convertBool If true, convert bool to locale-aware TRUE/FALSE rather than 1/null-string + * @param bool $lessFloatPrecision If true, floats will be converted to a more human-friendly but less computationally accurate value + */ + public static function convertToString(mixed $value, bool $throw = true, string $default = '', bool $convertBool = false, bool $lessFloatPrecision = false): string + { + if ($convertBool && is_bool($value)) { + return $value ? Calculation::getTRUE() : Calculation::getFALSE(); + } + if (is_float($value) && !$lessFloatPrecision) { + $string = (string) $value; + // look out for scientific notation + if (!Preg::isMatch('/[^-+0-9.]/', $string)) { + $minus = $value < 0 ? '-' : ''; + $positive = abs($value); + $floor = floor($positive); + $oldFrac = (string) ($positive - $floor); + $frac = Preg::replace('/^0[.](\d+)$/', '$1', $oldFrac); + if ($frac !== $oldFrac) { + return "$minus$floor.$frac"; + } + } + + return $string; + } + if ($value === null || is_scalar($value) || $value instanceof Stringable) { + return (string) $value; + } + + if ($throw) { + throw new SpreadsheetException('Unable to convert to string'); + } + + return $default; + } + + /** + * Assist with POST items when samples are run in browser. + * Never run as part of unit tests, which are command line. + * + * @codeCoverageIgnore + */ + public static function convertPostToString(string $index, string $default = ''): string + { + if (isset($_POST[$index])) { + return htmlentities(self::convertToString($_POST[$index], false, $default)); + } + + return $default; + } + + /** + * Php introduced str_increment with Php8.3, + * but didn't issue deprecation notices till 8.5. + * + * @codeCoverageIgnore + */ + public static function stringIncrement(string &$str): string + { + if (function_exists('str_increment')) { + $str = str_increment($str); // @phpstan-ignore-line + } else { + ++$str; // @phpstan-ignore-line + } + + return $str; // @phpstan-ignore-line + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/BestFit.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/BestFit.php index f9dacfb..3a17205 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/BestFit.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/BestFit.php @@ -351,7 +351,11 @@ abstract class BestFit } } - /** @return float|int */ + /** + * @param array $values + * + * @return float|int + */ private function sumSquares(array $values) { return array_sum( diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php index 188c2ce..0fc6671 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php @@ -3,11 +3,14 @@ namespace PhpOffice\PhpSpreadsheet\Shared\Trend; use Matrix\Matrix; +use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; // Phpstan and Scrutinizer seem to have legitimate complaints. // $this->slope is specified where an array is expected in several places. // But it seems that it should always be float. // This code is probably not exercised at all in unit tests. +// Private bool property $implemented is set to indicate +// whether this implementation is correct. class PolynomialBestFit extends BestFit { /** @@ -21,6 +24,8 @@ class PolynomialBestFit extends BestFit */ protected int $order = 0; + private bool $implemented = false; + /** * Return the order of this polynomial. */ @@ -43,7 +48,9 @@ class PolynomialBestFit extends BestFit // Phpstan and Scrutinizer are both correct - getSlope returns float, not array. // @phpstan-ignore-next-line foreach ($slope as $key => $value) { + /** @var float $value */ if ($value != 0.0) { + /** @var int $key */ $retVal += $value * $xValue ** ($key + 1); } } @@ -77,8 +84,10 @@ class PolynomialBestFit extends BestFit // Phpstan and Scrutinizer are both correct - getSlope returns float, not array. // @phpstan-ignore-next-line foreach ($slope as $key => $value) { + /** @var float|int $value */ if ($value != 0.0) { $equation .= ' + ' . $value . ' * X'; + /** @var int $key */ if ($key > 0) { $equation .= '^' . ($key + 1); } @@ -99,6 +108,7 @@ class PolynomialBestFit extends BestFit $coefficients = []; //* @phpstan-ignore-next-line foreach ($this->slope as $coefficient) { + /** @var float|int $coefficient */ $coefficients[] = round($coefficient, $dp); } @@ -109,6 +119,7 @@ class PolynomialBestFit extends BestFit return $this->slope; } + /** @return array */ public function getCoefficients(int $dp = 0): array { // Phpstan and Scrutinizer are both correct - getSlope returns float, not array. @@ -187,6 +198,10 @@ class PolynomialBestFit extends BestFit */ public function __construct(int $order, array $yValues, array $xValues = []) { + if (!$this->implemented) { + throw new SpreadsheetException('Polynomial Best Fit not yet implemented'); + } + parent::__construct($yValues, $xValues); if (!$this->error) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/Trend.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/Trend.php index dc87943..e44c669 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/Trend.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/Trend.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheet\Shared\Trend; +use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; + class Trend { const TREND_LINEAR = 'Linear'; @@ -18,10 +20,8 @@ class Trend /** * Names of the best-fit Trend analysis methods. - * - * @var string[] */ - private static array $trendTypes = [ + private const TREND_TYPES = [ self::TREND_LINEAR, self::TREND_LOGARITHMIC, self::TREND_EXPONENTIAL, @@ -48,10 +48,16 @@ class Trend */ private static array $trendCache = []; - public static function calculate(string $trendType = self::TREND_BEST_FIT, array $yValues = [], array $xValues = [], bool $const = true): mixed + /** + * @param mixed[] $yValues + * @param mixed[] $xValues + */ + public static function calculate(string $trendType = self::TREND_BEST_FIT, array $yValues = [], array $xValues = [], bool $const = true): BestFit { // Calculate number of points in each dataset + /** @var float[] $xValues */ $nY = count($yValues); + /** @var float[] $xValues */ $nX = count($xValues); // Define X Values if necessary @@ -59,7 +65,7 @@ class Trend $xValues = range(1, $nY); } elseif ($nY !== $nX) { // Ensure both arrays of points are the same size - trigger_error('Trend(): Number of elements in coordinate arrays do not match.', E_USER_ERROR); + throw new SpreadsheetException('Trend(): Number of elements in coordinate arrays do not match.'); } $key = md5($trendType . $const . serialize($yValues) . serialize($xValues)); @@ -71,7 +77,9 @@ class Trend case self::TREND_EXPONENTIAL: case self::TREND_POWER: if (!isset(self::$trendCache[$key])) { + /** @var float[] $yValues */ $className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendType . 'BestFit'; + /** @var float[] $xValues */ self::$trendCache[$key] = new $className($yValues, $xValues, $const); } @@ -83,6 +91,7 @@ class Trend case self::TREND_POLYNOMIAL_6: if (!isset(self::$trendCache[$key])) { $order = (int) substr($trendType, -1); + /** @var float[] $yValues */ self::$trendCache[$key] = new PolynomialBestFit($order, $yValues, $xValues); } @@ -91,15 +100,16 @@ class Trend case self::TREND_BEST_FIT_NO_POLY: // If the request is to determine the best fit regression, then we test each Trend line in turn // Start by generating an instance of each available Trend method + /** @var float[] $yValues */ $bestFit = []; + /** @var float[] $xValues */ $bestFitValue = []; - foreach (self::$trendTypes as $trendMethod) { - $className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendType . 'BestFit'; - //* @phpstan-ignore-next-line + foreach (self::TREND_TYPES as $trendMethod) { + $className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendMethod . 'BestFit'; $bestFit[$trendMethod] = new $className($yValues, $xValues, $const); $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); } - if ($trendType != self::TREND_BEST_FIT_NO_POLY) { + if ($trendType !== self::TREND_BEST_FIT_NO_POLY) { foreach (self::$trendTypePolynomialOrders as $trendMethod) { $order = (int) substr($trendMethod, -1); $bestFit[$trendMethod] = new PolynomialBestFit($order, $yValues, $xValues); @@ -116,7 +126,7 @@ class Trend return $bestFit[$bestFitType]; default: - return false; + throw new SpreadsheetException("Unknown trend type $trendType"); } } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/XMLWriter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/XMLWriter.php index 2703e98..17b1ee6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/XMLWriter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/XMLWriter.php @@ -39,6 +39,10 @@ class XMLWriter extends \XMLWriter if (empty($this->tempFileName) || $this->openUri($this->tempFileName) === false) { // Fallback to memory... $this->openMemory(); + if ($this->tempFileName != '') { + @unlink($this->tempFileName); + } + $this->tempFileName = ''; } } @@ -60,7 +64,8 @@ class XMLWriter extends \XMLWriter } } - public function __wakeup(): void + /** @param mixed[] $data */ + public function __unserialize(array $data): void { $this->tempFileName = ''; @@ -91,6 +96,6 @@ class XMLWriter extends \XMLWriter $rawTextData = implode("\n", $rawTextData); } - return $this->writeRaw(htmlspecialchars($rawTextData ?? '')); + return $this->text($rawTextData ?? ''); } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Xls.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Xls.php index cdb1bf2..6e34a5d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Xls.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Xls.php @@ -201,6 +201,8 @@ class Xls * @param int $offsetY Vertical offset in pixels * @param int $width Width in pixels * @param int $height Height in pixels + * + * @return array{startCoordinates: string, startOffsetX: int, startOffsetY: int, endCoordinates: string, endOffsetX: int, endOffsetY: int} */ public static function oneAnchor2twoAnchor(Worksheet $worksheet, string $coordinates, int $offsetX, int $offsetY, int $width, int $height): ?array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php index 597651b..5681e4a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php @@ -8,6 +8,7 @@ use PhpOffice\PhpSpreadsheet\Cell\IValueBinder; use PhpOffice\PhpSpreadsheet\Document\Properties; use PhpOffice\PhpSpreadsheet\Document\Security; use PhpOffice\PhpSpreadsheet\Shared\Date; +use PhpOffice\PhpSpreadsheet\Shared\Font as SharedFont; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Iterator; @@ -57,7 +58,7 @@ class Spreadsheet implements JsonSerializable /** * Calculation Engine. */ - private ?Calculation $calculationEngine; + private Calculation $calculationEngine; /** * Active sheet index. @@ -115,12 +116,16 @@ class Spreadsheet implements JsonSerializable /** * ribbonBinObjects : null if workbook is'nt Excel 2007 or not contain embedded objects (picture(s)) for Ribbon Elements * ignored if $ribbonXMLData is null. + * + * @var null|mixed[] */ private ?array $ribbonBinObjects = null; /** * List of unparsed loaded data for export to same format with better compatibility. * It has to be minimized when the library start to support currently unparsed data. + * + * @var array|string>>> */ private array $unparsedLoadedData = []; @@ -173,6 +178,36 @@ class Spreadsheet implements JsonSerializable private ?IValueBinder $valueBinder = null; + /** @var array */ + private array $fontCharsets = [ + 'B Nazanin' => SharedFont::CHARSET_ANSI_ARABIC, + ]; + + /** + * @param int $charset uses any value from Shared\Font, + * but defaults to ARABIC because that is the only known + * charset for which this declaration might be needed + */ + public function addFontCharset(string $fontName, int $charset = SharedFont::CHARSET_ANSI_ARABIC): void + { + $this->fontCharsets[$fontName] = $charset; + } + + public function getFontCharset(string $fontName): int + { + return $this->fontCharsets[$fontName] ?? -1; + } + + /** + * Return all fontCharsets. + * + * @return array + */ + public function getFontCharsets(): array + { + return $this->fontCharsets; + } + public function getTheme(): Theme { return $this->theme; @@ -263,6 +298,8 @@ class Spreadsheet implements JsonSerializable /** * retrieve ribbon XML Data. + * + * @return mixed[] */ public function getRibbonXMLData(string $what = 'all'): null|array|string //we need some constants here... { @@ -302,6 +339,8 @@ class Spreadsheet implements JsonSerializable * It has to be minimized when the library start to support currently unparsed data. * * @internal + * + * @return mixed[] */ public function getUnparsedLoadedData(): array { @@ -313,6 +352,8 @@ class Spreadsheet implements JsonSerializable * It has to be minimized when the library start to support currently unparsed data. * * @internal + * + * @param array|string>>> $unparsedLoadedData */ public function setUnparsedLoadedData(array $unparsedLoadedData): void { @@ -321,6 +362,8 @@ class Spreadsheet implements JsonSerializable /** * retrieve Binaries Ribbon Objects. + * + * @return mixed[] */ public function getRibbonBinObjects(string $what = 'all'): ?array { @@ -331,7 +374,7 @@ class Spreadsheet implements JsonSerializable return $this->ribbonBinObjects; case 'names': case 'data': - if (is_array($this->ribbonBinObjects) && isset($this->ribbonBinObjects[$what])) { + if (is_array($this->ribbonBinObjects) && is_array($this->ribbonBinObjects[$what] ?? null)) { $ReturnData = $this->ribbonBinObjects[$what]; } @@ -434,7 +477,7 @@ class Spreadsheet implements JsonSerializable public function __destruct() { $this->disconnectWorksheets(); - $this->calculationEngine = null; + unset($this->calculationEngine); $this->cellXfCollection = []; $this->cellStyleXfCollection = []; $this->definedNames = []; @@ -456,11 +499,25 @@ class Spreadsheet implements JsonSerializable /** * Return the calculation engine for this worksheet. */ - public function getCalculationEngine(): ?Calculation + public function getCalculationEngine(): Calculation { return $this->calculationEngine; } + /** + * Intended for use only via a destructor. + * + * @internal + */ + public function getCalculationEngineOrNull(): ?Calculation + { + if (!isset($this->calculationEngine)) { //* @phpstan-ignore-line + return null; + } + + return $this->calculationEngine; + } + /** * Get properties. */ @@ -648,10 +705,10 @@ class Spreadsheet implements JsonSerializable */ public function getSheetByName(string $worksheetName): ?Worksheet { - $worksheetCount = count($this->workSheetCollection); - for ($i = 0; $i < $worksheetCount; ++$i) { - if (strcasecmp($this->workSheetCollection[$i]->getTitle(), trim($worksheetName, "'")) === 0) { - return $this->workSheetCollection[$i]; + $trimWorksheetName = StringHelper::strToUpper(trim($worksheetName, "'")); + foreach ($this->workSheetCollection as $worksheet) { + if (StringHelper::strToUpper($worksheet->getTitle()) === $trimWorksheetName) { + return $worksheet; } } @@ -678,9 +735,8 @@ class Spreadsheet implements JsonSerializable */ public function getIndex(Worksheet $worksheet, bool $noThrow = false): int { - $wsHash = $worksheet->getHashInt(); foreach ($this->workSheetCollection as $key => $value) { - if ($value->getHashInt() === $wsHash) { + if ($value === $worksheet) { return $key; } } @@ -974,13 +1030,34 @@ class Spreadsheet implements JsonSerializable if ($definedName !== '') { $definedName = StringHelper::strToUpper($definedName); // first look for global defined name - if (isset($this->definedNames[$definedName])) { - $returnValue = $this->definedNames[$definedName]; + foreach ($this->definedNames as $dn) { + $upper = StringHelper::strToUpper($dn->getName()); + if ( + !$dn->getLocalOnly() + && $definedName === $upper + ) { + $returnValue = $dn; + + break; + } } // then look for local defined name (has priority over global defined name if both names exist) - if (($worksheet !== null) && isset($this->definedNames[$worksheet->getTitle() . '!' . $definedName])) { - $returnValue = $this->definedNames[$worksheet->getTitle() . '!' . $definedName]; + if ($worksheet !== null) { + $wsTitle = StringHelper::strToUpper($worksheet->getTitle()); + $definedName = (string) preg_replace('/^.*!/', '', $definedName); + foreach ($this->definedNames as $dn) { + $sheet = $dn->getScope() ?? $dn->getWorksheet(); + $upper = StringHelper::strToUpper($dn->getName()); + $upperTitle = StringHelper::strToUpper((string) $sheet?->getTitle()); + if ( + $dn->getLocalOnly() + && $upper === $definedName + && $upperTitle === $wsTitle + ) { + return $dn; + } + } } } @@ -1058,7 +1135,7 @@ class Spreadsheet implements JsonSerializable */ public function copy(): self { - return unserialize(serialize($this)); + return unserialize(serialize($this)); //* @phpstan-ignore-line } /** @@ -1077,12 +1154,19 @@ class Spreadsheet implements JsonSerializable $oldCalc = $this->calculationEngine; $this->calculationEngine = new Calculation($this); - if ($oldCalc !== null) { - $this->calculationEngine - ->setInstanceArrayReturnType( - $oldCalc->getInstanceArrayReturnType() - ); - } + $this->calculationEngine + ->setSuppressFormulaErrors( + $oldCalc->getSuppressFormulaErrors() + ) + ->setCalculationCacheEnabled( + $oldCalc->getCalculationCacheEnabled() + ) + ->setBranchPruningEnabled( + $oldCalc->getBranchPruningEnabled() + ) + ->setInstanceArrayReturnType( + $oldCalc->getInstanceArrayReturnType() + ); $usedKeys['calculationEngine'] = true; $currentCollection = $this->cellStyleXfCollection; @@ -1119,6 +1203,7 @@ class Spreadsheet implements JsonSerializable switch ($key) { // arrays of objects not covered above case 'definedNames': + /** @var DefinedName[] */ $currentCollection = $val; $this->$key = []; foreach ($currentCollection as $item) { @@ -1382,6 +1467,10 @@ class Spreadsheet implements JsonSerializable /** * Return the unique ID value assigned to this spreadsheet workbook. + * + * @deprecated 5.2.0 Serves no useful purpose. No replacement. + * + * @codeCoverageIgnore */ public function getID(): string { @@ -1666,7 +1755,10 @@ class Spreadsheet implements JsonSerializable public function getLegacyDrawing(Worksheet $worksheet): ?string { - return $this->unparsedLoadedData['sheets'][$worksheet->getCodeName()]['legacyDrawing'] ?? null; + /** @var ?string */ + $temp = $this->unparsedLoadedData['sheets'][$worksheet->getCodeName()]['legacyDrawing'] ?? null; + + return $temp; } public function getValueBinder(): ?IValueBinder @@ -1728,4 +1820,35 @@ class Spreadsheet implements JsonSerializable } } } + + /** + * Excel will sometimes replace user's formatting choice + * with a built-in choice that it thinks is equivalent. + * Its choice is often not equivalent after all. + * Such treatment is astonishingly user-hostile. + * This function will undo such changes. + */ + public function replaceBuiltinNumberFormat(int $builtinFormatIndex, string $formatCode): void + { + foreach ($this->cellXfCollection as $style) { + $numberFormat = $style->getNumberFormat(); + if ($numberFormat->getBuiltInFormatCode() === $builtinFormatIndex) { + $numberFormat->setFormatCode($formatCode); + } + } + } + + public function returnArrayAsArray(): void + { + $this->calculationEngine->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_ARRAY + ); + } + + public function returnArrayAsValue(): void + { + $this->calculationEngine->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Alignment.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Alignment.php index a502299..6ff44e3 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Alignment.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Alignment.php @@ -92,6 +92,8 @@ class Alignment extends Supervisor const TEXTROTATION_STACK_EXCEL = 255; const TEXTROTATION_STACK_PHPSPREADSHEET = -165; // 90 - 255 + public const INDENT_UNITS_TO_PIXELS = 9; + /** * Horizontal alignment. */ @@ -168,6 +170,10 @@ class Alignment extends Supervisor /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return array{alignment: mixed[]} */ public function getStyleArray(array $array): array { @@ -188,7 +194,7 @@ class Alignment extends Supervisor * ); * * - * @param array $styleArray Array containing style information + * @param mixed[] $styleArray Array containing style information * * @return $this */ @@ -198,6 +204,7 @@ class Alignment extends Supervisor $this->getActiveSheet()->getStyle($this->getSelectedCells()) ->applyFromArray($this->getStyleArray($styleArray)); } else { + /** @var array{horizontal?: string, vertical?: string, justifyLastLine?: bool, textRotation?: int, wrapText?: bool, shrinkToFit?: bool, readOrder?: int, indent?: int} $styleArray */ if (isset($styleArray['horizontal'])) { $this->setHorizontal($styleArray['horizontal']); } @@ -523,6 +530,7 @@ class Alignment extends Supervisor ); } + /** @return mixed[] */ protected function exportArray1(): array { $exportedArray = []; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Border.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Border.php index 0716256..ea2ff5f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Border.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Border.php @@ -83,6 +83,10 @@ class Border extends Supervisor /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return mixed[] */ public function getStyleArray(array $array): array { @@ -106,7 +110,7 @@ class Border extends Supervisor * ); * * - * @param array $styleArray Array containing style information + * @param mixed[] $styleArray Array containing style information * * @return $this */ @@ -115,11 +119,13 @@ class Border extends Supervisor if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); } else { + /** @var array{borderStyle?: string, color?: array{rgb?: string, argb?: string}} $styleArray */ if (isset($styleArray['borderStyle'])) { $this->setBorderStyle($styleArray['borderStyle']); } if (isset($styleArray['color'])) { - $this->getColor()->applyFromArray($styleArray['color']); + $this->getColor() + ->applyFromArray($styleArray['color']); } } @@ -210,6 +216,7 @@ class Border extends Supervisor ); } + /** @return mixed[] */ protected function exportArray1(): array { $exportedArray = []; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Borders.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Borders.php index 1d23af3..05ee0df 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Borders.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Borders.php @@ -124,6 +124,10 @@ class Borders extends Supervisor /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return array{borders: mixed[]} */ public function getStyleArray(array $array): array { @@ -165,7 +169,7 @@ class Borders extends Supervisor * ); * * - * @param array $styleArray Array containing style information + * @param mixed[] $styleArray Array containing style information * * @return $this */ @@ -174,6 +178,7 @@ class Borders extends Supervisor if ($this->isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); } else { + /** @var array{left?: float[], right?: float[], top?: float[], bottom?: float[], diagonal?: mixed[], diagonalDirection?: int, allBorders?: mixed[][]} $styleArray */ if (isset($styleArray['left'])) { $this->getLeft()->applyFromArray($styleArray['left']); } @@ -356,6 +361,7 @@ class Borders extends Supervisor ); } + /** @return mixed[][] */ protected function exportArray1(): array { $exportedArray = []; @@ -365,6 +371,7 @@ class Borders extends Supervisor $this->exportArray2($exportedArray, 'left', $this->getLeft()); $this->exportArray2($exportedArray, 'right', $this->getRight()); $this->exportArray2($exportedArray, 'top', $this->getTop()); + /** @var mixed[][] $exportedArray */ return $exportedArray; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Color.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Color.php index 8aa4734..10929bc 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Color.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Color.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheet\Style; +use PhpOffice\PhpSpreadsheet\Theme; + class Color extends Supervisor { const NAMED_COLORS = [ @@ -111,6 +113,8 @@ class Color extends Supervisor private bool $hasChanged = false; + private int $theme = -1; + /** * Create a new Color. * @@ -156,6 +160,10 @@ class Color extends Supervisor /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return mixed[] */ public function getStyleArray(array $array): array { @@ -172,14 +180,18 @@ class Color extends Supervisor * $spreadsheet->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray(['rgb' => '808080']); * * - * @param array $styleArray Array containing style information + * @param array{rgb?: string, argb?: string, theme?: int} $styleArray Array containing style information * * @return $this */ public function applyFromArray(array $styleArray): static { if ($this->isSupervisor) { - $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); + $this->getActiveSheet() + ->getStyle($this->getSelectedCells()) + ->applyFromArray( + $this->getStyleArray($styleArray) + ); } else { if (isset($styleArray['rgb'])) { $this->setRGB($styleArray['rgb']); @@ -187,6 +199,9 @@ class Color extends Supervisor if (isset($styleArray['argb'])) { $this->setARGB($styleArray['argb']); } + if (isset($styleArray['theme'])) { + $this->setTheme($styleArray['theme']); + } } return $this; @@ -233,6 +248,7 @@ class Color extends Supervisor public function setARGB(?string $colorValue = self::COLOR_BLACK, bool $nullStringOkay = false): static { $this->hasChanged = true; + $this->setTheme(-1); if (!$nullStringOkay || $colorValue !== '') { $colorValue = $this->validateColor($colorValue); if ($colorValue === '') { @@ -365,6 +381,7 @@ class Color extends Supervisor * @param int $colorIndex Index entry point into the colour array * @param bool $background Flag to indicate whether default background or foreground colour * should be returned if the indexed colour doesn't exist + * @param null|string[] $palette */ public static function indexedColor(int $colorIndex, bool $background = false, ?array $palette = null): self { @@ -397,14 +414,17 @@ class Color extends Supervisor return md5( $this->argb + . (string) $this->theme . __CLASS__ ); } + /** @return mixed[] */ protected function exportArray1(): array { $exportedArray = []; $this->exportArray2($exportedArray, 'argb', $this->getARGB()); + $this->exportArray2($exportedArray, 'theme', $this->getTheme()); return $exportedArray; } @@ -417,4 +437,42 @@ class Color extends Supervisor return $this->hasChanged; } + + public function getTheme(): int + { + if ($this->isSupervisor) { + return $this->getSharedComponent()->getTheme(); + } + + return $this->theme; + } + + public function setTheme(int $theme): self + { + $this->hasChanged = true; + + if ($this->isSupervisor) { + $styleArray = $this->getStyleArray(['theme' => $theme]); + $this->getActiveSheet() + ->getStyle($this->getSelectedCells()) + ->applyFromArray($styleArray); + } else { + $this->theme = $theme; + } + + return $this; + } + + public function setHyperlinkTheme(): self + { + $rgb = $this->getActiveSheet() + ->getParent() + ?->getTheme() + ->getThemeColors(); + if (is_array($rgb) && array_key_exists('hlink', $rgb)) { + $this->setRGB($rgb['hlink']); + } + + return $this->setTheme(Theme::HYPERLINK_THEME); + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Conditional.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Conditional.php index d476bdf..fedd0aa 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Conditional.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Conditional.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\IComparable; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalColorScale; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar; +use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalIconSet; class Conditional implements IComparable { @@ -25,6 +26,7 @@ class Conditional implements IComparable const CONDITION_TIMEPERIOD = 'timePeriod'; const CONDITION_DUPLICATES = 'duplicateValues'; const CONDITION_UNIQUE = 'uniqueValues'; + const CONDITION_ICONSET = 'iconSet'; private const CONDITION_TYPES = [ self::CONDITION_BEGINSWITH, @@ -43,6 +45,7 @@ class Conditional implements IComparable self::CONDITION_NOTCONTAINSTEXT, self::CONDITION_TIMEPERIOD, self::CONDITION_UNIQUE, + self::CONDITION_ICONSET, ]; // Operator types @@ -102,6 +105,8 @@ class Conditional implements IComparable private ?ConditionalColorScale $colorScale = null; + private ?ConditionalIconSet $iconSet = null; + private Style $style; private bool $noFormatSet = false; @@ -269,8 +274,16 @@ class Conditional implements IComparable /** * Get Style. */ - public function getStyle(): Style + public function getStyle(mixed $cellData = null): Style { + if ($this->conditionType === self::CONDITION_COLORSCALE && $cellData !== null && $this->colorScale !== null && is_numeric($cellData)) { + $style = new Style(isConditional: true); + $style->getFill()->setFillType(Fill::FILL_SOLID); + $style->getFill()->getStartColor()->setARGB($this->colorScale->getColorForValue((float) $cellData)); + + return $style; + } + return $this->style; } @@ -310,6 +323,18 @@ class Conditional implements IComparable return $this; } + public function getIconSet(): ?ConditionalIconSet + { + return $this->iconSet; + } + + public function setIconSet(ConditionalIconSet $iconSet): static + { + $this->iconSet = $iconSet; + + return $this; + } + /** * Get hash code. * @@ -319,10 +344,10 @@ class Conditional implements IComparable { return md5( $this->conditionType - . $this->operatorType - . implode(';', $this->condition) - . $this->style->getHashCode() - . __CLASS__ + . $this->operatorType + . implode(';', $this->condition) + . $this->style->getHashCode() + . __CLASS__ ); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellMatcher.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellMatcher.php index e14ceac..f0deb56 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellMatcher.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellMatcher.php @@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; @@ -110,6 +111,7 @@ class CellMatcher // Last 7 Days AND(TODAY()-FLOOR(,1)<=6,FLOOR(,1)<=TODAY()) Conditional::CONDITION_TIMEPERIOD, Conditional::CONDITION_EXPRESSION => $this->processExpression($conditional), + Conditional::CONDITION_COLORSCALE => $this->processColorScale($conditional), default => false, }; } @@ -123,7 +125,7 @@ class CellMatcher return 'NULL'; } - return '"' . $value . '"'; + return '"' . StringHelper::convertToString($value) . '"'; } return $value; @@ -136,19 +138,20 @@ class CellMatcher return $this->wrapValue($this->cell->getCalculatedValue()); } + /** @param string[] $matches */ protected function conditionCellAdjustment(array $matches): float|int|string { $column = $matches[6]; $row = $matches[7]; - if (!str_contains($column, '$')) { + // $column = Coordinate::stringFromColumnIndex($this->cellColumn); $column = Coordinate::columnIndexFromString($column); $column += $this->cellColumn - $this->referenceColumn; $column = Coordinate::stringFromColumnIndex($column); } if (!str_contains($row, '$')) { - $row += $this->cellRow - $this->referenceRow; + $row = (int) $row + $this->cellRow - $this->referenceRow; } if (!empty($matches[4])) { @@ -192,6 +195,11 @@ class CellMatcher return implode(Calculation::FORMULA_STRING_QUOTE, $splitCondition); } + /** + * @param mixed[] $conditions + * + * @return mixed[] + */ protected function adjustConditionsForCellReferences(array $conditions): array { return array_map( @@ -208,11 +216,24 @@ class CellMatcher $operator = self::COMPARISON_OPERATORS[$conditional->getOperatorType()]; $conditions = $this->adjustConditionsForCellReferences($conditional->getConditions()); - $expression = sprintf('%s%s%s', (string) $this->wrapCellValue(), $operator, (string) array_pop($conditions)); + /** @var float|int|string */ + $temp1 = $this->wrapCellValue(); + /** @var scalar */ + $temp2 = array_pop($conditions); + $expression = sprintf('%s%s%s', (string) $temp1, $operator, (string) $temp2); return $this->evaluateExpression($expression); } + protected function processColorScale(Conditional $conditional): bool + { + if (is_numeric($this->wrapCellValue()) && $conditional->getColorScale()?->colorScaleReadyForUse()) { + return true; + } + + return false; + } + protected function processRangeOperator(Conditional $conditional): bool { $conditions = $this->adjustConditionsForCellReferences($conditional->getConditions()); @@ -223,7 +244,7 @@ class CellMatcher (string) $this->wrapCellValue(), self::COMPARISON_RANGE_OPERATORS[$conditional->getOperatorType()] ), - ...$conditions + ...$conditions //* @phpstan-ignore-line ); return $this->evaluateExpression($expression); @@ -246,11 +267,14 @@ class CellMatcher protected function processExpression(Conditional $conditional): bool { $conditions = $this->adjustConditionsForCellReferences($conditional->getConditions()); + /** @var string */ $expression = array_pop($conditions); + /** @var float|int|string */ + $temp = $this->wrapCellValue(); $expression = (string) preg_replace( '/\b' . $this->referenceCell . '\b/i', - (string) $this->wrapCellValue(), + (string) $temp, $expression ); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellStyleAssessor.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellStyleAssessor.php index bcf59de..f8826f0 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellStyleAssessor.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/CellStyleAssessor.php @@ -12,8 +12,11 @@ class CellStyleAssessor protected StyleMerger $styleMerger; + protected Cell $cell; + public function __construct(Cell $cell, string $conditionalRange) { + $this->cell = $cell; $this->cellMatcher = new CellMatcher($cell, $conditionalRange); $this->styleMerger = new StyleMerger($cell->getStyle()); } @@ -26,7 +29,7 @@ class CellStyleAssessor foreach ($conditionalStyles as $conditional) { if ($this->cellMatcher->evaluateConditional($conditional) === true) { // Merging the conditional style into the base style goes in here - $this->styleMerger->mergeStyle($conditional->getStyle()); + $this->styleMerger->mergeStyle($conditional->getStyle($this->cell->getValue())); if ($conditional->getStopIfTrue() === true) { break; } @@ -35,4 +38,28 @@ class CellStyleAssessor return $this->styleMerger->getStyle(); } + + /** + * @param Conditional[] $conditionalStyles + */ + public function matchConditionsReturnNullIfNoneMatched(array $conditionalStyles, string $cellData, bool $stopAtFirstMatch = false): ?Style + { + $matched = false; + $value = (float) $cellData; + foreach ($conditionalStyles as $conditional) { + if ($this->cellMatcher->evaluateConditional($conditional) === true) { + $matched = true; + // Merging the conditional style into the base style goes in here + $this->styleMerger->mergeStyle($conditional->getStyle($value)); + if ($conditional->getStopIfTrue() === true || $stopAtFirstMatch) { + break; + } + } + } + if ($matched) { + return $this->styleMerger->getStyle(); + } + + return null; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalColorScale.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalColorScale.php index 7fcc080..539b331 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalColorScale.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalColorScale.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Percentiles; use PhpOffice\PhpSpreadsheet\Style\Color; class ConditionalColorScale @@ -18,6 +19,19 @@ class ConditionalColorScale private ?Color $maximumColor = null; + private ?string $sqref = null; + + /** @var mixed[] */ + private array $valueArray = []; + + private float $minValue = 0; + + private float $maxValue = 0; + + private float $midValue = 0; + + private ?\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet = null; + public function getMinimumConditionalFormatValueObject(): ?ConditionalFormatValueObject { return $this->minimumConditionalFormatValueObject; @@ -89,4 +103,166 @@ class ConditionalColorScale return $this; } + + public function getSqRef(): ?string + { + return $this->sqref; + } + + public function setSqRef(string $sqref, \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet): self + { + $this->sqref = $sqref; + $this->worksheet = $worksheet; + + return $this; + } + + public function setScaleArray(): self + { + if ($this->sqref !== null && $this->worksheet !== null) { + $values = $this->worksheet->rangesToArray($this->sqref, null, true, true, true); + $this->valueArray = []; + foreach ($values as $key => $value) { + /** @var array $value */ + foreach ($value as $k => $v) { + $this->valueArray[] = (float) $v; + } + } + $this->prepareColorScale(); + } + + return $this; + } + + public function getColorForValue(float $value): string + { + if ($this->minimumColor === null || $this->midpointColor === null || $this->maximumColor === null) { + return 'FF000000'; + } + $minColor = $this->minimumColor->getARGB(); + $midColor = $this->midpointColor->getARGB(); + $maxColor = $this->maximumColor->getARGB(); + + if ($minColor === null || $midColor === null || $maxColor === null) { + return 'FF000000'; + } + + if ($value <= $this->minValue) { + return $minColor; + } + if ($value >= $this->maxValue) { + return $maxColor; + } + if ($value == $this->midValue) { + return $midColor; + } + if ($value < $this->midValue) { + $blend = ($value - $this->minValue) / ($this->midValue - $this->minValue); + $alpha1 = hexdec(substr($minColor, 0, 2)); + $alpha2 = hexdec(substr($midColor, 0, 2)); + $red1 = hexdec(substr($minColor, 2, 2)); + $red2 = hexdec(substr($midColor, 2, 2)); + $green1 = hexdec(substr($minColor, 4, 2)); + $green2 = hexdec(substr($midColor, 4, 2)); + $blue1 = hexdec(substr($minColor, 6, 2)); + $blue2 = hexdec(substr($midColor, 6, 2)); + + return strtoupper(dechex((int) ($alpha2 * $blend + $alpha1 * (1 - $blend))) . '' . dechex((int) ($red2 * $blend + $red1 * (1 - $blend))) . '' . dechex((int) ($green2 * $blend + $green1 * (1 - $blend))) . '' . dechex((int) ($blue2 * $blend + $blue1 * (1 - $blend)))); + } + $blend = ($value - $this->midValue) / ($this->maxValue - $this->midValue); + $alpha1 = hexdec(substr($midColor, 0, 2)); + $alpha2 = hexdec(substr($maxColor, 0, 2)); + $red1 = hexdec(substr($midColor, 2, 2)); + $red2 = hexdec(substr($maxColor, 2, 2)); + $green1 = hexdec(substr($midColor, 4, 2)); + $green2 = hexdec(substr($maxColor, 4, 2)); + $blue1 = hexdec(substr($midColor, 6, 2)); + $blue2 = hexdec(substr($maxColor, 6, 2)); + + return strtoupper(dechex((int) ($alpha2 * $blend + $alpha1 * (1 - $blend))) . '' . dechex((int) ($red2 * $blend + $red1 * (1 - $blend))) . '' . dechex((int) ($green2 * $blend + $green1 * (1 - $blend))) . '' . dechex((int) ($blue2 * $blend + $blue1 * (1 - $blend)))); + } + + private function getLimitValue(string $type, float $value = 0, float $formula = 0): float + { + if (count($this->valueArray) === 0) { + return 0; + } + switch ($type) { + case 'min': + /** @var float|int */ + $temp = min($this->valueArray); + + return (float) $temp; + case 'max': + /** @var float|int */ + $temp = max($this->valueArray); + + return (float) $temp; + case 'percentile': + return (float) Percentiles::PERCENTILE($this->valueArray, (float) ($value / 100)); + case 'formula': + return $formula; + case 'percent': + /** @var float|int */ + $min = min($this->valueArray); + $min = (float) $min; + /** @var float|int */ + $max = max($this->valueArray); + $max = (float) $max; + + return $min + (float) ($value / 100) * ($max - $min); + default: + return 0; + } + } + + /** + * Prepares color scale for execution, see the first if for variables that must be set beforehand. + */ + public function prepareColorScale(): self + { + if ($this->minimumConditionalFormatValueObject !== null && $this->maximumConditionalFormatValueObject !== null && $this->minimumColor !== null && $this->maximumColor !== null) { + if ($this->midpointConditionalFormatValueObject !== null && $this->midpointConditionalFormatValueObject->getType() !== 'None') { + $this->minValue = $this->getLimitValue($this->minimumConditionalFormatValueObject->getType(), (float) $this->minimumConditionalFormatValueObject->getValue(), (float) $this->minimumConditionalFormatValueObject->getCellFormula()); + $this->midValue = $this->getLimitValue($this->midpointConditionalFormatValueObject->getType(), (float) $this->midpointConditionalFormatValueObject->getValue(), (float) $this->midpointConditionalFormatValueObject->getCellFormula()); + $this->maxValue = $this->getLimitValue($this->maximumConditionalFormatValueObject->getType(), (float) $this->maximumConditionalFormatValueObject->getValue(), (float) $this->maximumConditionalFormatValueObject->getCellFormula()); + } else { + $this->minValue = $this->getLimitValue($this->minimumConditionalFormatValueObject->getType(), (float) $this->minimumConditionalFormatValueObject->getValue(), (float) $this->minimumConditionalFormatValueObject->getCellFormula()); + $this->maxValue = $this->getLimitValue($this->maximumConditionalFormatValueObject->getType(), (float) $this->maximumConditionalFormatValueObject->getValue(), (float) $this->maximumConditionalFormatValueObject->getCellFormula()); + $this->midValue = (float) ($this->minValue + $this->maxValue) / 2; + $blend = 0.5; + + $minColor = $this->minimumColor->getARGB(); + $maxColor = $this->maximumColor->getARGB(); + + if ($minColor !== null && $maxColor !== null) { + $alpha1 = hexdec(substr($minColor, 0, 2)); + $alpha2 = hexdec(substr($maxColor, 0, 2)); + $red1 = hexdec(substr($minColor, 2, 2)); + $red2 = hexdec(substr($maxColor, 2, 2)); + $green1 = hexdec(substr($minColor, 4, 2)); + $green2 = hexdec(substr($maxColor, 4, 2)); + $blue1 = hexdec(substr($minColor, 6, 2)); + $blue2 = hexdec(substr($maxColor, 6, 2)); + $this->midpointColor = new Color(strtoupper(dechex((int) ($alpha2 * $blend + $alpha1 * (1 - $blend))) . '' . dechex((int) ($red2 * $blend + $red1 * (1 - $blend))) . '' . dechex((int) ($green2 * $blend + $green1 * (1 - $blend))) . '' . dechex((int) ($blue2 * $blend + $blue1 * (1 - $blend))))); + } else { + $this->midpointColor = null; + } + } + } + + return $this; + } + + /** + * Checks that all needed color scale data is in place. + */ + public function colorScaleReadyForUse(): bool + { + if ($this->minimumColor === null || $this->midpointColor === null || $this->maximumColor === null) { + return false; + } + + return true; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php index 28cd94b..a94bc28 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php @@ -31,12 +31,14 @@ class ConditionalDataBarExtension private ?string $negativeBorderColor = null; + /** @var array{rgb: ?string, theme: ?string, tint: ?string} */ private array $axisColor = [ 'rgb' => null, 'theme' => null, 'tint' => null, ]; + /** @return mixed[] */ public function getXmlAttributes(): array { $ret = []; @@ -54,6 +56,7 @@ class ConditionalDataBarExtension return $ret; } + /** @return mixed[] */ public function getXmlElements(): array { $ret = []; @@ -217,12 +220,13 @@ class ConditionalDataBarExtension return $this; } + /** @return array{rgb: ?string, theme: ?string, tint: ?string} */ public function getAxisColor(): array { return $this->axisColor; } - public function setAxisColor(mixed $rgb, mixed $theme = null, mixed $tint = null): self + public function setAxisColor(?string $rgb, ?string $theme = null, ?string $tint = null): self { $this->axisColor = [ 'rgb' => $rgb, diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php index e6d1035..d1dfb51 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php @@ -10,6 +10,13 @@ class ConditionalFormatValueObject private ?string $cellFormula; + /** + * For icon sets, determines whether this threshold value uses the greater + * than or equal to operator. False indicates 'greater than' is used instead + * of 'greater than or equal to'. + */ + private ?bool $greaterThanOrEqual = null; + public function __construct(string $type, null|float|int|string $value = null, ?string $cellFormula = null) { $this->type = $type; @@ -52,4 +59,16 @@ class ConditionalFormatValueObject return $this; } + + public function getGreaterThanOrEqual(): ?bool + { + return $this->greaterThanOrEqual; + } + + public function setGreaterThanOrEqual(?bool $greaterThanOrEqual): self + { + $this->greaterThanOrEqual = $greaterThanOrEqual; + + return $this; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php index ad7dfc4..906006b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php @@ -47,6 +47,7 @@ class ConditionalFormattingRuleExtension return implode('', $chars); } + /** @return mixed[] */ public static function parseExtLstXml(?SimpleXMLElement $extLstXml): array { $conditionalFormattingRuleExtensions = []; @@ -118,6 +119,7 @@ class ConditionalFormattingRuleExtension } } + /** @param string[] $ns */ private static function parseExtDataBarElementChildrenFromXml(ConditionalDataBarExtension $extDataBarObj, SimpleXMLElement $dataBarXml, array $ns): void { if ($dataBarXml->borderColor) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/StyleMerger.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/StyleMerger.php index 10f3ba6..645f238 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/StyleMerger.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/StyleMerger.php @@ -14,7 +14,10 @@ class StyleMerger public function __construct(Style $baseStyle) { - $this->baseStyle = $baseStyle; + // Setting to $baseStyle sometimes causes problems later on. + $array = $baseStyle->exportArray(); + $this->baseStyle = new Style(); + $this->baseStyle->applyFromArray($array); } public function getStyle(): Style @@ -75,7 +78,11 @@ class StyleMerger protected function mergeBorderStyle(Border $baseBorderStyle, Border $borderStyle): void { - $baseBorderStyle->setBorderStyle($borderStyle->getBorderStyle()); + if ($borderStyle->getBorderStyle() !== Border::BORDER_OMIT) { + $baseBorderStyle->setBorderStyle( + $borderStyle->getBorderStyle() + ); + } if ($borderStyle->getColor()->getARGB() !== null) { $baseBorderStyle->setColor($borderStyle->getColor()); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/CellValue.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/CellValue.php index 63f360b..032bb98 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/CellValue.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/CellValue.php @@ -38,6 +38,7 @@ class CellValue extends WizardAbstract implements WizardInterface protected string $operator = Conditional::OPERATOR_EQUAL; + /** @var array */ protected array $operand = [0]; /** @@ -65,7 +66,7 @@ class CellValue extends WizardAbstract implements WizardInterface $operand = $this->validateOperand($operand, $operandValueType); } - $this->operand[$index] = $operand; + $this->operand[$index] = $operand; //* @phpstan-ignore-line $this->operandValueType[$index] = $operandValueType; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Expression.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Expression.php index 3f95441..7623158 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Expression.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Expression.php @@ -28,6 +28,7 @@ class Expression extends WizardAbstract implements WizardInterface public function getConditional(): Conditional { + /** @var string[] */ $expression = $this->adjustConditionsForCellReferences([$this->expression]); $conditional = new Conditional(); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/WizardAbstract.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/WizardAbstract.php index 953a559..9f64ad1 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/WizardAbstract.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/WizardAbstract.php @@ -82,6 +82,7 @@ abstract class WizardAbstract return $operand; } + /** @param string[] $matches */ protected static function reverseCellAdjustment(array $matches, int $referenceColumn, int $referenceRow): string { $worksheet = $matches[1]; @@ -95,7 +96,7 @@ abstract class WizardAbstract } if (!str_contains($row, '$')) { - $row -= $referenceRow - 1; + $row = (int) $row - ($referenceRow - 1); } return "{$worksheet}{$column}{$row}"; @@ -126,6 +127,7 @@ abstract class WizardAbstract return implode(Calculation::FORMULA_STRING_QUOTE, $splitCondition); } + /** @param string[] $matches */ protected function conditionCellAdjustment(array $matches): string { $worksheet = $matches[1]; @@ -139,7 +141,7 @@ abstract class WizardAbstract } if (!str_contains($row, '$')) { - $row += $this->referenceRow - 1; + $row = (int) $row + ($this->referenceRow - 1); } return "{$worksheet}{$column}{$row}"; @@ -166,6 +168,11 @@ abstract class WizardAbstract return implode(Calculation::FORMULA_STRING_QUOTE, $splitCondition); } + /** + * @param mixed[] $conditions + * + * @return mixed[] + */ protected function adjustConditionsForCellReferences(array $conditions): array { return array_map( diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Fill.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Fill.php index 9ec5d73..66fe271 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Fill.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Fill.php @@ -96,6 +96,10 @@ class Fill extends Supervisor /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return array{fill: mixed[]} */ public function getStyleArray(array $array): array { @@ -120,7 +124,7 @@ class Fill extends Supervisor * ); * * - * @param array $styleArray Array containing style information + * @param array{fillType?: string, rotation?: float, startColor?: array{rgb?: string, argb?: string}, endColor?: array{rgb?: string, argb?: string}, color?: array{rgb?: string, argb?: string}} $styleArray Array containing style information * * @return $this */ @@ -136,14 +140,18 @@ class Fill extends Supervisor $this->setRotation($styleArray['rotation']); } if (isset($styleArray['startColor'])) { - $this->getStartColor()->applyFromArray($styleArray['startColor']); + $this->getStartColor() + ->applyFromArray($styleArray['startColor']); } if (isset($styleArray['endColor'])) { - $this->getEndColor()->applyFromArray($styleArray['endColor']); + $this->getEndColor() + ->applyFromArray($styleArray['endColor']); } if (isset($styleArray['color'])) { - $this->getStartColor()->applyFromArray($styleArray['color']); - $this->getEndColor()->applyFromArray($styleArray['color']); + $this->getStartColor() + ->applyFromArray($styleArray['color']); + $this->getEndColor() + ->applyFromArray($styleArray['color']); } } @@ -302,6 +310,7 @@ class Fill extends Supervisor ); } + /** @return mixed[] */ protected function exportArray1(): array { $exportedArray = []; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Font.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Font.php index 7d70dc4..ae5ec6c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Font.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Font.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Chart\ChartColor; +use PhpOffice\PhpSpreadsheet\Theme; class Font extends Supervisor { @@ -85,6 +86,8 @@ class Font extends Supervisor */ protected Color $color; + protected bool $autoColor = false; + public ?int $colorIndex = null; protected string $scheme = ''; @@ -124,6 +127,14 @@ class Font extends Supervisor } } + public function applyThemeFonts(Theme $theme): void + { + $this->setName($theme->getMinorFontLatin()); + $this->setLatin($theme->getMinorFontLatin()); + $this->setEastAsian($theme->getMinorFontEastAsian()); + $this->setComplexScript($theme->getMinorFontComplexScript()); + } + /** * Get the shared style component for the currently active cell in currently active sheet. * Only used for style supervisor. @@ -138,6 +149,10 @@ class Font extends Supervisor /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return array{font: mixed[]} */ public function getStyleArray(array $array): array { @@ -162,7 +177,7 @@ class Font extends Supervisor * ); * * - * @param array $styleArray Array containing style information + * @param array{name?: string, latin?: string, eastAsian?: string, complexScript?: string, bold?: bool, italic?: bool, superscript?: bool, subscript?: bool, underline?: bool|string, strikethrough?: bool, color?: string[], size?: ?int, chartColor?: ChartColor, scheme?: string, cap?: string, autoColor?: bool} $styleArray Array containing style information * * @return $this */ @@ -181,7 +196,9 @@ class Font extends Supervisor $this->setEastAsian($styleArray['eastAsian']); } if (isset($styleArray['complexScript'])) { - $this->setComplexScript($styleArray['complexScript']); + $this->setComplexScript( + $styleArray['complexScript'] + ); } if (isset($styleArray['bold'])) { $this->setBold($styleArray['bold']); @@ -199,10 +216,15 @@ class Font extends Supervisor $this->setUnderline($styleArray['underline']); } if (isset($styleArray['strikethrough'])) { - $this->setStrikethrough($styleArray['strikethrough']); + $this->setStrikethrough( + $styleArray['strikethrough'] + ); } if (isset($styleArray['color'])) { - $this->getColor()->applyFromArray($styleArray['color']); + /** @var array{rgb?: string, argb?: string, theme?: int} */ + $temp = $styleArray['color']; + $this->getColor() + ->applyFromArray($temp); } if (isset($styleArray['size'])) { $this->setSize($styleArray['size']); @@ -216,6 +238,9 @@ class Font extends Supervisor if (isset($styleArray['cap'])) { $this->setCap($styleArray['cap']); } + if (isset($styleArray['autoColor'])) { + $this->setAutoColor($styleArray['autoColor']); + } } return $this; @@ -394,9 +419,6 @@ class Font extends Supervisor */ public function setBold(bool $bold): static { - if ($bold == '') { - $bold = false; - } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['bold' => $bold]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); @@ -426,9 +448,6 @@ class Font extends Supervisor */ public function setItalic(bool $italic): static { - if ($italic == '') { - $italic = false; - } if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['italic' => $italic]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); @@ -560,6 +579,7 @@ class Font extends Supervisor return $this->underlineColor; } + /** @param array{value: null|string, alpha: null|int|string, brightness?: null|int|string, type: null|string} $colorArray */ public function setUnderlineColor(array $colorArray): self { if (!$this->isSupervisor) { @@ -584,6 +604,7 @@ class Font extends Supervisor return $this->chartColor; } + /** @param array{value: null|string, alpha: null|int|string, brightness?: null|int|string, type: null|string} $colorArray */ public function setChartColor(array $colorArray): self { if (!$this->isSupervisor) { @@ -663,10 +684,6 @@ class Font extends Supervisor */ public function setStrikethrough(bool $strikethru): static { - if ($strikethru == '') { - $strikethru = false; - } - if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['strikethrough' => $strikethru]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); @@ -737,6 +754,7 @@ class Font extends Supervisor . ($this->subscript ? 't' : 'f') . $this->underline . ($this->strikethrough ? 't' : 'f') + . ($this->autoColor ? 't' : 'f') . $this->color->getHashCode() . $this->scheme . implode( @@ -756,6 +774,7 @@ class Font extends Supervisor ); } + /** @return mixed[] */ protected function exportArray1(): array { $exportedArray = []; @@ -777,6 +796,7 @@ class Font extends Supervisor $this->exportArray2($exportedArray, 'superscript', $this->getSuperscript()); $this->exportArray2($exportedArray, 'underline', $this->getUnderline()); $this->exportArray2($exportedArray, 'underlineColor', $this->getUnderlineColor()); + $this->exportArray2($exportedArray, 'autoColor', $this->getAutoColor()); return $exportedArray; } @@ -823,6 +843,37 @@ class Font extends Supervisor return $this->cap; } + public function setHyperlinkTheme(): self + { + $this->color->setHyperlinkTheme(); + $this->setUnderline(self::UNDERLINE_SINGLE); + + return $this; + } + + public function setAutoColor(bool $autoColor): self + { + if ($this->isSupervisor) { + $styleArray = $this->getStyleArray(['autoColor' => $autoColor]); + $this->getActiveSheet() + ->getStyle($this->getSelectedCells()) + ->applyFromArray($styleArray); + } else { + $this->autoColor = $autoColor; + } + + return $this; + } + + public function getAutoColor(): bool + { + if ($this->isSupervisor) { + return $this->getSharedComponent()->getAutoColor(); + } + + return $this->autoColor; + } + /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat.php index 9c9a545..07d0017 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat.php @@ -109,11 +109,15 @@ class NumberFormat extends Supervisor /** * Excel built-in number formats. + * + * @var string[] */ protected static array $builtInFormats; /** * Excel built-in number formats (flipped, for faster lookups). + * + * @var int[] */ protected static array $flippedBuiltInFormats; @@ -164,6 +168,10 @@ class NumberFormat extends Supervisor /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return array{numberFormat: mixed[]} */ public function getStyleArray(array $array): array { @@ -181,7 +189,7 @@ class NumberFormat extends Supervisor * ); * * - * @param array $styleArray Array containing style information + * @param string[] $styleArray Array containing style information * * @return $this */ @@ -458,15 +466,17 @@ class NumberFormat extends Supervisor * @param null|bool|float|int|RichText|string $value Value to format * @param string $format Format code: see = self::FORMAT_* for predefined values; * or can be any valid MS Excel custom format string - * @param ?array $callBack Callback function for additional formatting of string + * @param ?mixed[] $callBack Callback function for additional formatting of string + * @param bool $lessFloatPrecision If true, unstyled floats will be converted to a more human-friendly but less computationally accurate value * * @return string Formatted string */ - public static function toFormattedString(mixed $value, string $format, ?array $callBack = null): string + public static function toFormattedString(mixed $value, string $format, ?array $callBack = null, bool $lessFloatPrecision = false): string { - return NumberFormat\Formatter::toFormattedString($value, $format, $callBack); + return NumberFormat\Formatter::toFormattedString($value, $format, $callBack, $lessFloatPrecision); } + /** @return mixed[] */ protected function exportArray1(): array { $exportedArray = []; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php index 4b3d301..6630888 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php @@ -98,6 +98,7 @@ class DateFormatter '[ss]' => self::SECONDS_IN_DAY, ]; + /** @param float|int|numeric-string $value */ private static function tryInterval(bool &$seekingBracket, string &$block, mixed $value, string $format): void { if ($seekingBracket) { @@ -200,11 +201,13 @@ class DateFormatter return $dateObj->format($format); } + /** @param string[] $matches */ private static function setLowercaseCallback(array $matches): string { return mb_strtolower($matches[0]); } + /** @param string[] $matches */ private static function escapeQuotesCallback(array $matches): string { return '\\' . implode('\\', mb_str_split($matches[1], 1, 'UTF-8')); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Formatter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Formatter.php index bbc4677..82f2028 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Formatter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Formatter.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Reader\Xls\Color\BIFF8; use PhpOffice\PhpSpreadsheet\RichText\RichText; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\Color; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; @@ -43,7 +44,12 @@ class Formatter extends BaseFormatter }; } - /** @param float|int|numeric-string $value value to be formatted */ + /** + * @param float|int|numeric-string $value value to be formatted + * @param string[] $sections + * + * @return mixed[] + */ private static function splitFormatForSectionSelection(array $sections, mixed $value): array { // Extract the relevant section depending on whether number is positive, negative, or zero? @@ -109,14 +115,15 @@ class Formatter extends BaseFormatter /** * Convert a value in a pre-defined format to a PHP string. * - * @param null|array|bool|float|int|RichText|string $value Value to format + * @param null|array|bool|float|int|RichText|string $value Value to format * @param string $format Format code: see = self::FORMAT_* for predefined values; * or can be any valid MS Excel custom format string - * @param null|array|callable $callBack Callback function for additional formatting of string + * @param null|array|callable $callBack Callback function for additional formatting of string + * @param bool $lessFloatPrecision If true, unstyled floats will be converted to a more human-friendly but less computationally accurate value * * @return string Formatted string */ - public static function toFormattedString($value, string $format, null|array|callable $callBack = null): string + public static function toFormattedString($value, string $format, null|array|callable $callBack = null, bool $lessFloatPrecision = false): string { while (is_array($value)) { $value = array_shift($value); @@ -129,13 +136,13 @@ class Formatter extends BaseFormatter $formatx = str_replace('\"', self::QUOTE_REPLACEMENT, $format); if (preg_match(self::SECTION_SPLIT, $format) === 0 && preg_match(self::SYMBOL_AT, $formatx) === 1) { if (!str_contains($format, '"')) { - return str_replace('@', $value, $format); + return str_replace('@', StringHelper::convertToString($value, lessFloatPrecision: $lessFloatPrecision), $format); } //escape any dollar signs on the string, so they are not replaced with an empty value $value = str_replace( ['$', '"'], ['\$', self::QUOTE_REPLACEMENT], - (string) $value + StringHelper::convertToString($value, lessFloatPrecision: $lessFloatPrecision) ); return str_replace( @@ -147,13 +154,19 @@ class Formatter extends BaseFormatter // If we have a text value, return it "as is" if (!is_numeric($value)) { - return (string) $value; + return StringHelper::convertToString($value, lessFloatPrecision: $lessFloatPrecision); } // For 'General' format code, we just pass the value although this is not entirely the way Excel does it, // it seems to round numbers to a total of 10 digits. if (($format === NumberFormat::FORMAT_GENERAL) || ($format === NumberFormat::FORMAT_TEXT)) { - return self::adjustSeparators((string) $value); + if (is_float($value) && $lessFloatPrecision) { + return self::adjustSeparators((string) $value); + } + + return self::adjustSeparators( + StringHelper::convertToString($value, lessFloatPrecision: $lessFloatPrecision) + ); } // Ignore square-$-brackets prefix in format string, like "[$-411]ge.m.d", "[$-010419]0%", etc @@ -175,7 +188,9 @@ class Formatter extends BaseFormatter // In Excel formats, "_" is used to add spacing, // The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space - $format = (string) preg_replace('/_.?/ui', ' ', $format); + /** @var string */ + $temp = $format; + $format = (string) preg_replace('/_.?/ui', ' ', $temp); // Let's begin inspecting the format and converting the value to a formatted string if ( @@ -187,15 +202,21 @@ class Formatter extends BaseFormatter && (preg_match('/[0\?#]\.(?![^\[]*\])/miu', $format) === 0) ) { // datetime format - $value = DateFormatter::format($value, $format); + /** @var float|int */ + $temp = $value; + $value = DateFormatter::format($temp, $format); } else { if (str_starts_with($format, '"') && str_ends_with($format, '"') && substr_count($format, '"') === 2) { $value = substr($format, 1, -1); } elseif (preg_match('/[0#, ]%/', $format)) { // % number format - avoid weird '-0' problem - $value = PercentageFormatter::format(0 + (float) $value, $format); + /** @var float */ + $temp = $value; + $value = PercentageFormatter::format(0 + (float) $temp, $format); } else { - $value = NumberFormatter::format($value, $format); + /** @var float|int|numeric-string */ + $temp = $value; + $value = NumberFormatter::format($temp, $format); } } @@ -203,6 +224,7 @@ class Formatter extends BaseFormatter if (is_callable($callBack)) { $value = $callBack($value, $colors); } + /** @var string $value */ return str_replace(chr(0x00), '.', $value); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php index 0305700..7efcf21 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php @@ -9,6 +9,12 @@ class NumberFormatter extends BaseFormatter { private const NUMBER_REGEX = '/(0+)(\.?)(0*)/'; + /** + * @param string[] $numbers + * @param string[] $masks + * + * @return mixed[] + */ private static function mergeComplexNumberFormatMasks(array $numbers, array $masks): array { $decimalCount = strlen($numbers[1]); @@ -81,6 +87,7 @@ class NumberFormatter extends BaseFormatter if (count($masks) > 2) { $masks = self::mergeComplexNumberFormatMasks($numbers, $masks); } + /** @var string[] $masks */ $integerPart = self::complexNumberFormatMask($numbers[0], $masks[0], false); $numlen = strlen($numbers[1]); $msklen = strlen($masks[1]); @@ -132,6 +139,7 @@ class NumberFormatter extends BaseFormatter return $s; } + /** @param string[] $matches */ private static function formatStraightNumericValue(mixed $value, string $format, array $matches, bool $useThousands): string { /** @var float $valueFloat */ @@ -159,9 +167,10 @@ class NumberFormatter extends BaseFormatter $size = $decimals + 3; return sprintf("%{$size}.{$decimals}E", $valueFloat); - } elseif (preg_match('/0([^\d\.]+)0/', $format) || substr_count($format, '.') > 1) { + } + if (preg_match('/0([^\d\.]+)0/', $format) || substr_count($format, '.') > 1) { if ($valueFloat == floor($valueFloat) && substr_count($format, '.') === 1) { - $value *= 10 ** strlen(explode('.', $format)[1]); + $value *= 10 ** strlen(explode('.', $format)[1]); //* @phpstan-ignore-line } $result = self::complexNumberFormatMask($value, $format); @@ -255,6 +264,7 @@ class NumberFormatter extends BaseFormatter return (string) $value; } + /** @param mixed[]|string $value */ private static function makeString(array|string $value): string { return is_array($value) ? '' : "$value"; @@ -270,7 +280,7 @@ class NumberFormatter extends BaseFormatter $preDecimal = $postDecimal = ''; $pregArray = preg_split('/\.(?=(?:[^"]*"[^"]*")*[^"]*\Z)/miu', $baseFormat . '.?'); if (is_array($pregArray)) { - $preDecimal = $pregArray[0] ?? ''; + $preDecimal = $pregArray[0]; $postDecimal = $pregArray[1] ?? ''; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTime.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTime.php index c0fdeed..5f57a24 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTime.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTime.php @@ -22,7 +22,7 @@ class DateTime extends DateTimeWizard public function __construct($separators, ...$formatBlocks) { $this->separators = $this->padSeparatorArray( - is_array($separators) ? $separators : [$separators], + is_array($separators) ? $separators : [$separators], //* @phpstan-ignore-line count($formatBlocks) - 1 ); $this->formatBlocks = array_map([$this, 'mapFormatBlocks'], $formatBlocks); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTimeWizard.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTimeWizard.php index 8cd7da7..1fdb648 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTimeWizard.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/DateTimeWizard.php @@ -8,9 +8,14 @@ abstract class DateTimeWizard implements Stringable, Wizard { protected const NO_ESCAPING_NEEDED = "$+-/():!^&'~{}<>= "; + /** + * @param string[] $separators + * + * @return string[] + */ protected function padSeparatorArray(array $separators, int $count): array { - $lastSeparator = array_pop($separators); + $lastSeparator = (string) array_pop($separators); return $separators + array_fill(0, $count, $lastSeparator); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Locale.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Locale.php index 0c02286..06669d4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Locale.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Locale.php @@ -19,10 +19,6 @@ final class Locale public function __construct(?string $locale, int $style) { - if (class_exists(NumberFormatter::class) === false) { - throw new Exception(); - } - $formatterLocale = str_replace('-', '_', $locale ?? ''); $this->formatter = new NumberFormatter($formatterLocale, $style); if ($this->formatter->getLocale() !== $formatterLocale) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Protection.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Protection.php index 55a6526..256d0fe 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Protection.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Protection.php @@ -55,6 +55,10 @@ class Protection extends Supervisor /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return array{protection: mixed[]} */ public function getStyleArray(array $array): array { @@ -73,7 +77,7 @@ class Protection extends Supervisor * ); * * - * @param array $styleArray Array containing style information + * @param array{locked?: string, hidden?: string} $styleArray Array containing style information * * @return $this */ @@ -173,6 +177,7 @@ class Protection extends Supervisor ); } + /** @return mixed[] */ protected function exportArray1(): array { $exportedArray = []; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Style.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Style.php index 17d632e..feac1cb 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Style.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Style.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Chart\ChartColor; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; @@ -66,7 +67,7 @@ class Style extends Supervisor * @see Style::applyFromArray() * @see Style::getHashCode() * - * @var null|array + * @var null|array */ private static ?array $cachedStyles = null; @@ -131,6 +132,10 @@ class Style extends Supervisor /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return array{quotePrefix: mixed[]} */ public function getStyleArray(array $array): array { @@ -177,7 +182,7 @@ class Style extends Supervisor * ); * * - * @param array $styleArray Array containing style information + * @param mixed[] $styleArray Array containing style information * @param bool $advancedBorders advanced mode for setting borders * * @return $this @@ -226,6 +231,7 @@ class Style extends Supervisor if ($advancedBorders && isset($styleArray['borders'])) { // 'allBorders' is a shorthand property for 'outline' and 'inside' and // it applies to components that have not been set explicitly + /** @var mixed[][] $styleArray */ if (isset($styleArray['borders']['allBorders'])) { foreach (['outline', 'inside'] as $component) { if (!isset($styleArray['borders'][$component])) { @@ -312,10 +318,14 @@ class Style extends Supervisor switch ($innerEdge) { case 'top': case 'bottom': + /** @var mixed[][] $styleArray */ // should pick up 'horizontal' border property if set if (isset($styleArray['borders']['horizontal'])) { - $regionStyles['borders'][$innerEdge] = $styleArray['borders']['horizontal']; + /** @var mixed[][] $regionStyles */ + $regionStyles['borders'][$innerEdge] + = $styleArray['borders']['horizontal']; } else { + /** @var mixed[][] $regionStyles */ unset($regionStyles['borders'][$innerEdge]); } @@ -390,6 +400,7 @@ class Style extends Supervisor } // Find existing style by hash. + /** @var string $styleHash */ $existingStyle = self::$cachedStyles['styleByHash'][$styleHash] ?? null; if (!$existingStyle) { @@ -407,6 +418,7 @@ class Style extends Supervisor if ($existingStyle) { // there is already such cell Xf in our collection + /** @var Style $existingStyle */ $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex(); } else { if (!isset($newStyle)) { @@ -431,6 +443,7 @@ class Style extends Supervisor for ($col = $rangeStartIndexes[0]; $col <= $rangeEndIndexes[0]; ++$col) { $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col); $oldXfIndex = $columnDimension->getXfIndex(); + /** @var int[] $newXfIndexes */ $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]); } @@ -443,6 +456,7 @@ class Style extends Supervisor $rowDimension = $this->getActiveSheet()->getRowDimension($row); // row without explicit style should be formatted based on default style $oldXfIndex = $rowDimension->getXfIndex() ?? 0; + /** @var int[] $newXfIndexes */ $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]); } @@ -463,23 +477,38 @@ class Style extends Supervisor } } else { // not a supervisor, just apply the style array directly on style object + /** @var array{ + * alignment?: mixed[], + * fill?: array{fillType?: string, rotation?: float, startColor?: array{rgb?: string, argb?: string}, endColor?: array{rgb?: string, argb?: string}, color?: array{rgb?: string, argb?: string}}, + * font?: array{name?: string, latin?: string, eastAsian?: string, complexScript?: string, bold?: bool, italic?: bool, superscript?: bool, subscript?: bool, underline?: bool|string, strikethrough?: bool, color?: string[], size?: ?int, chartColor?: ChartColor, scheme?: string, cap?: string}, + * borders?: mixed[][], + * numberFormat?: string[], + * protection?: array{locked?: string, hidden?: string}, + * quotePrefix?: bool} $styleArray */ if (isset($styleArray['fill'])) { - $this->getFill()->applyFromArray($styleArray['fill']); + $this->getFill() + ->applyFromArray($styleArray['fill']); } if (isset($styleArray['font'])) { - $this->getFont()->applyFromArray($styleArray['font']); + $this->getFont() + ->applyFromArray($styleArray['font']); } if (isset($styleArray['borders'])) { - $this->getBorders()->applyFromArray($styleArray['borders']); + $this->getBorders() + ->applyFromArray($styleArray['borders']); } if (isset($styleArray['alignment'])) { - $this->getAlignment()->applyFromArray($styleArray['alignment']); + $temp = $styleArray['alignment']; + $this->getAlignment() + ->applyFromArray($temp); } if (isset($styleArray['numberFormat'])) { - $this->getNumberFormat()->applyFromArray($styleArray['numberFormat']); + $this->getNumberFormat() + ->applyFromArray($styleArray['numberFormat']); } if (isset($styleArray['protection'])) { - $this->getProtection()->applyFromArray($styleArray['protection']); + $this->getProtection() + ->applyFromArray($styleArray['protection']); } if (isset($styleArray['quotePrefix'])) { $this->quotePrefix = $styleArray['quotePrefix']; @@ -489,12 +518,20 @@ class Style extends Supervisor return $this; } + /** + * @param mixed[] $rangeStart + * @param mixed[] $rangeEnd + * @param mixed[] $styleArray + * + * @return mixed[] + */ private function getOldXfIndexes(string $selectionType, array $rangeStart, array $rangeEnd, string $columnStart, string $columnEnd, array $styleArray): array { $oldXfIndexes = []; switch ($selectionType) { case 'COLUMN': for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + /** @var int $col */ $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true; } foreach ($this->getActiveSheet()->getColumnIterator($columnStart, $columnEnd) as $columnIterator) { @@ -509,13 +546,18 @@ class Style extends Supervisor break; case 'ROW': for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + /** @var int $row */ if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() === null) { $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style } else { $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true; } } - foreach ($this->getActiveSheet()->getRowIterator((int) $rangeStart[1], (int) $rangeEnd[1]) as $rowIterator) { + /** @var float|int */ + $temp1 = $rangeStart[1]; + /** @var float|int */ + $temp2 = $rangeEnd[1]; + foreach ($this->getActiveSheet()->getRowIterator((int) $temp1, (int) $temp2) as $rowIterator) { $cellIterator = $rowIterator->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(true); foreach ($cellIterator as $rowCell) { @@ -527,7 +569,9 @@ class Style extends Supervisor break; case 'CELL': for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + /** @var int $col */ for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + /** @var int $row */ $oldXfIndexes[$this->getActiveSheet()->getCell([$col, $row])->getXfIndex()] = true; } } @@ -646,7 +690,9 @@ class Style extends Supervisor } if ($this->isSupervisor) { $styleArray = ['quotePrefix' => $quotePrefix]; - $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + $this->getActiveSheet() + ->getStyle($this->getSelectedCells()) + ->applyFromArray($styleArray); } else { $this->quotePrefix = (bool) $quotePrefix; } @@ -689,6 +735,7 @@ class Style extends Supervisor $this->index = $index; } + /** @return mixed[] */ protected function exportArray1(): array { $exportedArray = []; @@ -698,7 +745,7 @@ class Style extends Supervisor $this->exportArray2($exportedArray, 'font', $this->getFont()); $this->exportArray2($exportedArray, 'numberFormat', $this->getNumberFormat()); $this->exportArray2($exportedArray, 'protection', $this->getProtection()); - $this->exportArray2($exportedArray, 'quotePrefx', $this->getQuotePrefix()); + $this->exportArray2($exportedArray, 'quotePrefix', $this->getQuotePrefix()); return $exportedArray; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Supervisor.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Supervisor.php index 8388ef6..bbd940d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Supervisor.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Supervisor.php @@ -110,6 +110,8 @@ abstract class Supervisor implements IComparable * Available to anything which extends this class: * Alignment, Border, Borders, Color, Fill, Font, * NumberFormat, Protection, and Style. + * + * @return mixed[] */ final public function exportArray(): array { @@ -123,6 +125,8 @@ abstract class Supervisor implements IComparable * This method invokes exportArray2 with the names and values * of all properties to be included in output array, * returning that array to exportArray, then to caller. + * + * @return mixed[] */ abstract protected function exportArray1(): array; @@ -133,6 +137,8 @@ abstract class Supervisor implements IComparable * The parameter objOrValue is either a primitive type, * which is the value added to the array, * or a Style object to be recursively added via exportArray. + * + * @param mixed[] $exportedArray */ final protected function exportArray2(array &$exportedArray, string $index, mixed $objOrValue): void { @@ -151,6 +157,10 @@ abstract class Supervisor implements IComparable /** * Build style array from subcomponents. + * + * @param mixed[] $array + * + * @return mixed[] */ abstract public function getStyleArray(array $array): array; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Theme.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Theme.php index adeef80..757f902 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Theme.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Theme.php @@ -8,8 +8,9 @@ class Theme private string $themeFontName = 'Office'; - public const COLOR_SCHEME_2013_PLUS_NAME = 'Office 2013+'; - public const COLOR_SCHEME_2013_PLUS = [ + public const HYPERLINK_THEME = 10; + public const COLOR_SCHEME_2013_2022_NAME = 'Office 2013-2022'; + public const COLOR_SCHEME_2013_2022 = [ 'dk1' => '000000', 'lt1' => 'FFFFFF', 'dk2' => '44546A', @@ -23,6 +24,7 @@ class Theme 'hlink' => '0563C1', 'folHlink' => '954F72', ]; + private const COLOR_SCHEME_2013_PLUS_NAME = 'Office 2013+'; public const COLOR_SCHEME_2007_2010_NAME = 'Office 2007-2010'; public const COLOR_SCHEME_2007_2010 = [ @@ -40,6 +42,22 @@ class Theme 'folHlink' => '800080', ]; + public const COLOR_SCHEME_2023_PLUS_NAME = 'Office 2023+'; + public const COLOR_SCHEME_2023_PLUS = [ + 'dk1' => '000000', + 'lt1' => 'FFFFFF', + 'dk2' => '0E2841', + 'lt2' => 'E8E8E8', + 'accent1' => '156082', + 'accent2' => 'E97132', + 'accent3' => '196B24', + 'accent4' => '0F9ED5', + 'accent5' => 'A02B93', + 'accent6' => '4EA72E', + 'hlink' => '467886', + 'folHlink' => '96607D', + ]; + /** @var string[] */ private array $themeColors = self::COLOR_SCHEME_2007_2010; @@ -135,6 +153,7 @@ class Theme 'Geor' => 'Sylfaen', ]; + /** @return string[] */ public function getThemeColors(): array { return $this->themeColors; @@ -152,17 +171,35 @@ class Theme return $this->themeColorName; } - public function setThemeColorName(string $name, ?array $themeColors = null): self + /** @param null|string[] $themeColors */ + public function setThemeColorName(string $name, ?array $themeColors = null, ?Spreadsheet $spreadsheet = null): self { + if ($name === self::COLOR_SCHEME_2013_PLUS_NAME) { + // Ensure against this value being found in + // spreadsheets created while constant was public. + $name = self::COLOR_SCHEME_2013_2022_NAME; + } $this->themeColorName = $name; if ($name === self::COLOR_SCHEME_2007_2010_NAME) { $themeColors = $themeColors ?? self::COLOR_SCHEME_2007_2010; - } elseif ($name === self::COLOR_SCHEME_2013_PLUS_NAME) { - $themeColors = $themeColors ?? self::COLOR_SCHEME_2013_PLUS; + $this->majorFontLatin = 'Cambria'; + $this->minorFontLatin = 'Calibri'; + } elseif ($name === self::COLOR_SCHEME_2013_2022_NAME) { + $themeColors = $themeColors ?? self::COLOR_SCHEME_2013_2022; + $this->majorFontLatin = 'Calibri Light'; + $this->minorFontLatin = 'Calibri'; + } elseif ($name === self::COLOR_SCHEME_2023_PLUS_NAME) { + $themeColors = $themeColors ?? self::COLOR_SCHEME_2023_PLUS; + $this->majorFontLatin = 'Aptos Display'; + $this->minorFontLatin = 'Aptos Narrow'; } if ($themeColors !== null) { $this->themeColors = $themeColors; } + if ($spreadsheet !== null) { + $spreadsheet->getDefaultStyle()->getFont() + ->applyThemeFonts($this); + } return $this; } @@ -182,11 +219,13 @@ class Theme return $this->majorFontComplexScript; } + /** @return string[] */ public function getMajorFontSubstitutions(): array { return $this->majorFontSubstitutions; } + /** @param null|string[] $substitutions */ public function setMajorFontValues(?string $latin, ?string $eastAsian, ?string $complexScript, ?array $substitutions): self { if (!empty($latin)) { @@ -220,11 +259,13 @@ class Theme return $this->minorFontComplexScript; } + /** @return string[] */ public function getMinorFontSubstitutions(): array { return $this->minorFontSubstitutions; } + /** @param null|string[] $substitutions */ public function setMinorFontValues(?string $latin, ?string $eastAsian, ?string $complexScript, ?array $substitutions): self { if (!empty($latin)) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php index 73a2ea6..9074288 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php @@ -368,11 +368,10 @@ class AutoFilter implements Stringable /** * Test if cell value is within a set of values defined by a ruleset. * - * @param mixed[] $ruleSet + * @param mixed[][] $ruleSet */ protected static function filterTestInCustomDataSet(mixed $cellValue, array $ruleSet): bool { - /** @var array[] $dataSet */ $dataSet = $ruleSet['filterRules']; $join = $ruleSet['join']; $customRuleForBlanks = $ruleSet['customRuleForBlanks'] ?? false; @@ -385,11 +384,10 @@ class AutoFilter implements Stringable } $returnVal = ($join == AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND); foreach ($dataSet as $rule) { - /** @var string $ruleValue */ + /** @var string[] $rule */ $ruleValue = $rule['value']; - /** @var string $ruleOperator */ $ruleOperator = $rule['operator']; - /** @var string $cellValueString */ + /** @var string */ $cellValueString = $cellValue ?? ''; $retVal = false; @@ -529,6 +527,7 @@ class AutoFilter implements Stringable Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY => 'dynamicYesterday', ]; + /** @return array{DateTime, DateTime} */ private static function dynamicLastMonth(): array { $maxval = new DateTime(); @@ -554,6 +553,7 @@ class AutoFilter implements Stringable return $val; } + /** @return array{DateTime, DateTime} */ private static function dynamicLastQuarter(): array { $maxval = self::firstDayOfQuarter(); @@ -563,6 +563,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicLastWeek(): array { $val = new DateTime(); @@ -576,6 +577,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicLastYear(): array { $val = new DateTime(); @@ -586,6 +588,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicNextMonth(): array { $val = new DateTime(); @@ -600,6 +603,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicNextQuarter(): array { $val = self::firstDayOfQuarter(); @@ -610,6 +614,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicNextWeek(): array { $val = new DateTime(); @@ -623,6 +628,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicNextYear(): array { $val = new DateTime(); @@ -633,6 +639,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicThisMonth(): array { $baseDate = new DateTime(); @@ -646,6 +653,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicThisQuarter(): array { $val = self::firstDayOfQuarter(); @@ -655,6 +663,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicThisWeek(): array { $val = new DateTime(); @@ -668,6 +677,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicThisYear(): array { $val = new DateTime(); @@ -678,6 +688,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicToday(): array { $val = new DateTime(); @@ -688,6 +699,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicTomorrow(): array { $val = new DateTime(); @@ -699,6 +711,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicYearToDate(): array { $maxval = new DateTime(); @@ -709,6 +722,7 @@ class AutoFilter implements Stringable return [$val, $maxval]; } + /** @return array{DateTime, DateTime} */ private static function dynamicYesterday(): array { $maxval = new DateTime(); @@ -941,6 +955,7 @@ class AutoFilter implements Stringable if ($periodType == 'M') { $ruleValues = [$period]; } else { + /** @var int $period */ --$period; $periodEnd = (1 + $period) * 3; $periodStart = 1 + $period * 3; @@ -1071,7 +1086,7 @@ class AutoFilter implements Stringable // The columns array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter objects $this->{$key} = []; foreach ($value as $k => $v) { - $this->{$key}[$k] = clone $v; + $this->{$key}[$k] = clone $v; //* @phpstan-ignore-line // attach the new cloned Column to this new cloned Autofilter object $this->{$key}[$k]->setParent($this); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php index 1ee2eff..441204c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php @@ -274,7 +274,8 @@ class Rule throw new PhpSpreadsheetException('Invalid rule value for column AutoFilter Rule.'); } // Set the dateTime grouping that we've anticipated - $this->setGrouping(self::DATE_TIME_GROUPS[$grouping]); + // I have no idea what Phpstan is complaining about below + $this->setGrouping(self::DATE_TIME_GROUPS[$grouping]); // @phpstan-ignore-line } $this->value = $value; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFit.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFit.php index 859a70f..b4bd1b1 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFit.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFit.php @@ -15,13 +15,13 @@ class AutoFit $this->worksheet = $worksheet; } + /** @return mixed[] */ public function getAutoFilterIndentRanges(): array { $autoFilterIndentRanges = []; $autoFilterIndentRanges[] = $this->getAutoFilterIndentRange($this->worksheet->getAutoFilter()); foreach ($this->worksheet->getTableCollection() as $table) { - /** @var Table $table */ if ($table->getShowHeaderRow() === true && $table->getAllowFilter() === true) { $autoFilter = $table->getAutoFilter(); $autoFilterIndentRanges[] = $this->getAutoFilterIndentRange($autoFilter); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php index 135f5b2..faa836c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php @@ -422,7 +422,7 @@ class BaseDrawing implements IComparable return md5( $this->name . $this->description - . (($this->worksheet === null) ? '' : (string) $this->worksheet->getHashInt()) + . (($this->worksheet === null) ? '' : (string) spl_object_id($this->worksheet)) . $this->coordinates . $this->offsetX . $this->offsetY diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnDimension.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnDimension.php index 8ac405b..9553119 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnDimension.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ColumnDimension.php @@ -7,6 +7,8 @@ use PhpOffice\PhpSpreadsheet\Helper\Dimension as CssDimension; class ColumnDimension extends Dimension { + public const EXCEL_MAX_WIDTH = 255.0; + /** * Column index. */ @@ -89,6 +91,11 @@ class ColumnDimension extends Dimension : (new CssDimension((string) $this->width))->toUnit($unitOfMeasure); } + public function getWidthForOutput(bool $restrictMax): float + { + return ($restrictMax && $this->width > self::EXCEL_MAX_WIDTH) ? self::EXCEL_MAX_WIDTH : $this->width; + } + /** * Set Width. * diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Drawing.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Drawing.php index 5f2e745..2133514 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Drawing.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Drawing.php @@ -92,7 +92,7 @@ class Drawing extends BaseDrawing * * @return $this */ - public function setPath(string $path, bool $verifyFile = true, ?ZipArchive $zip = null): static + public function setPath(string $path, bool $verifyFile = true, ?ZipArchive $zip = null, bool $allowExternal = true): static { $this->isUrl = false; if (preg_match('~^data:image/[a-z]+;base64,~', $path) === 1) { @@ -107,6 +107,9 @@ class Drawing extends BaseDrawing if (!preg_match('/^(http|https|file|ftp|s3):/', $path)) { throw new PhpSpreadsheetException('Invalid protocol for linked drawing'); } + if (!$allowExternal) { + return $this; + } // Implicit that it is a URL, rather store info than running check above on value in other places. $this->isUrl = true; $ctx = null; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/HeaderFooter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/HeaderFooter.php index 68716c0..787b00f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/HeaderFooter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/HeaderFooter.php @@ -67,11 +67,29 @@ class HeaderFooter { // Header/footer image location const IMAGE_HEADER_LEFT = 'LH'; + const IMAGE_HEADER_LEFT_ODD = 'LH'; + const IMAGE_HEADER_LEFT_FIRST = 'LHFIRST'; + const IMAGE_HEADER_LEFT_EVEN = 'LHEVEN'; const IMAGE_HEADER_CENTER = 'CH'; + const IMAGE_HEADER_CENTER_ODD = 'CH'; + const IMAGE_HEADER_CENTER_FIRST = 'CHFIRST'; + const IMAGE_HEADER_CENTER_EVEN = 'CHEVEN'; const IMAGE_HEADER_RIGHT = 'RH'; + const IMAGE_HEADER_RIGHT_ODD = 'RH'; + const IMAGE_HEADER_RIGHT_FIRST = 'RHFIRST'; + const IMAGE_HEADER_RIGHT_EVEN = 'RHEVEN'; const IMAGE_FOOTER_LEFT = 'LF'; + const IMAGE_FOOTER_LEFT_ODD = 'LF'; + const IMAGE_FOOTER_LEFT_FIRST = 'LFFIRST'; + const IMAGE_FOOTER_LEFT_EVEN = 'LFEVEN'; const IMAGE_FOOTER_CENTER = 'CF'; + const IMAGE_FOOTER_CENTER_ODD = 'CF'; + const IMAGE_FOOTER_CENTER_FIRST = 'CFFIRST'; + const IMAGE_FOOTER_CENTER_EVEN = 'CFEVEN'; const IMAGE_FOOTER_RIGHT = 'RF'; + const IMAGE_FOOTER_RIGHT_ODD = 'RF'; + const IMAGE_FOOTER_RIGHT_FIRST = 'RFFIRST'; + const IMAGE_FOOTER_RIGHT_EVEN = 'RFEVEN'; /** * OddHeader. @@ -377,6 +395,27 @@ class HeaderFooter return $this; } + private const IMAGE_SORT_ORDER = [ + self::IMAGE_HEADER_LEFT, + self::IMAGE_HEADER_LEFT_FIRST, + self::IMAGE_HEADER_LEFT_EVEN, + self::IMAGE_HEADER_CENTER, + self::IMAGE_HEADER_CENTER_FIRST, + self::IMAGE_HEADER_CENTER_EVEN, + self::IMAGE_HEADER_RIGHT, + self::IMAGE_HEADER_RIGHT_FIRST, + self::IMAGE_HEADER_RIGHT_EVEN, + self::IMAGE_FOOTER_LEFT, + self::IMAGE_FOOTER_LEFT_FIRST, + self::IMAGE_FOOTER_LEFT_EVEN, + self::IMAGE_FOOTER_CENTER, + self::IMAGE_FOOTER_CENTER_FIRST, + self::IMAGE_FOOTER_CENTER_EVEN, + self::IMAGE_FOOTER_RIGHT, + self::IMAGE_FOOTER_RIGHT_FIRST, + self::IMAGE_FOOTER_RIGHT_EVEN, + ]; + /** * Get header/footer images. * @@ -384,25 +423,12 @@ class HeaderFooter */ public function getImages(): array { - // Sort array + // Sort array - not sure why needed $images = []; - if (isset($this->headerFooterImages[self::IMAGE_HEADER_LEFT])) { - $images[self::IMAGE_HEADER_LEFT] = $this->headerFooterImages[self::IMAGE_HEADER_LEFT]; - } - if (isset($this->headerFooterImages[self::IMAGE_HEADER_CENTER])) { - $images[self::IMAGE_HEADER_CENTER] = $this->headerFooterImages[self::IMAGE_HEADER_CENTER]; - } - if (isset($this->headerFooterImages[self::IMAGE_HEADER_RIGHT])) { - $images[self::IMAGE_HEADER_RIGHT] = $this->headerFooterImages[self::IMAGE_HEADER_RIGHT]; - } - if (isset($this->headerFooterImages[self::IMAGE_FOOTER_LEFT])) { - $images[self::IMAGE_FOOTER_LEFT] = $this->headerFooterImages[self::IMAGE_FOOTER_LEFT]; - } - if (isset($this->headerFooterImages[self::IMAGE_FOOTER_CENTER])) { - $images[self::IMAGE_FOOTER_CENTER] = $this->headerFooterImages[self::IMAGE_FOOTER_CENTER]; - } - if (isset($this->headerFooterImages[self::IMAGE_FOOTER_RIGHT])) { - $images[self::IMAGE_FOOTER_RIGHT] = $this->headerFooterImages[self::IMAGE_FOOTER_RIGHT]; + foreach (self::IMAGE_SORT_ORDER as $key) { + if (isset($this->headerFooterImages[$key])) { + $images[$key] = $this->headerFooterImages[$key]; + } } $this->headerFooterImages = $images; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php index 26bdc59..dfef51d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php @@ -64,10 +64,7 @@ class MemoryDrawing extends BaseDrawing public function __destruct() { - if ($this->imageResource) { - @imagedestroy($this->imageResource); - $this->imageResource = null; - } + $this->imageResource = null; $this->worksheet = null; } @@ -130,9 +127,6 @@ class MemoryDrawing extends BaseDrawing public static function fromStream($imageStream): self { $streamValue = stream_get_contents($imageStream); - if ($streamValue === false) { - throw new Exception('Unable to read data from stream'); - } return self::fromString($streamValue); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php index f8c2dd1..4c6a539 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php @@ -208,14 +208,14 @@ class PageSetup /** * Columns to repeat at left. * - * @var array Containing start column and end column, empty array if option unset + * @var array{string, string} Containing start column and end column, empty array if option unset */ private array $columnsToRepeatAtLeft = ['', '']; /** * Rows to repeat at top. * - * @var array Containing start row number and end row number, empty array if option unset + * @var int[] Containing start row number and end row number, empty array if option unset */ private array $rowsToRepeatAtTop = [0, 0]; @@ -443,7 +443,7 @@ class PageSetup /** * Get Columns to repeat at left. * - * @return array Containing start column and end column, empty array if option unset + * @return array{string, string} Containing start column and end column, empty array if option unset */ public function getColumnsToRepeatAtLeft(): array { @@ -453,7 +453,7 @@ class PageSetup /** * Set Columns to repeat at left. * - * @param array $columnsToRepeatAtLeft Containing start column and end column, empty array if option unset + * @param array{string, string} $columnsToRepeatAtLeft Containing start column and end column, empty array if option unset * * @return $this */ @@ -496,7 +496,7 @@ class PageSetup /** * Get Rows to repeat at top. * - * @return array Containing start column and end column, empty array if option unset + * @return int[] Containing start column and end column, empty array if option unset */ public function getRowsToRepeatAtTop(): array { @@ -506,7 +506,7 @@ class PageSetup /** * Set Rows to repeat at top. * - * @param array $rowsToRepeatAtTop Containing start column and end column, empty array if option unset + * @param int[] $rowsToRepeatAtTop Containing start column and end column, empty array if option unset * * @return $this */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ProtectedRange.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ProtectedRange.php index bd41976..13c0d50 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ProtectedRange.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/ProtectedRange.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheet\Worksheet; +use PhpOffice\PhpSpreadsheet\Cell\Coordinate; + class ProtectedRange { private string $name = ''; @@ -42,4 +44,16 @@ class ProtectedRange { return $this->securityDescriptor; } + + /** + * Split range into coordinate strings. + * + * @return array> Array containing one or more arrays containing one or two coordinate strings + * e.g. ['B4','D9'] or [['B4','D9'], ['H2','O11']] + * or ['B4'] + */ + public function allRanges(): array + { + return Coordinate::allRanges($this->sqref, false); + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowDimension.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowDimension.php index e94a63b..1242358 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowDimension.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowDimension.php @@ -6,9 +6,6 @@ use PhpOffice\PhpSpreadsheet\Helper\Dimension as CssDimension; class RowDimension extends Dimension { - /** - * Row index. - */ private ?int $rowIndex; /** @@ -23,9 +20,9 @@ class RowDimension extends Dimension */ private bool $zeroHeight = false; + private bool $customFormat = false; + /** - * Create a new RowDimension. - * * @param ?int $index Numeric row index */ public function __construct(?int $index = 0) @@ -37,19 +34,11 @@ class RowDimension extends Dimension parent::__construct(null); } - /** - * Get Row Index. - */ public function getRowIndex(): ?int { return $this->rowIndex; } - /** - * Set Row Index. - * - * @return $this - */ public function setRowIndex(int $index): static { $this->rowIndex = $index; @@ -76,35 +65,41 @@ class RowDimension extends Dimension * @param float $height in points. A value of -1 tells Excel to display this column in its default height. * By default, this will be the passed argument value; but this method also accepts an optional unit of measure * argument, and will convert the passed argument value to points from the specified UoM - * - * @return $this */ public function setRowHeight(float $height, ?string $unitOfMeasure = null): static { $this->height = ($unitOfMeasure === null || $height < 0) ? $height : (new CssDimension("{$height}{$unitOfMeasure}"))->height(); + $this->customFormat = false; return $this; } - /** - * Get ZeroHeight. - */ public function getZeroHeight(): bool { return $this->zeroHeight; } - /** - * Set ZeroHeight. - * - * @return $this - */ public function setZeroHeight(bool $zeroHeight): static { $this->zeroHeight = $zeroHeight; return $this; } + + public function getCustomFormat(): bool + { + return $this->customFormat; + } + + public function setCustomFormat(bool $customFormat, ?float $height = -1): self + { + $this->customFormat = $customFormat; + if ($height !== null) { + $this->height = $height; + } + + return $this; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Table.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Table.php index 18a2ced..072beab 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Table.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Table.php @@ -540,6 +540,19 @@ class Table implements Stringable return $this; } + /** + * Get the row number on this table for given coordinates. + */ + public function getRowNumber(string $coordinate): int + { + $range = $this->getRange(); + $coords = Coordinate::splitRange($range); + $firstCell = Coordinate::coordinateFromString($coords[0][0]); + $thisCell = Coordinate::coordinateFromString($coordinate); + + return (int) $thisCell[1] - (int) $firstCell[1]; + } + /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ @@ -558,6 +571,7 @@ class Table implements Stringable // The columns array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\Table objects $this->{$key} = []; foreach ($value as $k => $v) { + /** @var Table\Column $v */ $this->{$key}[$k] = clone $v; // attach the new cloned Column to this new cloned Table object $this->{$key}[$k]->setTable($this); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Table/TableStyle.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Table/TableStyle.php index 8115302..bb92e1b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Table/TableStyle.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Table/TableStyle.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Worksheet\Table; +use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Table; class TableStyle @@ -93,6 +94,11 @@ class TableStyle */ private bool $showColumnStripes = false; + /** + * TableDxfsStyle. + */ + private ?TableDxfsStyle $tableStyle = null; + /** * Table. */ @@ -198,6 +204,36 @@ class TableStyle return $this; } + /** + * Get this Style's Dxfs TableStyle. + */ + public function getTableDxfsStyle(): ?TableDxfsStyle + { + return $this->tableStyle; + } + + /** + * Set this Style's Dxfs TableStyle. + * + * @param Style[] $dxfs + */ + public function setTableDxfsStyle(TableDxfsStyle $tableStyle, array $dxfs): self + { + $this->tableStyle = $tableStyle; + + if ($this->tableStyle->getHeaderRow() !== null && isset($dxfs[$this->tableStyle->getHeaderRow()])) { + $this->tableStyle->setHeaderRowStyle($dxfs[$this->tableStyle->getHeaderRow()]); + } + if ($this->tableStyle->getFirstRowStripe() !== null && isset($dxfs[$this->tableStyle->getFirstRowStripe()])) { + $this->tableStyle->setFirstRowStripeStyle($dxfs[$this->tableStyle->getFirstRowStripe()]); + } + if ($this->tableStyle->getSecondRowStripe() !== null && isset($dxfs[$this->tableStyle->getSecondRowStripe()])) { + $this->tableStyle->setSecondRowStripeStyle($dxfs[$this->tableStyle->getSecondRowStripe()]); + } + + return $this; + } + /** * Get this Style's Table. */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php index 6f6c5cf..64c4ec2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Worksheet; use ArrayObject; +use Composer\Pcre\Preg; use Generator; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; @@ -158,6 +159,8 @@ class Worksheet /** * Conditional styles. Indexed by cell coordinate, e.g. 'A1'. + * + * @var Conditional[][] */ private array $conditionalStylesCollection = []; @@ -285,12 +288,16 @@ class Worksheet /** * Hyperlinks. Indexed by cell coordinate, e.g. 'A1'. + * + * @var Hyperlink[] */ private array $hyperlinkCollection = []; /** * Data validation objects. Indexed by cell coordinate, e.g. 'A1'. * Index can include ranges, and multiple cells/ranges. + * + * @var DataValidation[] */ private array $dataValidationCollection = []; @@ -299,11 +306,6 @@ class Worksheet */ private ?Color $tabColor = null; - /** - * Hash. - */ - private int $hash; - /** * CodeName. */ @@ -316,7 +318,6 @@ class Worksheet { // Set parent and title $this->parent = $parent; - $this->hash = spl_object_id($this); $this->setTitle($title, false); // setTitle can change $pTitle $this->setCodeName($this->getTitle()); @@ -353,7 +354,7 @@ class Worksheet */ public function disconnectCells(): void { - if (isset($this->cellCollection)) { + if (isset($this->cellCollection)) { //* @phpstan-ignore-line $this->cellCollection->unsetWorksheetCells(); unset($this->cellCollection); } @@ -366,17 +367,13 @@ class Worksheet */ public function __destruct() { - Calculation::getInstance($this->parent)->clearCalculationCacheForWorksheet($this->title); + Calculation::getInstanceOrNull($this->parent) + ?->clearCalculationCacheForWorksheet($this->title); $this->disconnectCells(); unset($this->rowDimensions, $this->columnDimensions, $this->tableCollection, $this->drawingCollection, $this->chartCollection, $this->autoFilter); } - public function __wakeup(): void - { - $this->hash = spl_object_id($this); - } - /** * Return the cell collection. */ @@ -387,6 +384,8 @@ class Worksheet /** * Get array of invalid characters for sheet title. + * + * @return string[] */ public static function getInvalidCharacters(): array { @@ -454,7 +453,7 @@ class Worksheet */ public function getCoordinates(bool $sorted = true): array { - if (!isset($this->cellCollection)) { + if (!isset($this->cellCollection)) { //* @phpstan-ignore-line return []; } @@ -727,6 +726,7 @@ class Worksheet $filterAdjustment = false; if (!empty($autoFilterIndentRanges)) { foreach ($autoFilterIndentRanges as $autoFilterFirstRowRange) { + /** @var string $autoFilterFirstRowRange */ if ($cell->isInRange($autoFilterFirstRowRange)) { $filterAdjustment = true; @@ -899,7 +899,7 @@ class Worksheet // Set title $this->title = $title; - if ($this->parent && $this->parent->getIndex($this, true) >= 0 && $this->parent->getCalculationEngine()) { + if ($this->parent && $this->parent->getIndex($this, true) >= 0) { // New title $newTitle = $this->getTitle(); $this->parent->getCalculationEngine() @@ -1099,7 +1099,7 @@ class Worksheet /** * Get highest worksheet column and highest row that have cell records. * - * @return array Highest column name and highest row number + * @return array{row: int, column: string} Highest column name and highest row number */ public function getHighestRowAndColumn(): array { @@ -1203,8 +1203,8 @@ class Worksheet throw new Exception('Sheet not found for name: ' . $worksheetReference[0]); } } elseif ( - !preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $coordinate) - && preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/iu', $coordinate) + !Preg::isMatch('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $coordinate) + && Preg::isMatch('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/iu', $coordinate) ) { // Named range? $namedRange = $this->validateNamedRange($coordinate, true); @@ -1414,6 +1414,34 @@ class Worksheet return $this->getParentOrThrow()->getCellXfSupervisor(); } + /** + * Get table styles set for the for given cell. + * + * @param Cell $cell + * The Cell for which the tables are retrieved + * + * @return mixed[] + */ + public function getTablesWithStylesForCell(Cell $cell): array + { + $retVal = []; + + foreach ($this->tableCollection as $table) { + /** @var Table $table */ + $dxfsTableStyle = $table->getStyle()->getTableDxfsStyle(); + if ($dxfsTableStyle !== null) { + if ($dxfsTableStyle->getHeaderRowStyle() !== null || $dxfsTableStyle->getFirstRowStripeStyle() !== null || $dxfsTableStyle->getSecondRowStripeStyle() !== null) { + $range = $table->getRange(); + if ($cell->isInRange($range)) { + $retVal[] = $table; + } + } + } + } + + return $retVal; + } + /** * Get conditional styles for a cell. * @@ -1430,7 +1458,7 @@ class Worksheet public function getConditionalStyles(string $coordinate, bool $firstOnly = true): array { $coordinate = strtoupper($coordinate); - if (preg_match('/[: ,]/', $coordinate) === 1) { + if (Preg::isMatch('/[: ,]/', $coordinate)) { return $this->conditionalStylesCollection[$coordinate] ?? []; } @@ -1532,6 +1560,8 @@ class Worksheet /** * Get collection of conditional styles. + * + * @return Conditional[][] */ public function getConditionalStylesCollection(): array { @@ -1748,7 +1778,7 @@ class Worksheet $range .= ":{$range}"; } - if (preg_match('/^([A-Z]+)(\d+):([A-Z]+)(\d+)$/', $range, $matches) !== 1) { + if (!Preg::isMatch('/^([A-Z]+)(\d+):([A-Z]+)(\d+)$/', $range, $matches)) { throw new Exception('Merge must be on a valid range of cells.'); } @@ -1831,6 +1861,11 @@ class Worksheet } } + /** + * @param mixed[] $leftCellValue + * + * @return mixed[] + */ public function mergeCellBehaviour(Cell $cell, string $upperLeft, string $behaviour, array $leftCellValue): array { if ($cell->getCoordinate() !== $upperLeft) { @@ -2362,6 +2397,42 @@ class Worksheet if ($row < 1) { throw new Exception('Rows to be deleted should at least start from row 1.'); } + $startRow = $row; + $endRow = $startRow + $numberOfRows - 1; + $removeKeys = []; + $addKeys = []; + foreach ($this->mergeCells as $key => $value) { + if ( + Preg::isMatch( + '/^([a-z]{1,3})(\d+):([a-z]{1,3})(\d+)/i', + $key, + $matches + ) + ) { + $startMergeInt = (int) $matches[2]; + $endMergeInt = (int) $matches[4]; + if ($startMergeInt >= $startRow) { + if ($startMergeInt <= $endRow) { + $removeKeys[] = $key; + } + } elseif ($endMergeInt >= $startRow) { + if ($endMergeInt <= $endRow) { + $temp = $endMergeInt - 1; + $removeKeys[] = $key; + if ($temp !== $startMergeInt) { + $temp3 = $matches[1] . $matches[2] . ':' . $matches[3] . $temp; + $addKeys[] = $temp3; + } + } + } + } + } + foreach ($removeKeys as $key) { + unset($this->mergeCells[$key]); + } + foreach ($addKeys as $key) { + $this->mergeCells[$key] = $key; + } $holdRowDimensions = $this->removeRowDimensions($row, $numberOfRows); $highestRow = $this->getHighestDataRow(); @@ -2386,6 +2457,7 @@ class Worksheet return $this; } + /** @return RowDimension[] */ private function removeRowDimensions(int $row, int $numberOfRows): array { $highRow = $row + $numberOfRows - 1; @@ -2418,6 +2490,43 @@ class Worksheet if (is_numeric($column)) { throw new Exception('Column references should not be numeric.'); } + $startColumnInt = Coordinate::columnIndexFromString($column); + $endColumnInt = $startColumnInt + $numberOfColumns - 1; + $removeKeys = []; + $addKeys = []; + foreach ($this->mergeCells as $key => $value) { + if ( + Preg::isMatch( + '/^([a-z]{1,3})(\d+):([a-z]{1,3})(\d+)/i', + $key, + $matches + ) + ) { + $startMergeInt = Coordinate::columnIndexFromString($matches[1]); + $endMergeInt = Coordinate::columnIndexFromString($matches[3]); + if ($startMergeInt >= $startColumnInt) { + if ($startMergeInt <= $endColumnInt) { + $removeKeys[] = $key; + } + } elseif ($endMergeInt >= $startColumnInt) { + if ($endMergeInt <= $endColumnInt) { + $temp = Coordinate::columnIndexFromString($matches[3]) - 1; + $temp2 = Coordinate::stringFromColumnIndex($temp); + $removeKeys[] = $key; + if ($temp2 !== $matches[1]) { + $temp3 = $matches[1] . $matches[2] . ':' . $temp2 . $matches[4]; + $addKeys[] = $temp3; + } + } + } + } + } + foreach ($removeKeys as $key) { + unset($this->mergeCells[$key]); + } + foreach ($addKeys as $key) { + $this->mergeCells[$key] = $key; + } $highestColumn = $this->getHighestDataColumn(); $highestColumnIndex = Coordinate::columnIndexFromString($highestColumn); @@ -2447,6 +2556,7 @@ class Worksheet return $this; } + /** @return ColumnDimension[] */ private function removeColumnDimensions(int $pColumnIndex, int $numberOfColumns): array { $highCol = $pColumnIndex + $numberOfColumns - 1; @@ -2779,7 +2889,7 @@ class Worksheet /** * Fill worksheet from values in array. * - * @param array $source Source array + * @param mixed[]|mixed[][] $source Source array * @param mixed $nullValue Value in source array that stands for blank cell * @param string $startCell Insert array starting from this cell address as the top left coordinate * @param bool $strictNullComparison Apply strict comparison when testing for null values in the array @@ -2792,20 +2902,22 @@ class Worksheet if (!is_array(end($source))) { $source = [$source]; } + /** @var mixed[][] $source */ // start coordinate [$startColumn, $startRow] = Coordinate::coordinateFromString($startCell); + $startRow = (int) $startRow; // Loop through $source if ($strictNullComparison) { foreach ($source as $rowData) { + /** @var string */ $currentColumn = $startColumn; foreach ($rowData as $cellValue) { if ($cellValue !== $nullValue) { - // Set cell value $this->getCell($currentColumn . $startRow)->setValue($cellValue); } - ++$currentColumn; + StringHelper::stringIncrement($currentColumn); } ++$startRow; } @@ -2814,10 +2926,9 @@ class Worksheet $currentColumn = $startColumn; foreach ($rowData as $cellValue) { if ($cellValue != $nullValue) { - // Set cell value $this->getCell($currentColumn . $startRow)->setValue($cellValue); } - ++$currentColumn; + StringHelper::stringIncrement($currentColumn); } ++$startRow; } @@ -2827,12 +2938,15 @@ class Worksheet } /** + * @param bool $calculateFormulas Whether to calculate cell's value if it is a formula. * @param null|bool|float|int|RichText|string $nullValue value to use when null + * @param bool $formatData Whether to format data according to cell's style. + * @param bool $lessFloatPrecision If true, formatting unstyled floats will convert them to a more human-friendly but less computationally accurate value * * @throws Exception * @throws \PhpOffice\PhpSpreadsheet\Calculation\Exception */ - protected function cellToArray(Cell $cell, bool $calculateFormulas, bool $formatData, mixed $nullValue): mixed + protected function cellToArray(Cell $cell, bool $calculateFormulas, bool $formatData, mixed $nullValue, bool $lessFloatPrecision = false): mixed { $returnValue = $nullValue; @@ -2849,7 +2963,8 @@ class Worksheet $returnValuex = $returnValue; $returnValue = NumberFormat::toFormattedString( $returnValuex, - $style->getNumberFormat()->getFormatCode() ?? NumberFormat::FORMAT_GENERAL + $style->getNumberFormat()->getFormatCode() ?? NumberFormat::FORMAT_GENERAL, + lessFloatPrecision: $lessFloatPrecision ); } } @@ -2867,6 +2982,10 @@ class Worksheet * True - Return rows and columns indexed by their actual row and column IDs * @param bool $ignoreHidden False - Return values for rows/columns even if they are defined as hidden. * True - Don't return values for rows/columns that are defined as hidden. + * @param bool $reduceArrays If true and result is a formula which evaluates to an array, reduce it to the top leftmost value. + * @param bool $lessFloatPrecision If true, formatting unstyled floats will convert them to a more human-friendly but less computationally accurate value + * + * @return mixed[][] */ public function rangeToArray( string $range, @@ -2875,12 +2994,14 @@ class Worksheet bool $formatData = true, bool $returnCellRef = false, bool $ignoreHidden = false, - bool $reduceArrays = false + bool $reduceArrays = false, + bool $lessFloatPrecision = false ): array { $returnValue = []; // Loop through rows - foreach ($this->rangeToArrayYieldRows($range, $nullValue, $calculateFormulas, $formatData, $returnCellRef, $ignoreHidden, $reduceArrays) as $rowRef => $rowArray) { + foreach ($this->rangeToArrayYieldRows($range, $nullValue, $calculateFormulas, $formatData, $returnCellRef, $ignoreHidden, $reduceArrays, $lessFloatPrecision) as $rowRef => $rowArray) { + /** @var int $rowRef */ $returnValue[$rowRef] = $rowArray; } @@ -2888,6 +3009,46 @@ class Worksheet return $returnValue; } + /** + * Create array from a multiple ranges of cells. (such as A1:A3,A15,B17:C17). + * + * @param null|bool|float|int|RichText|string $nullValue Value returned in the array entry if a cell doesn't exist + * @param bool $calculateFormulas Should formulas be calculated? + * @param bool $formatData Should formatting be applied to cell values? + * @param bool $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @param bool $ignoreHidden False - Return values for rows/columns even if they are defined as hidden. + * True - Don't return values for rows/columns that are defined as hidden. + * @param bool $reduceArrays If true and result is a formula which evaluates to an array, reduce it to the top leftmost value. + * @param bool $lessFloatPrecision If true, formatting unstyled floats will convert them to a more human-friendly but less computationally accurate value + * + * @return mixed[][] + */ + public function rangesToArray( + string $ranges, + mixed $nullValue = null, + bool $calculateFormulas = true, + bool $formatData = true, + bool $returnCellRef = false, + bool $ignoreHidden = false, + bool $reduceArrays = false, + bool $lessFloatPrecision = false, + ): array { + $returnValue = []; + + $parts = explode(',', $ranges); + foreach ($parts as $part) { + // Loop through rows + foreach ($this->rangeToArrayYieldRows($part, $nullValue, $calculateFormulas, $formatData, $returnCellRef, $ignoreHidden, $reduceArrays, $lessFloatPrecision) as $rowRef => $rowArray) { + /** @var int $rowRef */ + $returnValue[$rowRef] = $rowArray; + } + } + + // Return + return $returnValue; + } + /** * Create array from a range of cells, yielding each row in turn. * @@ -2898,8 +3059,10 @@ class Worksheet * True - Return rows and columns indexed by their actual row and column IDs * @param bool $ignoreHidden False - Return values for rows/columns even if they are defined as hidden. * True - Don't return values for rows/columns that are defined as hidden. + * @param bool $reduceArrays If true and result is a formula which evaluates to an array, reduce it to the top leftmost value. + * @param bool $lessFloatPrecision If true, formatting unstyled floats will convert them to a more human-friendly but less computationally accurate value * - * @return Generator + * @return Generator> */ public function rangeToArrayYieldRows( string $range, @@ -2908,7 +3071,8 @@ class Worksheet bool $formatData = true, bool $returnCellRef = false, bool $ignoreHidden = false, - bool $reduceArrays = false + bool $reduceArrays = false, + bool $lessFloatPrecision = false ) { $range = Validations::validateCellOrCellRange($range); @@ -2921,7 +3085,7 @@ class Worksheet $minColInt = $rangeStart[0]; $maxColInt = $rangeEnd[0]; - ++$maxCol; + StringHelper::stringIncrement($maxCol); /** @var array */ $hiddenColumns = []; $nullRow = $this->buildNullRow($nullValue, $minCol, $maxCol, $returnCellRef, $ignoreHidden, $hiddenColumns); @@ -2940,9 +3104,30 @@ class Worksheet $index = ($row - 1) * AddressRange::MAX_COLUMN_INT + 1; $indexPlus = $index + AddressRange::MAX_COLUMN_INT - 1; + + // Binary search to quickly approach the correct index + $keyIndex = intdiv($keysCount, 2); + $boundLow = 0; + $boundHigh = $keysCount - 1; + while ($boundLow <= $boundHigh) { + $keyIndex = intdiv($boundLow + $boundHigh, 2); + if ($keys[$keyIndex] < $index) { + $boundLow = $keyIndex + 1; + } elseif ($keys[$keyIndex] > $index) { + $boundHigh = $keyIndex - 1; + } else { + break; + } + } + + // Realign to the proper index value + while ($keyIndex > 0 && $keys[$keyIndex] > $index) { + --$keyIndex; + } while ($keyIndex < $keysCount && $keys[$keyIndex] < $index) { ++$keyIndex; } + while ($keyIndex < $keysCount && $keys[$keyIndex] <= $indexPlus) { $key = $keys[$keyIndex]; $thisRow = intdiv($key - 1, AddressRange::MAX_COLUMN_INT) + 1; @@ -2953,7 +3138,7 @@ class Worksheet $columnRef = $returnCellRef ? $col : ($thisCol - $minColInt); $cell = $this->cellCollection->get("{$col}{$thisRow}"); if ($cell !== null) { - $value = $this->cellToArray($cell, $calculateFormulas, $formatData, $nullValue); + $value = $this->cellToArray($cell, $calculateFormulas, $formatData, $nullValue, lessFloatPrecision: $lessFloatPrecision); if ($reduceArrays) { while (is_array($value)) { $value = array_shift($value); @@ -2983,6 +3168,8 @@ class Worksheet * @param bool $ignoreHidden False - Return values for rows/columns even if they are defined as hidden. * True - Don't return values for rows/columns that are defined as hidden. * @param array $hiddenColumns + * + * @return mixed[] */ private function buildNullRow( mixed $nullValue, @@ -2994,9 +3181,9 @@ class Worksheet ): array { $nullRow = []; $c = -1; - for ($col = $minCol; $col !== $maxCol; ++$col) { + for ($col = $minCol; $col !== $maxCol; StringHelper::stringIncrement($col)) { if ($ignoreHidden === true && $this->columnDimensionExists($col) && $this->getColumnDimension($col)->getVisible() === false) { - $hiddenColumns[$col] = true; // @phpstan-ignore-line + $hiddenColumns[$col] = true; } else { $columnRef = $returnCellRef ? $col : ++$c; $nullRow[$columnRef] = $nullValue; @@ -3027,7 +3214,7 @@ class Worksheet if ($namedRange->getLocalOnly()) { $worksheet = $namedRange->getWorksheet(); - if ($worksheet === null || $this->hash !== $worksheet->getHashInt()) { + if ($worksheet === null || $this !== $worksheet) { if ($returnNullIfInvalid) { return null; } @@ -3052,6 +3239,10 @@ class Worksheet * True - Return rows and columns indexed by their actual row and column IDs * @param bool $ignoreHidden False - Return values for rows/columns even if they are defined as hidden. * True - Don't return values for rows/columns that are defined as hidden. + * @param bool $reduceArrays If true and result is a formula which evaluates to an array, reduce it to the top leftmost value. + * @param bool $lessFloatPrecision If true, formatting unstyled floats will convert them to a more human-friendly but less computationally accurate value + * + * @return mixed[][] */ public function namedRangeToArray( string $definedName, @@ -3060,7 +3251,8 @@ class Worksheet bool $formatData = true, bool $returnCellRef = false, bool $ignoreHidden = false, - bool $reduceArrays = false + bool $reduceArrays = false, + bool $lessFloatPrecision = false ): array { $retVal = []; $namedRange = $this->validateNamedRange($definedName); @@ -3069,7 +3261,7 @@ class Worksheet $cellRange = str_replace('$', '', $cellRange); $workSheet = $namedRange->getWorksheet(); if ($workSheet !== null) { - $retVal = $workSheet->rangeToArray($cellRange, $nullValue, $calculateFormulas, $formatData, $returnCellRef, $ignoreHidden, $reduceArrays); + $retVal = $workSheet->rangeToArray($cellRange, $nullValue, $calculateFormulas, $formatData, $returnCellRef, $ignoreHidden, $reduceArrays, $lessFloatPrecision); } } @@ -3086,6 +3278,10 @@ class Worksheet * True - Return rows and columns indexed by their actual row and column IDs * @param bool $ignoreHidden False - Return values for rows/columns even if they are defined as hidden. * True - Don't return values for rows/columns that are defined as hidden. + * @param bool $reduceArrays If true and result is a formula which evaluates to an array, reduce it to the top leftmost value. + * @param bool $lessFloatPrecision If true, formatting unstyled floats will convert them to a more human-friendly but less computationally accurate value + * + * @return mixed[][] */ public function toArray( mixed $nullValue = null, @@ -3093,7 +3289,8 @@ class Worksheet bool $formatData = true, bool $returnCellRef = false, bool $ignoreHidden = false, - bool $reduceArrays = false + bool $reduceArrays = false, + bool $lessFloatPrecision = false ): array { // Garbage collect... $this->garbageCollect(); @@ -3104,7 +3301,7 @@ class Worksheet $maxRow = $this->getHighestRow(); // Return - return $this->rangeToArray("A1:{$maxCol}{$maxRow}", $nullValue, $calculateFormulas, $formatData, $returnCellRef, $ignoreHidden, $reduceArrays); + return $this->rangeToArray("A1:{$maxCol}{$maxRow}", $nullValue, $calculateFormulas, $formatData, $returnCellRef, $ignoreHidden, $reduceArrays, $lessFloatPrecision); } /** @@ -3155,20 +3352,22 @@ class Worksheet } // Cache values - if ($highestColumn < 1) { - $this->cachedHighestColumn = 1; - } else { - $this->cachedHighestColumn = $highestColumn; - } + $this->cachedHighestColumn = max(1, $highestColumn); + /** @var int $highestRow */ $this->cachedHighestRow = $highestRow; // Return return $this; } + /** + * @deprecated 5.2.0 Serves no useful purpose. No replacement. + * + * @codeCoverageIgnore + */ public function getHashInt(): int { - return $this->hash; + return spl_object_id($this); } /** @@ -3366,7 +3565,7 @@ class Worksheet $collectionCells = []; $collectionRanges = []; foreach ($this->dataValidationCollection as $key => $dataValidation) { - if (preg_match('/[: ]/', $key) === 1) { + if (Preg::isMatch('/[: ]/', $key)) { $collectionRanges[$key] = $dataValidation; } else { $collectionCells[$key] = $dataValidation; @@ -3555,7 +3754,6 @@ class Worksheet } } } - $this->hash = spl_object_id($this); } /** @@ -3634,7 +3832,7 @@ class Worksheet public static function nameRequiresQuotes(string $sheetName): bool { - return preg_match(self::SHEET_NAME_REQUIRES_NO_QUOTES, $sheetName) !== 1; + return !Preg::isMatch(self::SHEET_NAME_REQUIRES_NO_QUOTES, $sheetName); } public function isRowVisible(int $row): bool @@ -3746,6 +3944,7 @@ class Worksheet { $toArray = Coordinate::extractAllCellReferencesInRange($toCells); $valueString = $this->getCell($fromCell)->getValueString(); + /** @var mixed[][] */ $style = $this->getStyle($fromCell)->exportArray(); $fromIndexes = Coordinate::indexesFromString($fromCell); $referenceHelper = ReferenceHelper::getInstance(); @@ -3766,7 +3965,7 @@ class Worksheet $keys = $this->cellCollection->getCoordinates(); foreach ($keys as $key) { if ($this->getCell($key)->getDataType() === DataType::TYPE_FORMULA) { - if (preg_match(self::FUNCTION_LIKE_GROUPBY, $this->getCell($key)->getValue()) !== 1) { + if (!Preg::isMatch(self::FUNCTION_LIKE_GROUPBY, $this->getCell($key)->getValueString())) { $this->getCell($key)->getCalculatedValue(); } } @@ -3794,6 +3993,7 @@ class Worksheet return false; } + /** @param mixed[][] $styleArray */ public function applyStylesFromArray(string $coordinate, array $styleArray): bool { $spreadsheet = $this->parent; @@ -3810,4 +4010,22 @@ class Worksheet return true; } + + public function copyFormula(string $fromCell, string $toCell): void + { + $formula = $this->getCell($fromCell)->getValue(); + $newFormula = $formula; + if (is_string($formula) && $this->getCell($fromCell)->getDataType() === DataType::TYPE_FORMULA) { + [$fromColInt, $fromRow] = Coordinate::indexesFromString($fromCell); + [$toColInt, $toRow] = Coordinate::indexesFromString($toCell); + $helper = ReferenceHelper::getInstance(); + $newFormula = $helper->updateFormulaReferences( + $formula, + 'A1', + $toColInt - $fromColInt, + $toRow - $fromRow + ); + } + $this->setCellValue($toCell, $newFormula); + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/BaseWriter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/BaseWriter.php index 5e6d3cd..50aa9da 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/BaseWriter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/BaseWriter.php @@ -123,13 +123,18 @@ abstract class BaseWriter implements IWriter $this->shouldCloseFile = true; } + protected function tryClose(): bool + { + return fclose($this->fileHandle); + } + /** * Close file handle only if we opened it ourselves. */ protected function maybeCloseFileHandle(): void { if ($this->shouldCloseFile) { - if (!fclose($this->fileHandle)) { + if (!$this->tryClose()) { throw new Exception('Could not close file after writing.'); } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Csv.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Csv.php index 19da568..0ec8aa4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Csv.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Csv.php @@ -2,10 +2,10 @@ namespace PhpOffice\PhpSpreadsheet\Writer; +use Composer\Pcre\Preg; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Spreadsheet; -use Stringable; class Csv extends BaseWriter { @@ -133,6 +133,7 @@ class Csv extends BaseWriter } } } + /** @var string[] $cellsArray */ $this->writeLine($this->fileHandle, $cellsArray); } @@ -271,25 +272,11 @@ class Csv extends BaseWriter return $this->enclosureRequired; } - /** - * Convert boolean to TRUE/FALSE; otherwise return element cast to string. - * - * @param null|bool|float|int|string|Stringable $element element to be converted - */ - private static function elementToString(mixed $element): string - { - if (is_bool($element)) { - return $element ? 'TRUE' : 'FALSE'; - } - - return (string) $element; - } - /** * Write line to CSV file. * * @param resource $fileHandle PHP filehandle - * @param array $values Array containing values in a row + * @param string[] $values Array containing values in a row */ private function writeLine($fileHandle, array $values): void { @@ -299,9 +286,23 @@ class Csv extends BaseWriter // Build the line $line = ''; - /** @var null|bool|float|int|string|Stringable $element */ foreach ($values as $element) { - $element = self::elementToString($element); + if (Preg::isMatch('/^([+-])?(\d+)[.](\d+)/', $element, $matches)) { + // Excel will "convert" file with pop-up + // if there are more than 15 digits precision. + $whole = $matches[2]; + if ($whole !== '0') { + $wholeLen = strlen($whole); + $frac = $matches[3]; + $maxFracLen = 15 - $wholeLen; + if ($maxFracLen >= 0 && strlen($frac) > $maxFracLen) { + $result = sprintf("%.{$maxFracLen}F", $element); + if (str_contains($result, '.')) { + $element = Preg::replace('/[.]?0+$/', '', $result); // strip trailing zeros + } + } + } + } // Add delimiter $line .= $delimiter; $delimiter = $this->delimiter; @@ -325,7 +326,7 @@ class Csv extends BaseWriter // Write to file if ($this->outputEncoding != '') { - $line = mb_convert_encoding($line, $this->outputEncoding); + $line = (string) mb_convert_encoding($line, $this->outputEncoding); } fwrite($fileHandle, $line); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Html.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Html.php index a70cc97..ecf79d8 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Html.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Html.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer; use Composer\Pcre\Preg; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\DataType; @@ -22,6 +23,9 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Alignment; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Style\Borders; +use PhpOffice\PhpSpreadsheet\Style\Conditional; +use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\CellStyleAssessor; +use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\StyleMerger; use PhpOffice\PhpSpreadsheet\Style\Fill; use PhpOffice\PhpSpreadsheet\Style\Font; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; @@ -30,6 +34,8 @@ use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup; +use PhpOffice\PhpSpreadsheet\Worksheet\Table; +use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableDxfsStyle; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Html extends BaseWriter @@ -80,11 +86,15 @@ class Html extends BaseWriter /** * Array of CSS styles. + * + * @var string[][] */ private ?array $cssStyles = null; /** * Array of column widths in points. + * + * @var array> */ private array $columnWidths; @@ -100,16 +110,22 @@ class Html extends BaseWriter /** * Excel cells that should not be written as HTML cells. + * + * @var mixed[][][][] */ private array $isSpannedCell = []; /** * Excel cells that are upper-left corner in a cell merge. + * + * @var int[][][][] */ private array $isBaseCell = []; /** * Excel rows that should not be written as HTML rows. + * + * @var mixed[][] */ private array $isSpannedRow = []; @@ -126,7 +142,7 @@ class Html extends BaseWriter /** * Callback for editing generated html. * - * @var null|callable + * @var null|callable(string): string */ private $editHtmlCallback; @@ -142,6 +158,22 @@ class Html extends BaseWriter private string $getFalse = 'FALSE'; + protected bool $rtlSheets = false; + + protected bool $ltrSheets = false; + + /** + * Table formats + * Enables table formats in writer, disabled here, must be enabled in writer via a setter. + */ + protected bool $tableFormats = false; + + /** + * Conditional Formatting + * Enables conditional formatting in writer, disabled here, must be enabled in writer via a setter. + */ + protected bool $conditionalFormatting = false; + /** * Create a new HTML. */ @@ -162,22 +194,39 @@ class Html extends BaseWriter public function save($filename, int $flags = 0): void { $this->processFlags($flags); - // Open file $this->openFileHandle($filename); - // Write html fwrite($this->fileHandle, $this->generateHTMLAll()); - // Close file $this->maybeCloseFileHandle(); } + protected function checkRtlAndLtr(): void + { + $this->rtlSheets = false; + $this->ltrSheets = false; + if ($this->sheetIndex === null) { + foreach ($this->spreadsheet->getAllSheets() as $sheet) { + if ($sheet->getRightToLeft()) { + $this->rtlSheets = true; + } else { + $this->ltrSheets = true; + } + } + } else { + if ($this->spreadsheet->getSheet($this->sheetIndex)->getRightToLeft()) { + $this->rtlSheets = true; + } + } + } + /** * Save Spreadsheet as html to variable. */ public function generateHtmlAll(): string { + $this->checkRtlAndLtr(); $sheets = $this->generateSheetPrep(); foreach ($sheets as $sheet) { $sheet->calculateArrays($this->preCalculateFormulas); @@ -356,7 +405,8 @@ class Html extends BaseWriter // Construct HTML $properties = $this->spreadsheet->getProperties(); $html = '' . PHP_EOL; - $html .= '' . PHP_EOL; + $rtl = ($this->rtlSheets && !$this->ltrSheets) ? " dir='rtl'" : ''; + $html .= '' . PHP_EOL; $html .= ' ' . PHP_EOL; $html .= ' ' . PHP_EOL; $html .= ' ' . PHP_EOL; @@ -427,6 +477,7 @@ class Html extends BaseWriter return $sheets; } + /** @return array{int, int, int} */ private function generateSheetStarts(Worksheet $sheet, int $rowMin): array { // calculate start of , @@ -446,6 +497,7 @@ class Html extends BaseWriter return [$theadStart, $theadEnd, $tbodyStart]; } + /** @return array{string, string, string} */ private function generateSheetTags(int $row, int $theadStart, int $theadEnd, int $tbodyStart): array { // ? @@ -473,12 +525,24 @@ class Html extends BaseWriter // Loop all sheets $sheetId = 0; + + $activeSheet = $this->spreadsheet->getActiveSheetIndex(); + foreach ($sheets as $sheet) { + // save active cells + $selectedCells = $sheet->getSelectedCells(); // Write table header $html .= $this->generateTableHeader($sheet); $this->sheetCharts = []; $this->sheetDrawings = []; - + $condStylesCollection = $sheet->getConditionalStylesCollection(); + foreach ($condStylesCollection as $condStyles) { + foreach ($condStyles as $key => $cs) { + if ($cs->getConditionType() === Conditional::CONDITION_COLORSCALE) { + $cs->getColorScale()?->setScaleArray(); + } + } + } // Get worksheet dimension [$min, $max] = explode(':', $sheet->calculateWorksheetDataDimension()); [$minCol, $minRow, $minColString] = Coordinate::indexesFromString($min); @@ -486,12 +550,11 @@ class Html extends BaseWriter $this->extendRowsAndColumns($sheet, $maxCol, $maxRow); [$theadStart, $theadEnd, $tbodyStart] = $this->generateSheetStarts($sheet, $minRow); - // Loop through cells $row = $minRow - 1; while ($row++ < $maxRow) { [$cellType, $startTag, $endTag] = $this->generateSheetTags($row, $theadStart, $theadEnd, $tbodyStart); - $html .= $startTag; + $html .= StringHelper::convertToString($startTag); // Write row if there are HTML table cells in it if ($this->shouldGenerateRow($sheet, $row) && !isset($this->isSpannedRow[$sheet->getParentOrThrow()->getIndex($sheet)][$row])) { @@ -507,14 +570,14 @@ class Html extends BaseWriter $rowData[$column] = ($sheet->getCellCollection()->has($cellAddress)) ? $cellAddress : ''; } ++$column; - ++$colStr; + /** @var string $colStr */ + StringHelper::stringIncrement($colStr); } $html .= $this->generateRow($sheet, $rowData, $row - 1, $cellType); } - $html .= $endTag; + $html .= StringHelper::convertToString($endTag); } - // Write table footer $html .= $this->generateTableFooter(); // Writing PDF? @@ -526,7 +589,9 @@ class Html extends BaseWriter // Next sheet ++$sheetId; + $sheet->setSelectedCells($selectedCells); } + $this->spreadsheet->setActiveSheetIndex($activeSheet); return $html; } @@ -761,6 +826,7 @@ class Html extends BaseWriter $topLeft = $chart->getTopLeftPosition(); $bottomRight = $chart->getBottomRightPosition(); $tlCell = $topLeft['cell']; + /** @var string */ $brCell = $bottomRight['cell']; if ($tlCell !== '' && $brCell !== '') { $tlCoordinate = Coordinate::indexesFromString($tlCell); @@ -775,11 +841,12 @@ class Html extends BaseWriter $totalHeight += ($height >= 0) ? $height : $defaultRowHeight; } $rightEdge = $brCoordinate[2]; - ++$rightEdge; - for ($column = $tlCoordinate[2]; $column !== $rightEdge; ++$column) { + StringHelper::stringIncrement($rightEdge); + for ($column = $tlCoordinate[2]; $column !== $rightEdge;) { $width = $sheet->getColumnDimension($column)->getWidth(); $width = ($width < 0) ? self::DEFAULT_CELL_WIDTH_PIXELS : SharedDrawing::cellDimensionToPixels($sheet->getColumnDimension($column)->getWidth(), $this->defaultFont); $totalWidth += $width; + StringHelper::stringIncrement($column); } $chart->setRenderedWidth($totalWidth); $chart->setRenderedHeight($totalHeight); @@ -823,6 +890,7 @@ class Html extends BaseWriter return $html; } + /** @param string[][] $css */ private function buildCssRowHeights(Worksheet $sheet, array &$css, int $sheetIndex): void { // Calculate row heights @@ -843,6 +911,7 @@ class Html extends BaseWriter } } + /** @param string[][] $css */ private function buildCssPerSheet(Worksheet $sheet, array &$css): void { // Calculate hash code @@ -871,7 +940,7 @@ class Html extends BaseWriter if ($this->shouldGenerateColumn($sheet, $colStr)) { $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = self::DEFAULT_CELL_WIDTH_POINTS . 'pt'; } - ++$colStr; + StringHelper::stringIncrement($colStr); } // col elements, loop through columnDimensions and set width @@ -915,6 +984,8 @@ class Html extends BaseWriter * Build CSS styles. * * @param bool $generateSurroundingHTML Generate surrounding HTML style? (html { }) + * + * @return string[][] */ public function buildCSS(bool $generateSurroundingHTML = true): array { @@ -927,6 +998,7 @@ class Html extends BaseWriter $this->calculateSpans(); // Construct CSS + /** @var string[][] */ $css = []; // Start styles @@ -977,6 +1049,9 @@ class Html extends BaseWriter // .s {} $css['.s']['text-align'] = 'left'; // STRING + $css['.floatright']['float'] = 'right'; + $css['.floatleft']['float'] = 'left'; + // Calculate cell style hashes foreach ($this->spreadsheet->getCellXfCollection() as $index => $style) { $css['td.style' . $index . ', th.style' . $index] = $this->createCSSStyle($style); @@ -1007,20 +1082,24 @@ class Html extends BaseWriter /** * Create CSS style. + * + * @return string[] */ - private function createCSSStyle(Style $style): array + private function createCSSStyle(Style $style, bool $conditional = false): array { // Create CSS return array_merge( - $this->createCSSStyleAlignment($style->getAlignment()), + $conditional ? [] : $this->createCSSStyleAlignment($style->getAlignment()), $this->createCSSStyleBorders($style->getBorders()), - $this->createCSSStyleFont($style->getFont()), + $this->createCSSStyleFont($style->getFont(), conditional: $conditional), $this->createCSSStyleFill($style->getFill()) ); } /** * Create CSS style. + * + * @return string[] */ private function createCSSStyleAlignment(Alignment $alignment): array { @@ -1036,7 +1115,12 @@ class Html extends BaseWriter if ($textAlign) { $css['text-align'] = $textAlign; if (in_array($textAlign, ['left', 'right'])) { - $css['padding-' . $textAlign] = (string) ((int) $alignment->getIndent() * 9) . 'px'; + $css['padding-' . $textAlign] = (string) ($alignment->getIndent() * Alignment::INDENT_UNITS_TO_PIXELS) . 'px'; + } + } else { + $indent = $alignment->getIndent(); + if ($indent !== 0) { + $css['text-indent'] = (string) ($alignment->getIndent() * Alignment::INDENT_UNITS_TO_PIXELS) . 'px'; } } $rotation = $alignment->getTextRotation(); @@ -1047,44 +1131,77 @@ class Html extends BaseWriter $css['transform'] = "rotate({$rotation}deg)"; } } - - return $css; - } - - /** - * Create CSS style. - */ - private function createCSSStyleFont(Font $font): array - { - // Construct CSS - $css = []; - - // Create CSS - if ($font->getBold()) { - $css['font-weight'] = 'bold'; + $direction = $alignment->getReadOrder(); + if ($direction === Alignment::READORDER_LTR) { + $css['direction'] = 'ltr'; + } elseif ($direction === Alignment::READORDER_RTL) { + $css['direction'] = 'rtl'; } - if ($font->getUnderline() != Font::UNDERLINE_NONE && $font->getStrikethrough()) { - $css['text-decoration'] = 'underline line-through'; - } elseif ($font->getUnderline() != Font::UNDERLINE_NONE) { - $css['text-decoration'] = 'underline'; - } elseif ($font->getStrikethrough()) { - $css['text-decoration'] = 'line-through'; - } - if ($font->getItalic()) { - $css['font-style'] = 'italic'; - } - - $css['color'] = '#' . $font->getColor()->getRGB(); - $css['font-family'] = '\'' . htmlspecialchars((string) $font->getName(), ENT_QUOTES) . '\''; - $css['font-size'] = $font->getSize() . 'pt'; return $css; } + /** + * Create CSS style. + * + * @return string[] + */ + private function createCSSStyleFont(Font $font, bool $useDefaults = false, bool $conditional = false): array + { + // Construct CSS + $css = []; + + // Create CSS + if ($font->getBold()) { + $css['font-weight'] = 'bold'; + } elseif ($useDefaults) { + $css['font-weight'] = 'normal'; + } + if ($font->getUnderline() != Font::UNDERLINE_NONE && $font->getStrikethrough()) { + $css['text-decoration'] = 'underline line-through'; + } elseif ($font->getUnderline() != Font::UNDERLINE_NONE) { + $css['text-decoration'] = 'underline'; + } elseif ($font->getStrikethrough()) { + $css['text-decoration'] = 'line-through'; + } elseif ($useDefaults) { + $css['text-decoration'] = 'normal'; + } + if ($font->getItalic()) { + $css['font-style'] = 'italic'; + } elseif ($useDefaults) { + $css['font-style'] = 'normal'; + } + + $css['color'] = '#' . $font->getColor()->getRGB(); + if (!$conditional) { + $css['font-family'] = '\'' . htmlspecialchars((string) $font->getName(), ENT_QUOTES) . '\''; + $css['font-size'] = $font->getSize() . 'pt'; + } + + return $css; + } + + /** + * @param string[] $css + */ + private function styleBorder(array &$css, string $index, Border $border): void + { + $borderStyle = $border->getBorderStyle(); + // Mpdf doesn't process !important, so omit unimportant border none + if ($borderStyle === Border::BORDER_NONE && $this instanceof Pdf\Mpdf) { + return; + } + if ($borderStyle !== Border::BORDER_OMIT) { + $css[$index] = $this->createCSSStyleBorder($border); + } + } + /** * Create CSS style. * * @param Borders $borders Borders + * + * @return string[] */ private function createCSSStyleBorders(Borders $borders): array { @@ -1092,26 +1209,10 @@ class Html extends BaseWriter $css = []; // Create CSS - if (!($this instanceof Pdf\Mpdf)) { - $css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom()); - $css['border-top'] = $this->createCSSStyleBorder($borders->getTop()); - $css['border-left'] = $this->createCSSStyleBorder($borders->getLeft()); - $css['border-right'] = $this->createCSSStyleBorder($borders->getRight()); - } else { - // Mpdf doesn't process !important, so omit unimportant border none - if ($borders->getBottom()->getBorderStyle() !== Border::BORDER_NONE) { - $css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom()); - } - if ($borders->getTop()->getBorderStyle() !== Border::BORDER_NONE) { - $css['border-top'] = $this->createCSSStyleBorder($borders->getTop()); - } - if ($borders->getLeft()->getBorderStyle() !== Border::BORDER_NONE) { - $css['border-left'] = $this->createCSSStyleBorder($borders->getLeft()); - } - if ($borders->getRight()->getBorderStyle() !== Border::BORDER_NONE) { - $css['border-right'] = $this->createCSSStyleBorder($borders->getRight()); - } - } + $this->styleBorder($css, 'border-bottom', $borders->getBottom()); + $this->styleBorder($css, 'border-top', $borders->getTop()); + $this->styleBorder($css, 'border-left', $borders->getLeft()); + $this->styleBorder($css, 'border-right', $borders->getRight()); return $css; } @@ -1133,6 +1234,8 @@ class Html extends BaseWriter * Create CSS style (Fill). * * @param Fill $fill Fill + * + * @return string[] */ private function createCSSStyleFill(Fill $fill): array { @@ -1169,21 +1272,52 @@ class Html extends BaseWriter return $html; } + private function getDir(Worksheet $worksheet): string + { + if ($worksheet->getRightToLeft()) { + return " dir='rtl'"; + } + if ($this->rtlSheets) { + return " dir='ltr'"; + } + + return ''; + } + + private function getFloat(Worksheet $worksheet): string + { + $float = ''; + if ($worksheet->getRightToLeft()) { + if ($this->ltrSheets) { + $float = ' floatright'; + } + } else { + if ($this->rtlSheets) { + $float = ' floatleft'; + } + } + + return $float; + } + private function generateTableTagInline(Worksheet $worksheet, string $id): string { $style = isset($this->cssStyles['table']) ? $this->assembleCSS($this->cssStyles['table']) : ''; - + $rtl = $this->getDir($worksheet); + $float = $this->getFloat($worksheet); $prntgrid = $worksheet->getPrintGridlines(); $viewgrid = $this->isPdf ? $prntgrid : $worksheet->getShowGridlines(); if ($viewgrid && $prntgrid) { - $html = " " . PHP_EOL; + $html = "
                  " . PHP_EOL; } elseif ($viewgrid) { - $html = "
                  " . PHP_EOL; + $html = "
                  " . PHP_EOL; } elseif ($prntgrid) { - $html = "
                  " . PHP_EOL; + $html = "
                  " . PHP_EOL; + } elseif ($float === '') { + $html = "
                  " . PHP_EOL; } else { - $html = "
                  " . PHP_EOL; + $html = "
                  " . PHP_EOL; } return $html; @@ -1192,9 +1326,11 @@ class Html extends BaseWriter private function generateTableTag(Worksheet $worksheet, string $id, string &$html, int $sheetIndex): void { if (!$this->useInlineCss) { + $rtl = $this->getDir($worksheet); + $float = $this->getFloat($worksheet); $gridlines = $worksheet->getShowGridlines() ? ' gridlines' : ''; $gridlinesp = $worksheet->getPrintGridlines() ? ' gridlinesp' : ''; - $html .= "
                  " . PHP_EOL; + $html .= "
                  " . PHP_EOL; } else { $html .= $this->generateTableTagInline($worksheet, $id); } @@ -1213,10 +1349,12 @@ class Html extends BaseWriter // Construct HTML $html = ''; $id = $showid ? "id='sheet$sheetIndex'" : ''; + $clear = ($this->rtlSheets && $this->ltrSheets) ? '; clear:both' : ''; + if ($showid) { - $html .= "
                  " . PHP_EOL; + $html .= "
                  " . PHP_EOL; } else { - $html .= "
                  " . PHP_EOL; + $html .= "
                  " . PHP_EOL; } $this->generateTableTag($worksheet, $id, $html, $sheetIndex); @@ -1278,12 +1416,17 @@ class Html extends BaseWriter $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $row]) ? $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $row]) : ''; - $html .= '
                  ' . PHP_EOL; + if ($style === '') { + $html .= ' ' . PHP_EOL; + } else { + $html .= ' ' . PHP_EOL; + } } return $html; } + /** @return array{null|''|Cell, array{}|string, non-empty-string} */ private function generateRowCellCss(Worksheet $worksheet, string $cellAddress, int $row, int $columnNumber): array { $cell = ($cellAddress > '') ? $worksheet->getCellCollection()->get($cellAddress) : ''; @@ -1292,40 +1435,28 @@ class Html extends BaseWriter $cssClass = 'column' . $columnNumber; } else { $cssClass = []; - // The statements below do nothing. - // Commenting out the code rather than deleting it - // in case someone can figure out what their intent was. - //if ($cellType == 'th') { - // if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) { - // $this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum]; - // } - //} else { - // if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) { - // $this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum]; - // } - //} - // End of mystery statements. } return [$cell, $cssClass, $coordinate]; } - private function generateRowCellDataValueRich(RichText $richText): string + private function generateRowCellDataValueRich(RichText $richText, ?Font $defaultFont = null): string { $cellData = ''; // Loop through rich text elements $elements = $richText->getRichTextElements(); foreach ($elements as $element) { // Rich text start? - if ($element instanceof Run) { + $font = ($element instanceof Run) ? $element->getFont() : $defaultFont; + if ($element instanceof Run || $font !== null) { $cellEnd = ''; - if ($element->getFont() !== null) { - $cellData .= ''; + if ($font !== null) { + $cellData .= ''; - if ($element->getFont()->getSuperscript()) { + if ($font->getSuperscript()) { $cellData .= ''; $cellEnd = ''; - } elseif ($element->getFont()->getSubscript()) { + } elseif ($font->getSubscript()) { $cellData .= ''; $cellEnd = ''; } @@ -1353,10 +1484,14 @@ class Html extends BaseWriter private function generateRowCellDataValue(Worksheet $worksheet, Cell $cell, string &$cellData): void { if ($cell->getValue() instanceof RichText) { - $cellData .= $this->generateRowCellDataValueRich($cell->getValue()); + $cellData .= $this->generateRowCellDataValueRich($cell->getValue(), $cell->getStyle()->getFont()); } else { if ($this->preCalculateFormulas) { - $origData = $cell->getCalculatedValue(); + try { + $origData = $cell->getCalculatedValue(); + } catch (CalculationException $exception) { + $origData = '#ERROR'; // mark as error, rather than crash everything + } if ($this->betterBoolean && is_bool($origData)) { $origData2 = $origData ? $this->getTrue : $this->getFalse; } else { @@ -1389,9 +1524,9 @@ class Html extends BaseWriter } } + /** @param string|string[] $cssClass */ private function generateRowCellData(Worksheet $worksheet, null|Cell|string $cell, array|string &$cssClass): string { - $cellData = ' '; if ($cell instanceof Cell) { $cellData = ''; // Don't know what this does, and no test cases. @@ -1440,13 +1575,21 @@ class Html extends BaseWriter } } } else { + $cellData = "$cell"; // Use default borders for empty cell if (is_string($cssClass)) { $cssClass .= ' style0'; } } + /* + * Browsers may remove an entirely empty row. + * An interesting option is to leave an empty cell empty using css. + * td:empty::after{content: "\00a0";} + * This works well in modern browsers. + * Alas, none of our Pdf writers can handle it. + */ - return $cellData; + return (trim($cellData) === '') ? ' ' : $cellData; } private function generateRowIncludeCharts(Worksheet $worksheet, string $coordinate): string @@ -1462,6 +1605,10 @@ class Html extends BaseWriter return $html; } + /** + * @param string|string[] $cssClass + * @param Conditional[] $condStyles + */ private function generateRowWriteCell( string &$html, Worksheet $worksheet, @@ -1473,7 +1620,8 @@ class Html extends BaseWriter array|string $cssClass, int $colNum, int $sheetIndex, - int $row + int $row, + array $condStyles = [] ): void { // Image? $htmlx = $this->writeImageInCell($coordinate); @@ -1491,6 +1639,7 @@ class Html extends BaseWriter $html .= ' data-type="' . DataType::TYPE_STRING . '"'; } } + $holdCss = ''; if (!$this->useInlineCss && !$this->isPdf && is_string($cssClass)) { $html .= ' class="' . $cssClass . '"'; if ($htmlx) { @@ -1535,13 +1684,83 @@ class Html extends BaseWriter if ($htmlx) { $xcssClass['position'] = 'relative'; } - $html .= ' style="' . $this->assembleCSS($xcssClass) . '"'; + /** @var string[] $xcssClass */ + $holdCss = $this->assembleCSS($xcssClass); if ($this->useInlineCss) { - $html .= ' class="gridlines gridlinesp"'; + $prntgrid = $worksheet->getPrintGridlines(); + $viewgrid = $this->isPdf ? $prntgrid : $worksheet->getShowGridlines(); + if ($viewgrid && $prntgrid) { + $html .= ' class="gridlines gridlinesp"'; + } elseif ($viewgrid) { + $html .= ' class="gridlines"'; + } elseif ($prntgrid) { + $html .= ' class="gridlinesp"'; + } } } + $html = $this->generateRowSpans($html, $rowSpan, $colSpan); + $tables = $worksheet->getTablesWithStylesForCell($worksheet->getCell($coordinate)); + if (count($tables) > 0 || count($condStyles) > 0) { + $matched = false; // TODO the style gotten from the merger overrides everything + $styleMerger = new StyleMerger($worksheet->getCell($coordinate)->getStyle()); + if ($this->tableFormats) { + if (count($tables) > 0) { + foreach ($tables as $ts) { + /** @var Table $ts */ + $dxfsTableStyle = $ts->getStyle()->getTableDxfsStyle(); + if ($dxfsTableStyle !== null) { + /** @var int */ + $tableRow = $ts->getRowNumber($coordinate); + /** @var TableDxfsStyle $dxfsTableStyle */ + if ($tableRow === 0 && $dxfsTableStyle->getHeaderRowStyle() !== null) { + $styleMerger->mergeStyle($dxfsTableStyle->getHeaderRowStyle()); + $matched = true; + } elseif ($tableRow % 2 === 1 && $dxfsTableStyle->getFirstRowStripeStyle() !== null) { + $styleMerger->mergeStyle($dxfsTableStyle->getFirstRowStripeStyle()); + $matched = true; + } elseif ($tableRow % 2 === 0 && $dxfsTableStyle->getSecondRowStripeStyle() !== null) { + $styleMerger->mergeStyle($dxfsTableStyle->getSecondRowStripeStyle()); + $matched = true; + } + } + } + } + } + if (count($condStyles) > 0 && $this->conditionalFormatting) { + if ($worksheet->getConditionalRange($coordinate) !== null) { + $assessor = new CellStyleAssessor($worksheet->getCell($coordinate), $worksheet->getConditionalRange($coordinate)); + } else { + $assessor = new CellStyleAssessor($worksheet->getCell($coordinate), $coordinate); + } + $matchedStyle = $assessor->matchConditionsReturnNullIfNoneMatched($condStyles, $cellData, true); + + if ($matchedStyle !== null) { + $matched = true; + // this is really slow + $styleMerger->mergeStyle($matchedStyle); + } + } + if ($matched) { + $styles = $this->createCSSStyle($styleMerger->getStyle(), true); + $html .= ' style="'; + if ($holdCss !== '') { + $html .= "$holdCss; "; + $holdCss = ''; + } + foreach ($styles as $key => $value) { + if (!str_starts_with($key, 'border-') || $value !== 'none #000000') { + $html .= $key . ':' . $value . ';'; + } + } + $html .= '"'; + } + } + if ($holdCss !== '') { + $html .= ' style="' . $holdCss . '"'; + } + $html .= '>'; $html .= $htmlx; @@ -1557,7 +1776,7 @@ class Html extends BaseWriter /** * Generate row. * - * @param array $values Array containing cells in a row + * @param array $values Array containing cells in a row * @param int $row Row number (0-based) * @param string $cellType eg: 'td' */ @@ -1587,6 +1806,9 @@ class Html extends BaseWriter // Cell Data $cellData = $this->generateRowCellData($worksheet, $cell, $cssClass); + // Get an array of all styles + $condStyles = $worksheet->getStyle($coordinate)->getConditionalStyles(); + // Hyperlink? if ($worksheet->hyperlinkExists($coordinate) && !$worksheet->getHyperlink($coordinate)->isInternal()) { $url = $worksheet->getHyperlink($coordinate)->getUrl(); @@ -1614,6 +1836,7 @@ class Html extends BaseWriter $colSpan = 1; $rowSpan = 1; if (isset($this->isBaseCell[$worksheet->getParentOrThrow()->getIndex($worksheet)][$row + 1][$colNum])) { + /** @var array */ $spans = $this->isBaseCell[$worksheet->getParentOrThrow()->getIndex($worksheet)][$row + 1][$colNum]; $rowSpan = $spans['rowspan']; $colSpan = $spans['colspan']; @@ -1636,7 +1859,7 @@ class Html extends BaseWriter // Write if ($writeCell) { - $this->generateRowWriteCell($html, $worksheet, $coordinate, $cellType, $cellData, $colSpan, $rowSpan, $cssClass, $colNum, $sheetIndex, $row); + $this->generateRowWriteCell($html, $worksheet, $coordinate, $cellType, $cellData, $colSpan, $rowSpan, $cssClass, $colNum, $sheetIndex, $row, $condStyles); } // Next column @@ -1650,6 +1873,7 @@ class Html extends BaseWriter return $html; } + /** @param string[] $matches */ private static function replaceNonAscii(array $matches): string { return '&#' . mb_ord($matches[0], 'UTF-8') . ';'; @@ -1666,6 +1890,8 @@ class Html extends BaseWriter /** * Takes array where of CSS properties / values and converts to CSS string. + * + * @param string[] $values */ private function assembleCSS(array $values = []): string { @@ -1738,6 +1964,30 @@ class Html extends BaseWriter return $this; } + public function getTableFormats(): bool + { + return $this->tableFormats; + } + + public function setTableFormats(bool $tableFormats): self + { + $this->tableFormats = $tableFormats; + + return $this; + } + + public function getConditionalFormatting(): bool + { + return $this->conditionalFormatting; + } + + public function setConditionalFormatting(bool $conditionalFormatting): self + { + $this->conditionalFormatting = $conditionalFormatting; + + return $this; + } + /** * Add color to formatted string as inline style. * @@ -1844,6 +2094,7 @@ class Html extends BaseWriter $this->spansAreCalculated = true; } + /** @param int[] $candidateSpannedRow */ private function calculateSpansOmitRows(Worksheet $sheet, int $sheetIndex, array $candidateSpannedRow): void { // Identify which rows should be omitted in HTML. These are the rows where all the cells @@ -1860,6 +2111,7 @@ class Html extends BaseWriter // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1 if (isset($this->isSpannedRow[$sheetIndex])) { foreach ($this->isSpannedRow[$sheetIndex] as $rowIndex) { + /** @var int $rowIndex */ $adjustedBaseCells = []; $c = -1; $e = $countColumns - 1; @@ -1868,6 +2120,7 @@ class Html extends BaseWriter if (!in_array($baseCell, $adjustedBaseCells, true)) { // subtract rowspan by 1 + /** @var array $baseCell */ --$this->isBaseCell[$sheetIndex][$baseCell[0]][$baseCell[1]]['rowspan']; $adjustedBaseCells[] = $baseCell; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Cell/Style.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Cell/Style.php index 92fc497..5c3cf52 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Cell/Style.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Cell/Style.php @@ -151,6 +151,7 @@ class Style $vAlign = $style->getAlignment()->getVertical(); $wrap = $style->getAlignment()->getWrapText(); $indent = $style->getAlignment()->getIndent(); + $readOrder = $style->getAlignment()->getReadOrder(); $this->writer->startElement('style:table-cell-properties'); if (!empty($vAlign) || $wrap) { @@ -172,7 +173,7 @@ class Style $this->writer->endElement(); - if ($hAlign !== '' || !empty($indent)) { + if ($hAlign !== '' || !empty($indent) || $readOrder === Alignment::READORDER_RTL || $readOrder === Alignment::READORDER_LTR) { $this->writer ->startElement('style:paragraph-properties'); if ($hAlign !== '') { @@ -182,6 +183,11 @@ class Style $indentString = sprintf('%.4f', $indent * self::INDENT_TO_INCHES) . 'in'; $this->writer->writeAttribute('fo:margin-left', $indentString); } + if ($readOrder === Alignment::READORDER_RTL) { + $this->writer->writeAttribute('style:writing-mode', 'rl-tb'); + } elseif ($readOrder === Alignment::READORDER_LTR) { + $this->writer->writeAttribute('style:writing-mode', 'lr-tb'); + } $this->writer->endElement(); } } @@ -204,15 +210,26 @@ class Style if ($font->getBold()) { $this->writer->writeAttribute('fo:font-weight', 'bold'); - $this->writer->writeAttribute('style:font-weight-complex', 'bold'); - $this->writer->writeAttribute('style:font-weight-asian', 'bold'); + $this->writer->writeAttribute( + 'style:font-weight-complex', + 'bold' + ); + $this->writer->writeAttribute( + 'style:font-weight-asian', + 'bold' + ); } if ($font->getItalic()) { $this->writer->writeAttribute('fo:font-style', 'italic'); } - $this->writer->writeAttribute('fo:color', sprintf('#%s', $font->getColor()->getRGB())); + if ($font->getAutoColor()) { + $this->writer + ->writeAttribute('style:use-window-font-color', 'true'); + } else { + $this->writer->writeAttribute('fo:color', sprintf('#%s', $font->getColor()->getRGB())); + } if ($family = $font->getName()) { $this->writer->writeAttribute('fo:font-family', $family); @@ -291,6 +308,21 @@ class Style $this->writer->endElement(); // Close style:style } + public function writeDefaultRowStyle(RowDimension $rowDimension, int $sheetId): void + { + $this->writer->startElement('style:style'); + $this->writer->writeAttribute('style:family', 'table-row'); + $this->writer->writeAttribute( + 'style:name', + sprintf('%s%d', self::ROW_STYLE_PREFIX, $sheetId) + ); + + $this->writeRowProperties($rowDimension); + + // End + $this->writer->endElement(); // Close style:style + } + public function writeTableStyle(Worksheet $worksheet, int $sheetId): void { $this->writer->startElement('style:style'); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Content.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Content.php index 2be188b..5aea6c2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Content.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Content.php @@ -174,6 +174,11 @@ class Content extends WriterPart 'table:style-name', sprintf('%s_%d_%d', Style::ROW_STYLE_PREFIX, $sheetIndex, $row->getRowIndex()) ); + } elseif ($sheet->getDefaultRowDimension()->getRowHeight() > 0.0 && !$sheet->getRowDimension($row->getRowIndex())->getCustomFormat()) { + $objWriter->writeAttribute( + 'table:style-name', + sprintf('%s%d', Style::ROW_STYLE_PREFIX, $sheetIndex) + ); } $this->writeCells($objWriter, $cellIterator); $objWriter->endElement(); @@ -323,6 +328,10 @@ class Content extends WriterPart } for ($i = 0; $i < $sheetCount; ++$i) { $worksheet = $spreadsheet->getSheet($i); + $default = $worksheet->getDefaultRowDimension(); + if ($default->getRowHeight() > 0.0) { + $styleWriter->writeDefaultRowStyle($default, $i); + } foreach ($worksheet->getRowDimensions() as $rowDimension) { if ($rowDimension->getRowHeight() > 0.0) { $styleWriter->writeRowStyles($rowDimension, $i); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Formula.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Formula.php index 4a874c7..0e470b6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Formula.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Formula.php @@ -9,6 +9,7 @@ use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Formula { + /** @var string[] */ private array $definedNames = []; /** @@ -25,6 +26,7 @@ class Formula { $formula = $this->convertCellReferences($formula, $worksheetName); $formula = $this->convertDefinedNames($formula); + $formula = $this->convertFunctionNames($formula); if (!str_starts_with($formula, '=')) { $formula = '=' . $formula; @@ -116,4 +118,22 @@ class Formula return $formula; } + + private function convertFunctionNames(string $formula): string + { + return Preg::replace( + [ + '/\b((CEILING|FLOOR)' + . '([.](MATH|PRECISE))?)\s*[(]/ui', + '/\b(CEILING|FLOOR)[.]XCL\s*[(]/ui', + '/\b(CEILING|FLOOR)[.]ODS\s*[(]/ui', + ], + [ + 'COM.MICROSOFT.$1(', + 'COM.MICROSOFT.$1(', + '$1(', + ], + $formula + ); + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Settings.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Settings.php index 695c604..d5c99f0 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Settings.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Ods/Settings.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Ods; use Composer\Pcre\Preg; use PhpOffice\PhpSpreadsheet\Cell\CellAddress; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; @@ -88,9 +89,7 @@ class Settings extends WriterPart $objWriter->writeAttribute('config:name', $worksheet->getTitle()); $this->writeSelectedCells($objWriter, $worksheet); - if ($worksheet->getFreezePane() !== null) { - $this->writeFreezePane($objWriter, $worksheet); - } + $this->writeFreezePane($objWriter, $worksheet); $objWriter->endElement(); // config:config-item-map-entry Worksheet } @@ -125,7 +124,7 @@ class Settings extends WriterPart private function writeFreezePane(XMLWriter $objWriter, Worksheet $worksheet): void { - $freezePane = CellAddress::fromCellAddress($worksheet->getFreezePane() ?? ''); + $freezePane = CellAddress::fromCellAddress($worksheet->getFreezePane() ?? 'A1'); if ($freezePane->cellAddress() === 'A1') { return; } @@ -139,7 +138,7 @@ class Settings extends WriterPart $this->writeSplitValue($objWriter, 'PositionLeft', 'short', '0'); $this->writeSplitValue($objWriter, 'PositionRight', 'short', (string) ($columnId - 1)); - for ($column = 'A'; $column !== $columnName; ++$column) { + for ($column = 'A'; $column !== $columnName; StringHelper::stringIncrement($column)) { $worksheet->getColumnDimension($column)->setAutoSize(true); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf.php index 17e1905..484b02e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf.php @@ -31,6 +31,8 @@ abstract class Pdf extends Html /** * Paper Sizes xRef List. + * + * @var array */ protected static array $paperSizes = [ PageSetup::PAPERSIZE_LETTER => 'LETTER', // (8.5 in. by 11 in.) diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php index 6569980..bad31ce 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php @@ -36,7 +36,7 @@ class Dompdf extends Pdf $orientation = $this->getOrientation() ?? $setup->getOrientation(); $orientation = ($orientation === PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->getPaperSize() ?? $setup->getPaperSize(); - $paperSize = self::$paperSizes[$printPaperSize] ?? PageSetup::getPaperSizeDefault(); + $paperSize = self::$paperSizes[$printPaperSize] ?? self::$paperSizes[PageSetup::getPaperSizeDefault()] ?? 'LETTER'; if (is_array($paperSize) && count($paperSize) === 2) { $paperSize = [0.0, 0.0, $paperSize[0], $paperSize[1]]; } @@ -51,7 +51,7 @@ class Dompdf extends Pdf $pdf->render(); // Write to file - fwrite($fileHandle, $pdf->output() ?? ''); + fwrite($fileHandle, $pdf->output()); parent::restoreStateAfterSave(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php index a98e3ed..83d4986 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php @@ -13,7 +13,7 @@ class Mpdf extends Pdf /** * Gets the implementation of external PDF library that should be used. * - * @param array $config Configuration array + * @param mixed[] $config Configuration array * * @return \Mpdf\Mpdf implementation */ @@ -40,6 +40,13 @@ class Mpdf extends Pdf // Create PDF $config = ['tempDir' => $this->tempDir . '/mpdf']; + $restoreHandler = false; + if (PHP_VERSION_ID >= self::$temporaryVersionCheck) { + // @codeCoverageIgnoreStart + set_error_handler(self::specialErrorHandler(...)); + $restoreHandler = true; + // @codeCoverageIgnoreEnd + } $pdf = $this->createExternalWriterInstance($config); $ortmp = $orientation; $pdf->_setPageSize($paperSize, $ortmp); @@ -79,11 +86,34 @@ class Mpdf extends Pdf } // Write to file - fwrite($fileHandle, $pdf->Output('', 'S')); + /** @var string */ + $str = $pdf->Output('', 'S'); + fwrite($fileHandle, $str); + if ($restoreHandler) { + restore_error_handler(); // @codeCoverageIgnore + } parent::restoreStateAfterSave(); } + protected static int $temporaryVersionCheck = 80500; + + /** + * Temporary handler for Php8.5 waiting for Dompdf release. + * + * @codeCoverageIgnore + */ + public function specialErrorHandler(int $errno, string $errstr, string $filename, int $lineno): bool + { + if ($errno === E_DEPRECATED) { + if (preg_match('/Providing an empty string is deprecated/', $errstr) === 1) { + return true; + } + } + + return false; // continue error handling + } + /** * Convert inches to mm. */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php index 747ebbd..94cbaff 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php @@ -24,15 +24,21 @@ class Tcpdf extends Pdf * * @param string $orientation Page orientation * @param string $unit Unit measure - * @param array|string $paperSize Paper size + * @param float[]|string $paperSize Paper size * * @return \TCPDF implementation */ protected function createExternalWriterInstance(string $orientation, string $unit, $paperSize): \TCPDF { + $this->defines(); + return new \TCPDF($orientation, $unit, $paperSize); } + protected function defines(): void + { + } + /** * Save Spreadsheet to file. * @@ -50,7 +56,7 @@ class Tcpdf extends Pdf $orientation = $this->getOrientation() ?? $setup->getOrientation(); $orientation = ($orientation === PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->getPaperSize() ?? $setup->getPaperSize(); - $paperSize = self::$paperSizes[$printPaperSize] ?? PageSetup::getPaperSizeDefault(); + $paperSize = self::$paperSizes[$printPaperSize] ?? self::$paperSizes[PageSetup::getPaperSizeDefault()] ?? 'LETTER'; $printMargins = $this->spreadsheet->getSheet($this->getSheetIndex() ?? 0)->getPageMargins(); // Create PDF @@ -67,14 +73,28 @@ class Tcpdf extends Pdf // Set the appropriate font $pdf->SetFont($this->getFont()); + $this->checkRtlAndLtr(); + if ($this->rtlSheets && !$this->ltrSheets) { + $pdf->setRTL(true); + } $pdf->writeHTML($this->generateHTMLAll()); // Document info - $pdf->SetTitle($this->spreadsheet->getProperties()->getTitle()); - $pdf->SetAuthor($this->spreadsheet->getProperties()->getCreator()); - $pdf->SetSubject($this->spreadsheet->getProperties()->getSubject()); - $pdf->SetKeywords($this->spreadsheet->getProperties()->getKeywords()); - $pdf->SetCreator($this->spreadsheet->getProperties()->getCreator()); + $pdf->SetTitle( + $this->spreadsheet->getProperties()->getTitle() + ); + $pdf->SetAuthor( + $this->spreadsheet->getProperties()->getCreator() + ); + $pdf->SetSubject( + $this->spreadsheet->getProperties()->getSubject() + ); + $pdf->SetKeywords( + $this->spreadsheet->getProperties()->getKeywords() + ); + $pdf->SetCreator( + $this->spreadsheet->getProperties()->getCreator() + ); // Write to file fwrite($fileHandle, $pdf->output('', 'S')); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php index 8d622be..3ef9bec 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php @@ -46,11 +46,15 @@ class Xls extends BaseWriter /** * Array of unique shared strings in workbook. + * + * @var array */ private array $strTable = []; /** * Color cache. Mapping between RGB value and color index. + * + * @var mixed[] */ private array $colors; @@ -61,6 +65,8 @@ class Xls extends BaseWriter /** * Identifier clusters for drawings. Used in MSODRAWINGGROUP record. + * + * @var mixed[] */ private array $IDCLs; @@ -145,12 +151,26 @@ class Xls extends BaseWriter $cell = $this->writerWorksheets[$i]->phpSheet->getCellCollection()->get($coordinate); $cVal = $cell->getValue(); if ($cVal instanceof RichText) { + $active = $this->spreadsheet->getActiveSheetIndex(); + $sheet = $cell->getWorksheet(); + $selected = $sheet->getSelectedCells(); + $font = $cell->getStyle()->getFont(); + $this->writerWorksheets[$i] + ->fontHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font); + $sheet->setSelectedCells($selected); + if ($active > -1) { + $this->spreadsheet + ->setActiveSheetIndex($active); + } $elements = $cVal->getRichTextElements(); foreach ($elements as $element) { if ($element instanceof Run) { $font = $element->getFont(); if ($font !== null) { - $this->writerWorksheets[$i]->fontHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font); + $this->writerWorksheets[$i] + ->fontHashIndex[ + $font->getHashCode() + ] = $this->writerWorkbook->addFont($font); } } } @@ -297,6 +317,7 @@ class Xls extends BaseWriter $twoAnchor = \PhpOffice\PhpSpreadsheet\Shared\Xls::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height); if (is_array($twoAnchor)) { + /** @var array{startCoordinates: string, startOffsetX: float|int, startOffsetY: float|int, endCoordinates: string, endOffsetX: float|int, endOffsetY: float|int} $twoAnchor */ $spContainer->setStartCoordinates($twoAnchor['startCoordinates']); $spContainer->setStartOffsetX($twoAnchor['startOffsetX']); $spContainer->setStartOffsetY($twoAnchor['startOffsetY']); @@ -752,6 +773,7 @@ class Xls extends BaseWriter return $data; } + /** @param array $dataSection */ private function writeSummaryPropOle(float|int $dataProp, int &$dataSection_NumProps, array &$dataSection, int $sumdata, int $typdata): void { if ($dataProp) { @@ -765,6 +787,7 @@ class Xls extends BaseWriter } } + /** @param array $dataSection */ private function writeSummaryProp(string $dataProp, int &$dataSection_NumProps, array &$dataSection, int $sumdata, int $typdata): void { if ($dataProp) { @@ -840,6 +863,7 @@ class Xls extends BaseWriter // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; foreach ($dataSection as $dataProp) { + /** @var array{data: array{data: string, length: int}, summary: array{pack: string, data: string}, offset: array{pack: string}, type: array{data: int, pack: string}} $dataProp */ // Summary $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); // Offset diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/CellDataValidation.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/CellDataValidation.php index 3afdac1..0f0b7b7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/CellDataValidation.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/CellDataValidation.php @@ -47,32 +47,20 @@ class CellDataValidation { $validationType = $dataValidation->getType(); - if (array_key_exists($validationType, self::$validationTypeMap)) { - return self::$validationTypeMap[$validationType]; - } - - return self::$validationTypeMap[DataValidation::TYPE_NONE]; + return self::$validationTypeMap[$validationType] ?? self::$validationTypeMap[DataValidation::TYPE_NONE]; } public static function errorStyle(DataValidation $dataValidation): int { $errorStyle = $dataValidation->getErrorStyle(); - if (array_key_exists($errorStyle, self::$errorStyleMap)) { - return self::$errorStyleMap[$errorStyle]; - } - - return self::$errorStyleMap[DataValidation::STYLE_STOP]; + return self::$errorStyleMap[$errorStyle] ?? self::$errorStyleMap[DataValidation::STYLE_STOP]; } public static function operator(DataValidation $dataValidation): int { $operator = $dataValidation->getOperator(); - if (array_key_exists($operator, self::$operatorMap)) { - return self::$operatorMap[$operator]; - } - - return self::$operatorMap[DataValidation::OPERATOR_BETWEEN]; + return self::$operatorMap[$operator] ?? self::$operatorMap[DataValidation::OPERATOR_BETWEEN]; } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/ConditionalHelper.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/ConditionalHelper.php index 016f0b3..f367692 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/ConditionalHelper.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/ConditionalHelper.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Xls; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard; class ConditionalHelper @@ -35,9 +36,7 @@ class ConditionalHelper $this->tokens = pack('Cv', 0x1E, $condition); } else { try { - /** @var float|int|string */ - $conditionx = $condition; // @phpstan-ignore-line - $formula = Wizard\WizardAbstract::reverseAdjustCellRef((string) $conditionx, $cellRange); + $formula = Wizard\WizardAbstract::reverseAdjustCellRef(StringHelper::convertToString($condition), $cellRange); $this->parser->parse($formula); $this->tokens = $this->parser->toReversePolish(); $this->size = strlen($this->tokens ?? ''); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/ErrorCode.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/ErrorCode.php index e74f4f4..ec9618b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/ErrorCode.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/ErrorCode.php @@ -19,10 +19,6 @@ class ErrorCode public static function error(string $errorCode): int { - if (array_key_exists($errorCode, self::$errorCodeMap)) { - return self::$errorCodeMap[$errorCode]; - } - - return 0; + return self::$errorCodeMap[$errorCode] ?? 0; } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Escher.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Escher.php index c3993be..26e1d02 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Escher.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Escher.php @@ -26,11 +26,15 @@ class Escher /** * Shape offsets. Positions in binary stream where a new shape record begins. + * + * @var int[] */ private array $spOffsets; /** * Shape types. + * + * @var mixed[] */ private array $spTypes; @@ -91,6 +95,7 @@ class Escher $IDCLs = $this->object->getIDCLs(); foreach ($IDCLs as $dgId => $maxReducedSpId) { + /** @var int $maxReducedSpId */ $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); } @@ -323,6 +328,7 @@ class Escher // treat the inner data foreach ($this->object->getChildren() as $spContainer) { + /** @var Blip|BSE|BstoreContainer|DgContainer|DggContainer|SharedEscher|SpContainer|SpgrContainer $spContainer */ $writer = new self($spContainer); $spData = $writer->close(); $innerData .= $spData; @@ -481,6 +487,8 @@ class Escher /** * Gets the shape offsets. + * + * @return int[] */ public function getSpOffsets(): array { @@ -489,6 +497,8 @@ class Escher /** * Gets the shape types. + * + * @return mixed[] */ public function getSpTypes(): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Parser.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Parser.php index c6581ad..55a530e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Parser.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Parser.php @@ -91,21 +91,29 @@ class Parser /** * The parse tree to be generated. + * + * @var mixed[]|string */ public array|string $parseTree; /** * Array of external sheets. + * + * @var array */ private array $externalSheets; /** * Array of sheet references in the form of REF structures. + * + * @var array */ public array $references; /** * The Excel ptg indices. + * + * @var array */ private array $ptg = [ 'ptgExp' => 0x01, @@ -218,6 +226,8 @@ class Parser * -1 is a variable number of arguments. * class: The reference, value or array class of the function args. * vol: The function is volatile. + * + * @var array */ private array $functions = [ // function ptg args class vol @@ -400,9 +410,11 @@ class Parser 'FISHER' => [283, 1, 1, 0], 'FISHERINV' => [284, 1, 1, 0], 'FLOOR' => [285, 2, 1, 0], + 'FLOOR.XCL' => [285, 2, 1, 0], 'GAMMADIST' => [286, 4, 1, 0], 'GAMMAINV' => [287, 3, 1, 0], 'CEILING' => [288, 2, 1, 0], + 'CEILING.XCL' => [288, 2, 1, 0], 'HYPGEOMDIST' => [289, 4, 1, 0], 'LOGNORMDIST' => [290, 3, 1, 0], 'LOGINV' => [291, 3, 1, 0], @@ -883,7 +895,7 @@ class Parser * * @param string $cell The Excel cell reference to be packed * - * @return array Array containing the row and column in packed() format + * @return array{string, string} Array containing the row and column in packed() format */ private function cellToPackedRowcol(string $cell): array { @@ -912,7 +924,7 @@ class Parser * * @param string $range The Excel range to be packed * - * @return array Array containing (row1,col1,row2,col2) in packed() format + * @return array{string, string, string, string} Array containing (row1,col1,row2,col2) in packed() format */ private function rangeToPackedRange(string $range): array { @@ -956,6 +968,8 @@ class Parser * whether the row or column are relative references. * * @param string $cell the Excel cell reference in A1 format + * + * @return array{int, int, int, int} */ private function cellToRowcol(string $cell): array { @@ -983,7 +997,7 @@ class Parser --$row; --$col; - return [$row, $col, $row_rel, $col_rel]; + return [(int) $row, (int) $col, $row_rel, $col_rel]; } /** @@ -1213,7 +1227,7 @@ class Parser * It parses a condition. It assumes the following rule: * Cond -> Expr [(">" | "<") Expr]. * - * @return array The parsed ptg'd tree on success + * @return mixed[] The parsed ptg'd tree on success */ private function condition(): array { @@ -1255,7 +1269,7 @@ class Parser * -> "+" Term : Positive value * -> Error code. * - * @return array The parsed ptg'd tree on success + * @return mixed[] The parsed ptg'd tree on success */ private function expression(): array { @@ -1326,7 +1340,7 @@ class Parser * This function just introduces a ptgParen element in the tree, so that Excel * doesn't get confused when working with a parenthesized formula afterwards. * - * @return array The parsed ptg'd tree + * @return mixed[] The parsed ptg'd tree * * @see fact() */ @@ -1339,7 +1353,7 @@ class Parser * It parses a term. It assumes the following rule: * Term -> Fact [("*" | "/") Fact]. * - * @return array The parsed ptg'd tree on success + * @return mixed[] The parsed ptg'd tree on success */ private function term(): array { @@ -1370,7 +1384,7 @@ class Parser * | Number * | Function. * - * @return array The parsed ptg'd tree on success + * @return mixed[] The parsed ptg'd tree on success */ private function fact(): array { @@ -1503,7 +1517,7 @@ class Parser * It parses a function call. It assumes the following rule: * Func -> ( Expr [,Expr]* ). * - * @return array The parsed ptg'd tree on success + * @return mixed[] The parsed ptg'd tree on success */ private function func(): array { @@ -1550,7 +1564,7 @@ class Parser * @param mixed $left the left array (sub-tree) or a final node * @param mixed $right the right array (sub-tree) or a final node * - * @return array A tree + * @return mixed[] A tree */ private function createTree(mixed $value, mixed $left, mixed $right): array { @@ -1580,7 +1594,7 @@ class Parser * * In fact all operands, functions, references, etc... are written as ptg's * - * @param array $tree the optional tree to convert + * @param mixed[] $tree the optional tree to convert * * @return string The tree in reverse polish notation */ @@ -1598,40 +1612,49 @@ class Parser $converted_tree = $this->toReversePolish($tree['left']); $polish .= $converted_tree; } elseif ($tree['left'] != '') { // It's a final node - $converted_tree = $this->convert($tree['left']); + $converted_tree = $this->convert($tree['left']); //* @phpstan-ignore-line $polish .= $converted_tree; } if (is_array($tree['right'])) { $converted_tree = $this->toReversePolish($tree['right']); $polish .= $converted_tree; } elseif ($tree['right'] != '') { // It's a final node - $converted_tree = $this->convert($tree['right']); + $converted_tree = $this->convert(StringHelper::convertToString($tree['right'])); $polish .= $converted_tree; } // if it's a function convert it here (so we can set it's arguments) + /** @var string */ + $treeValueString = $tree['value']; if ( - Preg::isMatch("/^[A-Z0-9\xc0-\xdc\\.]+$/", $tree['value']) - && !Preg::isMatch('/^([A-Ia-i]?[A-Za-z])(\d+)$/', $tree['value']) + Preg::isMatch("/^[A-Z0-9\xc0-\xdc\\.]+$/", $treeValueString) + && !Preg::isMatch('/^([A-Ia-i]?[A-Za-z])(\d+)$/', $treeValueString) && !Preg::isMatch( '/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/', - $tree['value'] + $treeValueString ) - && !is_numeric($tree['value']) - && !isset($this->ptg[$tree['value']]) + && !is_numeric($treeValueString) + && !isset($this->ptg[$treeValueString]) ) { // left subtree for a function is always an array. if ($tree['left'] != '') { - $left_tree = $this->toReversePolish($tree['left']); + $left_tree = $this->toReversePolish($tree['left']); //* @phpstan-ignore-line } else { $left_tree = ''; } // add its left subtree and return. if ($left_tree !== '' || $tree['right'] !== '') { - return $left_tree . $this->convertFunction($tree['value'], $tree['right'] ?: 0); + /** @var string */ + $treeValueString = $tree['value']; + /** @var int */ + $treeRightInt = is_numeric($tree['right']) ? ((int) $tree['right']) : 0; + + return $left_tree . $this->convertFunction($treeValueString, $treeRightInt); } } - $converted_tree = $this->convert($tree['value']); + /** @var string */ + $treeValueString = $tree['value']; + $converted_tree = $this->convert($treeValueString); return $polish . $converted_tree; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Workbook.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Workbook.php index 43e9f1c..4e0bf3e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Workbook.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Workbook.php @@ -10,6 +10,7 @@ use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\Style; // Original file header of PEAR::Spreadsheet_Excel_Writer_Workbook (used as the base for this class): @@ -69,6 +70,8 @@ class Workbook extends BIFFwriter /** * Array containing the colour palette. + * + * @var array */ private array $palette; @@ -96,26 +99,36 @@ class Workbook extends BIFFwriter /** * Added fonts. Maps from font's hash => index in workbook. + * + * @var int[] */ private array $addedFonts = []; /** * Shared number formats. + * + * @var NumberFormat[] */ private array $numberFormats = []; /** * Added number formats. Maps from numberFormat's hash => index in workbook. + * + * @var int[] */ private array $addedNumberFormats = []; /** * Sizes of the binary worksheet streams. + * + * @var int[] */ private array $worksheetSizes = []; /** * Offsets of the binary worksheet streams relative to the start of the global workbook stream. + * + * @var int[] */ private array $worksheetOffsets = []; @@ -131,11 +144,15 @@ class Workbook extends BIFFwriter /** * Array of unique shared strings in workbook. + * + * @var array */ private array $stringTable; /** * Color cache. + * + * @var int[] */ private array $colors; @@ -150,8 +167,8 @@ class Workbook extends BIFFwriter * @param Spreadsheet $spreadsheet The Workbook * @param int $str_total Total number of strings * @param int $str_unique Total number of unique strings - * @param array $str_table String Table - * @param array $colors Colour Table + * @param array $str_table String Table + * @param int[] $colors Colour Table * @param Parser $parser The formula parser created for the Workbook */ public function __construct(Spreadsheet $spreadsheet, int &$str_total, int &$str_unique, array &$str_table, array &$colors, Parser $parser) @@ -290,9 +307,9 @@ class Workbook extends BIFFwriter if (!isset($this->colors[$rgb])) { $color = [ - hexdec(substr($rgb, 0, 2)), - hexdec(substr($rgb, 2, 2)), - hexdec(substr($rgb, 4)), + (int) hexdec(substr($rgb, 0, 2)), + (int) hexdec(substr($rgb, 2, 2)), + (int) hexdec(substr($rgb, 4)), 0, ]; $colorIndex = array_search($color, $this->palette); @@ -391,7 +408,7 @@ class Workbook extends BIFFwriter * Assemble worksheets into a workbook and send the BIFF data to an OLE * storage. * - * @param array $worksheetSizes The sizes in bytes of the binary worksheet streams + * @param int[] $worksheetSizes The sizes in bytes of the binary worksheet streams * * @return string Binary data for workbook stream */ @@ -484,7 +501,7 @@ class Workbook extends BIFFwriter private function writeAllNumberFormats(): void { foreach ($this->numberFormats as $numberFormatIndex => $numberFormat) { - $this->writeNumberFormat($numberFormat->getFormatCode(), $numberFormatIndex); + $this->writeNumberFormat((string) $numberFormat->getFormatCode(), $numberFormatIndex); } } @@ -661,7 +678,9 @@ class Workbook extends BIFFwriter for ($j = 0; $j < $countPrintArea; ++$j) { $printAreaRect = $printArea[$j]; // e.g. A3:J6 $printAreaRect[0] = Coordinate::indexesFromString($printAreaRect[0]); - $printAreaRect[1] = Coordinate::indexesFromString($printAreaRect[1]); + /** @var string */ + $printAreaRect1 = $printAreaRect[1]; + $printAreaRect[1] = Coordinate::indexesFromString($printAreaRect1); $print_rowmin = $printAreaRect[0][1] - 1; $print_rowmax = $printAreaRect[1][1] - 1; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php index 8ca3f2f..810abe9 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php @@ -67,6 +67,8 @@ class Worksheet extends BIFFwriter /** * Array containing format information for columns. + * + * @var array */ private array $columnInfo; @@ -109,11 +111,15 @@ class Worksheet extends BIFFwriter /** * Reference to the array containing all the unique strings in the workbook. + * + * @var array */ private array $stringTable; /** * Color cache. + * + * @var mixed[] */ private array $colors; @@ -149,6 +155,8 @@ class Worksheet extends BIFFwriter /** * Array of font hashes associated to FONT records index. + * + * @var array */ public array $fontHashIndex; @@ -163,8 +171,8 @@ class Worksheet extends BIFFwriter * * @param int $str_total Total number of strings * @param int $str_unique Total number of unique strings - * @param array $str_table String Table - * @param array $colors Colour Table + * @param array $str_table String Table + * @param mixed[] $colors Colour Table * @param Parser $parser The formula parser created for the Workbook * @param bool $preCalculateFormulas Flag indicating whether formulas should be calculated or just written * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $phpSheet The worksheet to write @@ -203,15 +211,14 @@ class Worksheet extends BIFFwriter $maxC = $this->phpSheet->getHighestColumn(); // Determine lowest and highest column and row - $this->firstRowIndex = $minR; - $this->lastRowIndex = ($maxR > 65535) ? 65535 : $maxR; + // BIFF8 DIMENSIONS record requires 0-based indices for both rows and columns + // Row methods return 1-based values (Excel UI), so subtract 1 to convert to 0-based + $this->firstRowIndex = $minR - 1; + $this->lastRowIndex = ($maxR > 65536) ? 65535 : ($maxR - 1); - $this->firstColumnIndex = Coordinate::columnIndexFromString($minC); - $this->lastColumnIndex = Coordinate::columnIndexFromString($maxC); - - if ($this->lastColumnIndex > 255) { - $this->lastColumnIndex = 255; - } + // Column methods return 1-based values (columnIndexFromString('A') = 1), so subtract 1 + $this->firstColumnIndex = Coordinate::columnIndexFromString($minC) - 1; + $this->lastColumnIndex = min(255, Coordinate::columnIndexFromString($maxC) - 1); $this->writerWorkbook = $writerWorkbook; } @@ -250,7 +257,8 @@ class Worksheet extends BIFFwriter } $columnDimensions = $phpSheet->getColumnDimensions(); - $maxCol = $this->lastColumnIndex - 1; + // lastColumnIndex is now 0-based, so no need to subtract 1 + $maxCol = $this->lastColumnIndex; for ($i = 0; $i <= $maxCol; ++$i) { $hidden = 0; $level = 0; @@ -262,7 +270,7 @@ class Worksheet extends BIFFwriter if (isset($columnDimensions[$columnLetter])) { $columnDimension = $columnDimensions[$columnLetter]; if ($columnDimension->getWidth() >= 0) { - $width = $columnDimension->getWidth(); + $width = $columnDimension->getWidthForOutput(true); } $hidden = $columnDimension->getVisible() ? 0 : 1; $level = $columnDimension->getOutlineLevel(); @@ -373,11 +381,25 @@ class Worksheet extends BIFFwriter if ($getFont !== null) { $str_fontidx = $this->fontHashIndex[$getFont->getHashCode()]; } + } else { + $styleArray = $this->phpSheet + ->getParent() + ?->getCellXfCollection(); + if ($styleArray !== null) { + $font = $styleArray[$xfIndex - 15] ?? null; + if ($font !== null) { + $font = $font->getFont(); + } + if ($font !== null) { + $str_fontidx = $this->fontHashIndex[$font->getHashCode()]; + } + } } $arrcRun[] = ['strlen' => $str_pos, 'fontidx' => $str_fontidx]; // Position FROM $str_pos += StringHelper::countCharacters($element->getText(), 'UTF-8'); } + /** @var array $arrcRun */ $this->writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun); } else { switch ($cell->getDatatype()) { @@ -458,8 +480,9 @@ class Worksheet extends BIFFwriter [$column, $row] = Coordinate::indexesFromString($coordinate); $url = $hyperlink->getUrl(); - - if (str_contains($url, 'sheet://')) { + if ($url[0] === '#') { + $url = "internal:$url"; + } elseif (str_starts_with($url, 'sheet://')) { // internal to current workbook $url = str_replace('sheet://', 'internal:', $url); } elseif (Preg::isMatch('/^(http:|https:|ftp:|mailto:)/', $url)) { @@ -685,7 +708,7 @@ class Worksheet extends BIFFwriter * @param int $col Column index (0-based) * @param string $str The string * @param int $xfIndex The XF format index for the cell - * @param array $arrcRun Index to Font record and characters beginning + * @param array $arrcRun Index to Font record and characters beginning */ private function writeRichTextString(int $row, int $col, string $str, int $xfIndex, array $arrcRun): void { @@ -946,12 +969,11 @@ class Worksheet extends BIFFwriter // Check for internal/external sheet links or default to web link if (Preg::isMatch('[^internal:]', $url)) { $this->writeUrlInternal($row1, $col1, $row2, $col2, $url); - } - if (Preg::isMatch('[^external:]', $url)) { + } elseif (Preg::isMatch('[^external:]', $url)) { $this->writeUrlExternal($row1, $col1, $row2, $col2, $url); + } else { + $this->writeUrlWeb($row1, $col1, $row2, $col2, $url); } - - $this->writeUrlWeb($row1, $col1, $row2, $col2, $url); } /** @@ -1301,7 +1323,7 @@ class Worksheet extends BIFFwriter * Note: The SDK says the record length is 0x0B but Excel writes a 0x0C * length record. * - * @param array $col_array This is the only parameter received and is composed of the following: + * @param array{?int, ?int, ?float, ?int, ?int, ?int} $col_array This is the only parameter received and is composed of the following: * 0 => First formatted column, * 1 => Last formatted column, * 2 => Col width (8.43 is Excel default), @@ -2166,6 +2188,10 @@ class Worksheet extends BIFFwriter ? $this->processBitmapGd($bitmap) : $this->processBitmap($bitmap); [$width, $height, $size, $data] = $bitmap_array; + /** @var int $width */ + /** @var int $height */ + /** @var int $size */ + /** @var string $data */ // Scale the frame of the image. $width *= $scale_x; @@ -2406,7 +2432,7 @@ class Worksheet extends BIFFwriter * * @param string $bitmap The bitmap to process * - * @return array Array with data and properties of the bitmap + * @return mixed[] Array with data and properties of the bitmap */ public function processBitmap(string $bitmap): array { @@ -2438,6 +2464,7 @@ class Worksheet extends BIFFwriter // the data size at offset 0x22. // $size_array = unpack('Vsa', substr($data, 0, 4)) ?: []; + /** @var int */ $size = $size_array['sa']; $data = substr($data, 4); $size -= 0x36; // Subtract size of bitmap header. diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Xf.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Xf.php index 2ab5a4e..bda33ed 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Xf.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Xf.php @@ -220,8 +220,9 @@ class Xf $header = pack('vv', $record, $length); //BIFF8 options: identation, shrinkToFit and text direction - $biff8_options = $this->style->getAlignment()->getIndent(); + $biff8_options = $this->style->getAlignment()->getIndent() & 15; $biff8_options |= (int) $this->style->getAlignment()->getShrinkToFit() << 4; + $biff8_options |= $this->style->getAlignment()->getReadOrder() << 6; $data = pack('vvvC', $ifnt, $ifmt, $style, $align); $data .= pack('CCC', self::mapTextRotation((int) $this->style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php index 34c387f..a38c930 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\HashTable; +use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Borders; use PhpOffice\PhpSpreadsheet\Style\Conditional; @@ -145,6 +146,8 @@ class Xlsx extends BaseWriter // Default changed from null in PhpSpreadsheet 4.0.0. private ?bool $forceFullCalc = self::DEFAULT_FORCE_FULL_CALC; + protected bool $restrictMaxColumnWidth = false; + /** * Create a new Xlsx Writer. */ @@ -249,6 +252,53 @@ class Xlsx extends BaseWriter return $this->writerPartWorksheet; } + public function createStyleDictionaries(): void + { + $this->styleHashTable->addFromSource( + $this->getWriterPartStyle()->allStyles( + $this->spreadSheet + ) + ); + $this->stylesConditionalHashTable->addFromSource( + $this->getWriterPartStyle()->allConditionalStyles( + $this->spreadSheet + ) + ); + $this->fillHashTable->addFromSource( + $this->getWriterPartStyle()->allFills( + $this->spreadSheet + ) + ); + $this->fontHashTable->addFromSource( + $this->getWriterPartStyle()->allFonts( + $this->spreadSheet + ) + ); + $this->bordersHashTable->addFromSource( + $this->getWriterPartStyle()->allBorders( + $this->spreadSheet + ) + ); + $this->numFmtHashTable->addFromSource( + $this->getWriterPartStyle()->allNumberFormats( + $this->spreadSheet + ) + ); + } + + /** + * @return (RichText|string)[] $stringTable + */ + public function createStringTable(): array + { + $this->stringTable = []; + for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { + $this->stringTable = $this->getWriterPartStringTable()->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable); + } + + return $this->stringTable; + } + /** * Save PhpSpreadsheet to file. * @@ -269,22 +319,15 @@ class Xlsx extends BaseWriter Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); // Create string lookup table - $this->stringTable = []; - for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { - $this->stringTable = $this->getWriterPartStringTable()->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable); - } + $this->createStringTable(); // Create styles dictionaries - $this->styleHashTable->addFromSource($this->getWriterPartStyle()->allStyles($this->spreadSheet)); - $this->stylesConditionalHashTable->addFromSource($this->getWriterPartStyle()->allConditionalStyles($this->spreadSheet)); - $this->fillHashTable->addFromSource($this->getWriterPartStyle()->allFills($this->spreadSheet)); - $this->fontHashTable->addFromSource($this->getWriterPartStyle()->allFonts($this->spreadSheet)); - $this->bordersHashTable->addFromSource($this->getWriterPartStyle()->allBorders($this->spreadSheet)); - $this->numFmtHashTable->addFromSource($this->getWriterPartStyle()->allNumberFormats($this->spreadSheet)); + $this->createStyleDictionaries(); // Create drawing dictionary $this->drawingHashTable->addFromSource($this->getWriterPartDrawing()->allDrawings($this->spreadSheet)); + /** @var string[] */ $zipContent = []; // Add [Content_Types].xml to ZIP file $zipContent['[Content_Types].xml'] = $this->getWriterPartContentTypes()->writeContentTypes($this->spreadSheet, $this->includeCharts); @@ -369,20 +412,22 @@ class Xlsx extends BaseWriter // Add worksheet relationships (drawings, ...) for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { // Add relationships + /** @var string[] $zipContent */ $zipContent['xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels'] = $this->getWriterPartRels()->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts, $tableRef1, $zipContent); // Add unparsedLoadedData $sheetCodeName = $this->spreadSheet->getSheet($i)->getCodeName(); + /** @var mixed[][][] */ $unparsedLoadedData = $this->spreadSheet->getUnparsedLoadedData(); - if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'])) { - foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'] as $ctrlProp) { - $zipContent[$ctrlProp['filePath']] = $ctrlProp['content']; - } + /** @var mixed[][] */ + $unparsedSheet = $unparsedLoadedData['sheets'][$sheetCodeName] ?? []; + foreach (($unparsedSheet['ctrlProps'] ?? []) as $ctrlProp) { + /** @var string[] $ctrlProp */ + $zipContent[$ctrlProp['filePath']] = $ctrlProp['content']; } - if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'])) { - foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'] as $ctrlProp) { - $zipContent[$ctrlProp['filePath']] = $ctrlProp['content']; - } + foreach (($unparsedSheet['printerSettings'] ?? []) as $ctrlProp) { + /** @var string[] $ctrlProp */ + $zipContent[$ctrlProp['filePath']] = $ctrlProp['content']; } $drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection(); @@ -398,15 +443,15 @@ class Xlsx extends BaseWriter // Drawings $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = $this->getWriterPartDrawing()->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts); - } elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) { + } elseif (isset($unparsedSheet['drawingAlternateContents'])) { // Drawings $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = $this->getWriterPartDrawing()->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts); } // Add unparsed drawings - if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['Drawings']) && !isset($zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'])) { - foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['Drawings'] as $relId => $drawingXml) { - $drawingFile = array_search($relId, $unparsedLoadedData['sheets'][$sheetCodeName]['drawingOriginalIds']); + if (isset($unparsedSheet['Drawings']) && !isset($zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'])) { + foreach ($unparsedSheet['Drawings'] as $relId => $drawingXml) { + $drawingFile = array_search($relId, $unparsedSheet['drawingOriginalIds']); if ($drawingFile !== false) { //$drawingFile = ltrim($drawingFile, '.'); //$zipContent['xl' . $drawingFile] = $drawingXml; @@ -414,12 +459,15 @@ class Xlsx extends BaseWriter } } } - if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingOriginalIds']) && !isset($zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'])) { + if (isset($unparsedSheet['drawingOriginalIds']) && !isset($zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'])) { $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = ''; } // Add comment relationship parts - $legacy = $unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['legacyDrawing'] ?? null; + /** @var mixed[][] */ + $legacyTemp = $unparsedLoadedData['sheets'] ?? []; + $legacyTemp = $legacyTemp[$this->spreadSheet->getSheet($i)->getCodeName()] ?? []; + $legacy = $legacyTemp['legacyDrawing'] ?? null; if (count($this->spreadSheet->getSheet($i)->getComments()) > 0 || $legacy !== null) { // VML Comments relationships $zipContent['xl/drawings/_rels/vmlDrawing' . ($i + 1) . '.vml.rels'] = $this->getWriterPartRels()->writeVMLDrawingRelationships($this->spreadSheet->getSheet($i)); @@ -442,8 +490,9 @@ class Xlsx extends BaseWriter } // Add unparsed relationship parts - if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['vmlDrawings'])) { - foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['vmlDrawings'] as $vmlDrawing) { + if (isset($unparsedSheet['vmlDrawings'])) { + foreach ($unparsedSheet['vmlDrawings'] as $vmlDrawing) { + /** @var string[] $vmlDrawing */ if (!isset($zipContent[$vmlDrawing['filePath']])) { $zipContent[$vmlDrawing['filePath']] = $vmlDrawing['content']; } @@ -516,6 +565,7 @@ class Xlsx extends BaseWriter $this->zip = ZipStream0::newZipStream($this->fileHandle); + /** @var string[] $zipContent */ $this->addZipFiles($zipContent); // Close file @@ -652,6 +702,7 @@ class Xlsx extends BaseWriter return $this; } + /** @var string[] */ private array $pathNames = []; private function addZipFile(string $path, string $content): void @@ -662,6 +713,7 @@ class Xlsx extends BaseWriter } } + /** @param string[] $zipContent */ private function addZipFiles(array $zipContent): void { foreach ($zipContent as $path => $content) { @@ -768,4 +820,27 @@ class Xlsx extends BaseWriter return $this; } + + /** + * Excel has a nominal width limint of 255 for a column. + * Surprisingly, Xlsx can read and write larger values, + * and the file will appear as desired, + * but the User Interface does not allow you to set the width beyond 255, + * either directly or though auto-fit width. + * Xls sets its own value when the width is beyond 255. + * This method gets whether PhpSpreadsheet should restrict the + * column widths which it writes to the Excel limit, for formats + * which allow it to exceed 255. + */ + public function setRestrictMaxColumnWidth(bool $restrictMaxColumnWidth): self + { + $this->restrictMaxColumnWidth = $restrictMaxColumnWidth; + + return $this; + } + + public function getRestrictMaxColumnWidth(): bool + { + return $this->restrictMaxColumnWidth; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php index afb901f..93db883 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php @@ -13,6 +13,7 @@ use PhpOffice\PhpSpreadsheet\Chart\Properties; use PhpOffice\PhpSpreadsheet\Chart\Title; use PhpOffice\PhpSpreadsheet\Chart\TrendLine; use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Namespaces; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Style\Font; use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException; @@ -96,11 +97,9 @@ class Chart extends WriterPart $objWriter->writeAttribute('val', (string) (int) $chart->getPlotVisibleOnly()); $objWriter->endElement(); - if ($chart->getDisplayBlanksAs() !== '') { - $objWriter->startElement('c:dispBlanksAs'); - $objWriter->writeAttribute('val', $chart->getDisplayBlanksAs()); - $objWriter->endElement(); - } + $objWriter->startElement('c:dispBlanksAs'); + $objWriter->writeAttribute('val', $chart->getDisplayBlanksAs()); + $objWriter->endElement(); $objWriter->startElement('c:showDLblsOverMax'); $objWriter->writeAttribute('val', '0'); @@ -1314,12 +1313,12 @@ class Chart extends WriterPart } if ($trendLineType == TrendLine::TRENDLINE_POLYNOMIAL) { $objWriter->startElement('c:order'); - $objWriter->writeAttribute('val', $order); + $objWriter->writeAttribute('val', "$order"); $objWriter->endElement(); // order } if ($trendLineType == TrendLine::TRENDLINE_MOVING_AVG) { $objWriter->startElement('c:period'); - $objWriter->writeAttribute('val', $period); + $objWriter->writeAttribute('val', "$period"); $objWriter->endElement(); // period } $objWriter->startElement('c:dispRSqr'); @@ -1436,6 +1435,7 @@ class Chart extends WriterPart $objWriter->endElement(); foreach (($plotSeriesLabel->getDataValues() ?? []) as $plotLabelKey => $plotLabelValue) { + /** @var string $plotLabelValue */ $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotLabelKey); @@ -1478,6 +1478,7 @@ class Chart extends WriterPart $objWriter->startElement('c:lvl'); foreach (($plotSeriesValues->getDataValues() ?? []) as $plotSeriesKey => $plotSeriesValue) { + /** @var string[] $plotSeriesValue */ if (isset($plotSeriesValue[$level])) { $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotSeriesKey); @@ -1505,7 +1506,7 @@ class Chart extends WriterPart $count = $plotSeriesValues->getPointCount(); $source = $plotSeriesValues->getDataSource(); $values = $plotSeriesValues->getDataValues(); - if ($count > 1 || ($count === 1 && is_array($values) && array_key_exists(0, $values) && "=$source" !== (string) $values[0])) { + if ($count > 1 || ($count === 1 && is_array($values) && array_key_exists(0, $values) && "=$source" !== StringHelper::convertToString($values[0], false))) { $objWriter->startElement('c:' . $dataType . 'Cache'); if (($groupType != DataSeries::TYPE_PIECHART) && ($groupType != DataSeries::TYPE_PIECHART_3D) && ($groupType != DataSeries::TYPE_DONUTCHART)) { @@ -1520,6 +1521,7 @@ class Chart extends WriterPart $objWriter->writeAttribute('val', (string) $plotSeriesValues->getPointCount()); $objWriter->endElement(); + /** @var array */ $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) { foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Comments.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Comments.php index f42c242..5d2bc8e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Comments.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Comments.php @@ -77,14 +77,14 @@ class Comments extends WriterPart * * @param string $cellReference Cell reference * @param Comment $comment Comment - * @param array $authors Array of authors + * @param array $authors Array of authors */ private function writeComment(XMLWriter $objWriter, string $cellReference, Comment $comment, array $authors): void { // comment $objWriter->startElement('comment'); $objWriter->writeAttribute('ref', $cellReference); - $objWriter->writeAttribute('authorId', $authors[$comment->getAuthor()]); + $objWriter->writeAttribute('authorId', (string) $authors[$comment->getAuthor()]); // text $objWriter->startElement('text'); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php index 42224df..16c7bb9 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php @@ -98,6 +98,7 @@ class ContentTypes extends WriterPart } // Add worksheet relationship content types + /** @var mixed[][][][] */ $unparsedLoadedData = $spreadsheet->getUnparsedLoadedData(); $chart = 1; for ($i = 0; $i < $sheetCount; ++$i) { @@ -158,6 +159,7 @@ class ContentTypes extends WriterPart if ($spreadsheet->hasRibbonBinObjects()) { // Some additional objects in the ribbon ? // we need to write "Extension" but not already write for media content + /** @var string[] */ $tabRibbonTypes = array_diff($spreadsheet->getRibbonBinObjects('types') ?? [], array_keys($aMediaContentTypes)); foreach ($tabRibbonTypes as $aRibbonType) { $mimeType = 'image/.' . $aRibbonType; //we wrote $mimeType like customUI Editor @@ -203,14 +205,18 @@ class ContentTypes extends WriterPart // unparsed defaults if (isset($unparsedLoadedData['default_content_types'])) { - foreach ($unparsedLoadedData['default_content_types'] as $extName => $contentType) { + /** @var array */ + $unparsedDefault = $unparsedLoadedData['default_content_types']; + foreach ($unparsedDefault as $extName => $contentType) { $this->writeDefaultContentType($objWriter, $extName, $contentType); } } // unparsed overrides if (isset($unparsedLoadedData['override_content_types'])) { - foreach ($unparsedLoadedData['override_content_types'] as $partName => $overrideType) { + /** @var array */ + $unparsedOverride = $unparsedLoadedData['override_content_types']; + foreach ($unparsedOverride as $partName => $overrideType) { $this->writeOverrideContentType($objWriter, $partName, $overrideType); } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php index f8a70ea..000b2e4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php @@ -116,7 +116,7 @@ class DefinedNames $range[0] = Coordinate::absoluteCoordinate($range[0] ?? ''); if (count($range) > 1) { - $range[1] = Coordinate::absoluteCoordinate($range[1]); + $range[1] = Coordinate::absoluteCoordinate($range[1] ?? ''); } $range = implode(':', $range); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php index ed441b1..887b436 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php @@ -68,6 +68,7 @@ class Drawing extends WriterPart } // unparsed AlternateContent + /** @var string[][][][] */ $unparsedLoadedData = $worksheet->getParentOrThrow()->getUnparsedLoadedData(); if (isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingAlternateContents'])) { foreach ($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingAlternateContents'] as $drawingAlternateContent) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/FunctionPrefix.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/FunctionPrefix.php index 31e1e3e..50d0e5f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/FunctionPrefix.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/FunctionPrefix.php @@ -66,6 +66,8 @@ class FunctionPrefix . '|var[.]s' . '|weibull[.]dist' . '|z[.]test' + // probably added with Excel 2010 but not properly documented + . '|base' // functions added with Excel 2013 . '|acot' . '|acoth' @@ -216,6 +218,18 @@ class FunctionPrefix */ public static function addFunctionPrefixStripEquals(string $functionString): string { + $functionString = Preg::replace( + [ + '/\b(CEILING|FLOOR)[.]ODS\s*[(]/', + '/\b(CEILING|FLOOR)[.]XCL\s*[(]/', + ], + [ + '$1.MATH(', + '$1(', + ], + $functionString + ); + return self::addFunctionPrefix(substr($functionString, 1)); } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php index ceb7811..a913767 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php @@ -176,6 +176,7 @@ class Rels extends WriterPart * * @param bool $includeCharts Flag indicating if we should write charts * @param int $tableRef Table ID + * @param string[] $zipContent * * @return string XML Output */ @@ -198,6 +199,7 @@ class Rels extends WriterPart // Write drawing relationships? $drawingOriginalIds = []; + /** @var string[][][][] */ $unparsedLoadedData = $worksheet->getParentOrThrow()->getUnparsedLoadedData(); if (isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingOriginalIds'])) { $drawingOriginalIds = $unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingOriginalIds']; @@ -217,7 +219,7 @@ class Rels extends WriterPart // (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Worksheet::writeDrawings) reset($drawingOriginalIds); $relPath = key($drawingOriginalIds); - if (isset($drawingOriginalIds[$relPath])) { + if (isset($relPath, $drawingOriginalIds[$relPath])) { $rId = (int) (substr($drawingOriginalIds[$relPath], 3)); } @@ -314,6 +316,7 @@ class Rels extends WriterPart private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet, XMLWriter $objWriter, string $relationship, string $type): void { + /** @var mixed[][][][] */ $unparsedLoadedData = $worksheet->getParentOrThrow()->getUnparsedLoadedData(); if (!isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()][$relationship])) { return; @@ -321,6 +324,7 @@ class Rels extends WriterPart foreach ($unparsedLoadedData['sheets'][$worksheet->getCodeName()][$relationship] as $rId => $value) { if (!str_starts_with($rId, '_headerfooter_vml')) { + /** @var string[] $value */ $this->writeRelationship( $objWriter, $rId, diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/RelsRibbon.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/RelsRibbon.php index 93c9777..9bedd93 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/RelsRibbon.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/RelsRibbon.php @@ -35,6 +35,7 @@ class RelsRibbon extends WriterPart $objWriter->startElement('Relationship'); $objWriter->writeAttribute('Id', $aId); $objWriter->writeAttribute('Type', Namespaces::IMAGE); + /** @var string $aTarget */ $objWriter->writeAttribute('Target', $aTarget); $objWriter->endElement(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php index 705e47f..37a8e36 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php @@ -10,6 +10,7 @@ use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\RichText\Run; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; +use PhpOffice\PhpSpreadsheet\Style\Font; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet as ActualWorksheet; class StringTable extends WriterPart @@ -24,6 +25,7 @@ class StringTable extends WriterPart public function createStringTable(ActualWorksheet $worksheet, ?array $existingTable = null): array { // Create string lookup table + /** @var string[] */ $aStringTable = $existingTable ?? []; // Fill index array @@ -33,6 +35,7 @@ class StringTable extends WriterPart foreach ($worksheet->getCellCollection()->getCoordinates() as $coordinate) { /** @var Cell $cell */ $cell = $worksheet->getCellCollection()->get($coordinate); + /** @var null|int|RichText|string */ $cellValue = $cell->getValue(); if ( !is_object($cellValue) @@ -51,6 +54,7 @@ class StringTable extends WriterPart $aFlippedStringTable[$cellValue->getHashCode()] = true; } } + /** @var string[] $aStringTable */ return $aStringTable; } @@ -109,7 +113,7 @@ class StringTable extends WriterPart * * @param ?string $prefix Optional Namespace prefix */ - public function writeRichText(XMLWriter $objWriter, RichText $richText, ?string $prefix = null): void + public function writeRichText(XMLWriter $objWriter, RichText $richText, ?string $prefix = null, ?Font $defaultFont = null): void { if ($prefix !== null) { $prefix .= ':'; @@ -120,35 +124,36 @@ class StringTable extends WriterPart foreach ($elements as $element) { // r $objWriter->startElement($prefix . 'r'); + $font = ($element instanceof Run) ? $element->getFont() : $defaultFont; // rPr - if ($element instanceof Run && $element->getFont() !== null) { + if ($font !== null) { // rPr $objWriter->startElement($prefix . 'rPr'); // rFont - if ($element->getFont()->getName() !== null) { + if ($font->getName() !== null) { $objWriter->startElement($prefix . 'rFont'); - $objWriter->writeAttribute('val', $element->getFont()->getName()); + $objWriter->writeAttribute('val', $font->getName()); $objWriter->endElement(); } // Bold $objWriter->startElement($prefix . 'b'); - $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); + $objWriter->writeAttribute('val', ($font->getBold() ? 'true' : 'false')); $objWriter->endElement(); // Italic $objWriter->startElement($prefix . 'i'); - $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); + $objWriter->writeAttribute('val', ($font->getItalic() ? 'true' : 'false')); $objWriter->endElement(); // Superscript / subscript - if ($element->getFont()->getSuperscript() || $element->getFont()->getSubscript()) { + if ($font->getSuperscript() || $font->getSubscript()) { $objWriter->startElement($prefix . 'vertAlign'); - if ($element->getFont()->getSuperscript()) { + if ($font->getSuperscript()) { $objWriter->writeAttribute('val', 'superscript'); - } elseif ($element->getFont()->getSubscript()) { + } elseif ($font->getSubscript()) { $objWriter->writeAttribute('val', 'subscript'); } $objWriter->endElement(); @@ -156,27 +161,27 @@ class StringTable extends WriterPart // Strikethrough $objWriter->startElement($prefix . 'strike'); - $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); + $objWriter->writeAttribute('val', ($font->getStrikethrough() ? 'true' : 'false')); $objWriter->endElement(); // Color - if ($element->getFont()->getColor()->getARGB() !== null) { + if ($font->getColor()->getARGB() !== null) { $objWriter->startElement($prefix . 'color'); - $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); + $objWriter->writeAttribute('rgb', $font->getColor()->getARGB()); $objWriter->endElement(); } // Size - if ($element->getFont()->getSize() !== null) { + if ($font->getSize() !== null) { $objWriter->startElement($prefix . 'sz'); - $objWriter->writeAttribute('val', (string) $element->getFont()->getSize()); + $objWriter->writeAttribute('val', (string) $font->getSize()); $objWriter->endElement(); } // Underline - if ($element->getFont()->getUnderline() !== null) { + if ($font->getUnderline() !== null) { $objWriter->startElement($prefix . 'u'); - $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); + $objWriter->writeAttribute('val', $font->getUnderline()); $objWriter->endElement(); } @@ -301,7 +306,7 @@ class StringTable extends WriterPart $objWriter->writeAttribute('val', $value); $alpha = $underlineColor->getAlpha(); if (is_numeric($alpha)) { - $objWriter->startElement('a:alpha'); + $objWriter->startElement($prefix . 'alpha'); $objWriter->writeAttribute('val', ChartColor::alphaToXml((int) $alpha)); $objWriter->endElement(); } @@ -317,7 +322,9 @@ class StringTable extends WriterPart /** * Flip string table (for index searching). * - * @param array $stringTable Stringtable + * @param array $stringTable Stringtable + * + * @return array */ public function flipStringTable(array $stringTable): array { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Style.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Style.php index 8b09dd6..9b79301 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Style.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Style.php @@ -37,7 +37,6 @@ class Style extends WriterPart // styleSheet $objWriter->startElement('styleSheet'); - $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeAttribute('xmlns', Namespaces::MAIN); // numFmts @@ -59,7 +58,7 @@ class Style extends WriterPart for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { $thisfont = $this->getParentWriter()->getFontHashTable()->getByIndex($i); if ($thisfont !== null) { - $this->writeFont($objWriter, $thisfont); + $this->writeFont($objWriter, $thisfont, $spreadsheet); } } @@ -145,7 +144,7 @@ class Style extends WriterPart /** @var ?Conditional */ $thisstyle = $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i); if ($thisstyle !== null) { - $this->writeCellStyleDxf($objWriter, $thisstyle->getStyle()); + $this->writeCellStyleDxf($objWriter, $thisstyle->getStyle(), $spreadsheet); } } @@ -273,6 +272,9 @@ class Style extends WriterPart $objWriter->endElement(); } + /** + * @param-out true $fontStarted + */ private function startFont(XMLWriter $objWriter, bool &$fontStarted): void { if (!$fontStarted) { @@ -284,7 +286,7 @@ class Style extends WriterPart /** * Write Font. */ - private function writeFont(XMLWriter $objWriter, Font $font): void + private function writeFont(XMLWriter $objWriter, Font $font, Spreadsheet $spreadsheet): void { $fontStarted = false; // font @@ -347,7 +349,17 @@ class Style extends WriterPart } // Foreground color - if ($font->getColor()->getARGB() !== null) { + if ($font->getAutoColor()) { + $this->startFont($objWriter, $fontStarted); + $objWriter->startElement('auto'); + $objWriter->writeAttribute('val', '1'); + $objWriter->endElement(); + } elseif ($font->getColor()->getTheme() >= 0) { + $this->startFont($objWriter, $fontStarted); + $objWriter->startElement('color'); + $objWriter->writeAttribute('theme', (string) $font->getColor()->getTheme()); + $objWriter->endElement(); + } elseif ($font->getColor()->getARGB() !== null) { $this->startFont($objWriter, $fontStarted); $objWriter->startElement('color'); $objWriter->writeAttribute('rgb', $font->getColor()->getARGB()); @@ -360,6 +372,12 @@ class Style extends WriterPart $objWriter->startElement('name'); $objWriter->writeAttribute('val', $font->getName()); $objWriter->endElement(); + $charset = $spreadsheet->getFontCharset($font->getName()); + if ($charset >= 0 && $charset <= 255) { + $objWriter->startElement('charset'); + $objWriter->writeAttribute('val', "$charset"); + $objWriter->endElement(); + } } if (!empty($font->getScheme())) { @@ -499,13 +517,13 @@ class Style extends WriterPart /** * Write Cell Style Dxf. */ - private function writeCellStyleDxf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $style): void + private function writeCellStyleDxf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $style, Spreadsheet $spreadsheet): void { // dxf $objWriter->startElement('dxf'); // font - $this->writeFont($objWriter, $style->getFont()); + $this->writeFont($objWriter, $style->getFont(), $spreadsheet); // numFmt $this->writeNumFmt($objWriter, $style->getNumberFormat()); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Table.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Table.php index f88b2a0..4a1364e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Table.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Table.php @@ -34,7 +34,6 @@ class Table extends WriterPart $range = $table->getRange(); $objWriter->startElement('table'); - $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeAttribute('xmlns', Namespaces::MAIN); $objWriter->writeAttribute('id', (string) $tableRef); $objWriter->writeAttribute('name', $name); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php index c907e10..b9aa9b6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php @@ -33,7 +33,6 @@ class Workbook extends WriterPart // workbook $objWriter->startElement('workbook'); - $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeAttribute('xmlns', Namespaces::MAIN); $objWriter->writeAttribute('xmlns:r', Namespaces::SCHEMA_OFFICE_DOCUMENT); @@ -126,18 +125,35 @@ class Workbook extends WriterPart */ private function writeWorkbookProtection(XMLWriter $objWriter, Spreadsheet $spreadsheet): void { - if ($spreadsheet->getSecurity()->isSecurityEnabled()) { + $security = $spreadsheet->getSecurity(); + if ($security->isSecurityEnabled()) { $objWriter->startElement('workbookProtection'); - $objWriter->writeAttribute('lockRevision', ($spreadsheet->getSecurity()->getLockRevision() ? 'true' : 'false')); - $objWriter->writeAttribute('lockStructure', ($spreadsheet->getSecurity()->getLockStructure() ? 'true' : 'false')); - $objWriter->writeAttribute('lockWindows', ($spreadsheet->getSecurity()->getLockWindows() ? 'true' : 'false')); + $objWriter->writeAttribute('lockRevision', ($security->getLockRevision() ? 'true' : 'false')); + $objWriter->writeAttribute('lockStructure', ($security->getLockStructure() ? 'true' : 'false')); + $objWriter->writeAttribute('lockWindows', ($security->getLockWindows() ? 'true' : 'false')); - if ($spreadsheet->getSecurity()->getRevisionsPassword() != '') { - $objWriter->writeAttribute('revisionsPassword', $spreadsheet->getSecurity()->getRevisionsPassword()); + if ($security->getRevisionsPassword() !== '') { + $objWriter->writeAttribute('revisionsPassword', $security->getRevisionsPassword()); + } else { + $hashValue = $security->getRevisionsHashValue(); + if ($hashValue !== '') { + $objWriter->writeAttribute('revisionsAlgorithmName', $security->getRevisionsAlgorithmName()); + $objWriter->writeAttribute('revisionsHashValue', $hashValue); + $objWriter->writeAttribute('revisionsSaltValue', $security->getRevisionsSaltValue()); + $objWriter->writeAttribute('revisionsSpinCount', (string) $security->getRevisionsSpinCount()); + } } - if ($spreadsheet->getSecurity()->getWorkbookPassword() != '') { - $objWriter->writeAttribute('workbookPassword', $spreadsheet->getSecurity()->getWorkbookPassword()); + if ($security->getWorkbookPassword() !== '') { + $objWriter->writeAttribute('workbookPassword', $security->getWorkbookPassword()); + } else { + $hashValue = $security->getWorkbookHashValue(); + if ($hashValue !== '') { + $objWriter->writeAttribute('workbookAlgorithmName', $security->getWorkbookAlgorithmName()); + $objWriter->writeAttribute('workbookHashValue', $hashValue); + $objWriter->writeAttribute('workbookSaltValue', $security->getWorkbookSaltValue()); + $objWriter->writeAttribute('workbookSpinCount', (string) $security->getWorkbookSpinCount()); + } } $objWriter->endElement(); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index c95ea60..5e445f6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -10,13 +10,14 @@ use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Namespaces; use PhpOffice\PhpSpreadsheet\RichText\RichText; -use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalColorScale; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension; +use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalIconSet; +use PhpOffice\PhpSpreadsheet\Style\Font; use PhpOffice\PhpSpreadsheet\Worksheet\RowDimension; use PhpOffice\PhpSpreadsheet\Worksheet\SheetView; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet as PhpspreadsheetWorksheet; @@ -27,6 +28,8 @@ class Worksheet extends WriterPart private string $formula = ''; + private string $formulaRange = ''; + private string $twoDigitTextYear = ''; private string $evalError = ''; @@ -35,6 +38,8 @@ class Worksheet extends WriterPart private bool $useDynamicArrays = false; + private bool $restrictMaxColumnWidth = false; + /** * Write worksheet to XML format. * @@ -50,6 +55,7 @@ class Worksheet extends WriterPart $worksheet->calculateArrays($this->getParentWriter()->getPreCalculateFormulas()); $this->numberStoredAsText = ''; $this->formula = ''; + $this->formulaRange = ''; $this->twoDigitTextYear = ''; $this->evalError = ''; // Create XML writer @@ -59,13 +65,13 @@ class Worksheet extends WriterPart } else { $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); } + $this->restrictMaxColumnWidth = $this->getParentWriter()->getRestrictMaxColumnWidth(); // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Worksheet $objWriter->startElement('worksheet'); - $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeAttribute('xmlns', Namespaces::MAIN); $objWriter->writeAttribute('xmlns:r', Namespaces::SCHEMA_OFFICE_DOCUMENT); @@ -180,6 +186,7 @@ class Worksheet extends WriterPart $started = false; $this->writeIgnoredError($objWriter, $started, 'numberStoredAsText', $this->numberStoredAsText); $this->writeIgnoredError($objWriter, $started, 'formula', $this->formula); + $this->writeIgnoredError($objWriter, $started, 'formulaRange', $this->formulaRange); $this->writeIgnoredError($objWriter, $started, 'twoDigitTextYear', $this->twoDigitTextYear); $this->writeIgnoredError($objWriter, $started, 'evalError', $this->evalError); if ($started) { @@ -432,7 +439,7 @@ class Worksheet extends WriterPart // Default column width if ($worksheet->getDefaultColumnDimension()->getWidth() >= 0) { - $objWriter->writeAttribute('defaultColWidth', StringHelper::formatNumber($worksheet->getDefaultColumnDimension()->getWidth())); + $objWriter->writeAttribute('defaultColWidth', StringHelper::formatNumber($worksheet->getDefaultColumnDimension()->getWidthForOutput($this->restrictMaxColumnWidth))); } // Outline level - row @@ -479,7 +486,7 @@ class Worksheet extends WriterPart $objWriter->writeAttribute('width', '9.10'); } else { // Width set - $objWriter->writeAttribute('width', StringHelper::formatNumber($colDimension->getWidth())); + $objWriter->writeAttribute('width', StringHelper::formatNumber($colDimension->getWidthForOutput($this->restrictMaxColumnWidth))); } // Column visibility @@ -684,6 +691,7 @@ class Worksheet extends WriterPart $objWriter->startElementNs($prefix, 'dataBar', null); $dataBar = $ruleExtension->getDataBarExt(); foreach ($dataBar->getXmlAttributes() as $attrKey => $val) { + /** @var string $val */ $objWriter->writeAttribute($attrKey, $val); } $minCfvo = $dataBar->getMinimumConditionalFormatValueObject(); @@ -709,6 +717,7 @@ class Worksheet extends WriterPart } foreach ($dataBar->getXmlElements() as $elmKey => $elmAttr) { + /** @var string[] $elmAttr */ $objWriter->startElementNs($prefix, $elmKey, null); foreach ($elmAttr as $attrKey => $attrVal) { $objWriter->writeAttribute($attrKey, $attrVal); @@ -858,6 +867,47 @@ class Worksheet extends WriterPart } } + private function writeIconSetElements(XMLWriter $objWriter, ?ConditionalIconSet $iconSet): void + { + if ($iconSet === null) { + return; + } + + $objWriter->startElement('iconSet'); + if ($iconSet->getIconSetType() !== null) { + $objWriter->writeAttribute('iconSet', $iconSet->getIconSetType()->value); + } + foreach ( + [ + 'reverse' => $iconSet->getReverse(), + 'showValue' => $iconSet->getShowValue(), + 'custom' => $iconSet->getCustom(), + ] as $attr => $value + ) { + self::writeAttributeIf($objWriter, $value !== null, $attr, $value ? '1' : '0'); + } + + foreach ($iconSet->getCfvos() as $cfvo) { + $objWriter->startElement('cfvo'); + $objWriter->writeAttribute('type', $cfvo->getType()); + self::writeAttributeIf( + $objWriter, + $cfvo->getValue() !== null, + 'val', + (string) $cfvo->getValue(), + ); + self::writeAttributeIf( + $objWriter, + $cfvo->getGreaterThanOrEqual() !== null, + 'gte', + $cfvo->getGreaterThanOrEqual() ? '1' : '0', + ); + $objWriter->endElement(); // end cfvo + } + + $objWriter->endElement(); // end iconSet + } + /** * Write ConditionalFormatting. */ @@ -892,6 +942,7 @@ class Worksheet extends WriterPart $objWriter, ($conditional->getConditionType() !== Conditional::CONDITION_COLORSCALE && $conditional->getConditionType() !== Conditional::CONDITION_DATABAR + && $conditional->getConditionType() !== Conditional::CONDITION_ICONSET && $conditional->getNoFormatSet() === false), 'dxfId', (string) $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) @@ -928,6 +979,8 @@ class Worksheet extends WriterPart self::writeTimePeriodCondElements($objWriter, $conditional, $topLeftCell); } elseif ($conditional->getConditionType() === Conditional::CONDITION_COLORSCALE) { self::writeColorScaleElements($objWriter, $conditional->getColorScale()); + } elseif ($conditional->getConditionType() === Conditional::CONDITION_ICONSET) { + self::writeIconSetElements($objWriter, $conditional->getIconSet()); } else { self::writeOtherCondElements($objWriter, $conditional, $topLeftCell); } @@ -1198,6 +1251,7 @@ class Worksheet extends WriterPart } $objWriter->writeAttribute('pageOrder', $worksheet->getPageSetup()->getPageOrder()); + /** @var string[][][] */ $getUnparsedLoadedData = $worksheet->getParentOrThrow()->getUnparsedLoadedData(); if (isset($getUnparsedLoadedData['sheets'][$worksheet->getCodeName()]['pageSetupRelId'])) { $objWriter->writeAttribute('r:id', $getUnparsedLoadedData['sheets'][$worksheet->getCodeName()]['pageSetupRelId']); @@ -1269,6 +1323,9 @@ class Worksheet extends WriterPart $rowBreakMax = $break->getMaxColOrRow(); if ($rowBreakMax >= 0) { $objWriter->writeAttribute('max', "$rowBreakMax"); + } elseif ($worksheet->getPageSetup()->getPrintArea() !== '') { + $maxCol = Coordinate::columnIndexFromString($worksheet->getHighestColumn()); + $objWriter->writeAttribute('max', "$maxCol"); } $objWriter->endElement(); } @@ -1288,6 +1345,13 @@ class Worksheet extends WriterPart $objWriter->startElement('brk'); $objWriter->writeAttribute('id', (string) ((int) $coords[0] - 1)); $objWriter->writeAttribute('man', '1'); + $colBreakMax = $break->getMaxColOrRow(); + if ($colBreakMax >= 0) { + $objWriter->writeAttribute('max', "$colBreakMax"); + } elseif ($worksheet->getPageSetup()->getPrintArea() !== '') { + $maxRow = $worksheet->getHighestRow(); + $objWriter->writeAttribute('max', "$maxRow"); + } $objWriter->endElement(); } @@ -1334,6 +1398,16 @@ class Worksheet extends WriterPart } } + $customHeightNeeded = false; + if ($worksheet->getDefaultRowDimension()->getRowHeight() >= 0) { + foreach ($worksheet->getRowDimensions() as $rowDimension) { + if ($rowDimension->getCustomFormat()) { + $customHeightNeeded = true; + + break; + } + } + } $currentRow = 0; $emptyDimension = new RowDimension(); while ($currentRow++ < $highestRow) { @@ -1347,6 +1421,7 @@ class Worksheet extends WriterPart if ($writeCurrentRow) { // Start a new row + $customFormatWritten = false; $objWriter->startElement('row'); $objWriter->writeAttribute('r', "$currentRow"); $objWriter->writeAttribute('spans', '1:' . $colCount); @@ -1355,6 +1430,12 @@ class Worksheet extends WriterPart if ($rowDimension->getRowHeight() >= 0) { $objWriter->writeAttribute('customHeight', '1'); $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight())); + } elseif ($rowDimension->getCustomFormat()) { + $objWriter->writeAttribute('customFormat', '1'); + $customFormatWritten = true; + $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight())); + } elseif ($customHeightNeeded) { + $objWriter->writeAttribute('customHeight', '1'); } // Row visibility @@ -1375,7 +1456,9 @@ class Worksheet extends WriterPart // Style if ($rowDimension->getXfIndex() !== null) { $objWriter->writeAttribute('s', (string) $rowDimension->getXfIndex()); - $objWriter->writeAttribute('customFormat', '1'); + if (!$customFormatWritten) { + $objWriter->writeAttribute('customFormat', '1'); + } } // Write cells @@ -1392,6 +1475,9 @@ class Worksheet extends WriterPart if ($worksheet->getCell($coord)->getIgnoredErrors()->getFormula()) { $this->formula .= " $coord"; } + if ($worksheet->getCell($coord)->getIgnoredErrors()->getFormulaRange()) { + $this->formulaRange .= " $coord"; + } if ($worksheet->getCell($coord)->getIgnoredErrors()->getTwoDigitTextYear()) { $this->twoDigitTextYear .= " $coord"; } @@ -1411,19 +1497,26 @@ class Worksheet extends WriterPart $objWriter->endElement(); } - private function writeCellInlineStr(XMLWriter $objWriter, string $mappedType, RichText|string $cellValue): void + private function writeCellInlineStr(XMLWriter $objWriter, string $mappedType, RichText|string $cellValue, ?Font $font): void { $objWriter->writeAttribute('t', $mappedType); if (!$cellValue instanceof RichText) { $objWriter->startElement('is'); - $objWriter->writeElement( - 't', - StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue, Settings::htmlEntityFlags())) + $objWriter->startElement('t'); + $textToWrite = StringHelper::controlCharacterPHP2OOXML( + $cellValue ); - $objWriter->endElement(); + if ($textToWrite !== trim($textToWrite)) { + $objWriter->writeAttribute('xml:space', 'preserve'); + } + $objWriter->writeRawData($textToWrite); + $objWriter->endElement(); // t + $objWriter->endElement(); // is } else { $objWriter->startElement('is'); - $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue); + $this->getParentWriter() + ->getWriterPartstringtable() + ->writeRichText($objWriter, $cellValue, null, $font); $objWriter->endElement(); } } @@ -1443,15 +1536,11 @@ class Worksheet extends WriterPart private function writeCellNumeric(XMLWriter $objWriter, float|int $cellValue): void { - //force a decimal to be written if the type is float - if (is_float($cellValue)) { - // force point as decimal separator in case current locale uses comma - $cellValue = str_replace(',', '.', (string) $cellValue); - if (!str_contains($cellValue, '.')) { - $cellValue = $cellValue . '.0'; - } + $result = StringHelper::convertToString($cellValue); + if (is_float($cellValue) && !str_contains($result, '.')) { + $result .= '.0'; } - $objWriter->writeElement('v', "$cellValue"); + $objWriter->writeElement('v', $result); } private function writeCellBoolean(XMLWriter $objWriter, string $mappedType, bool $cellValue): void @@ -1544,8 +1633,8 @@ class Worksheet extends WriterPart self::writeElementIf( $objWriter, $this->getParentWriter()->getOffice2003Compatibility() === false - && $this->getParentWriter()->getPreCalculateFormulas() - && $calculatedValue !== null, + && $this->getParentWriter()->getPreCalculateFormulas() + && $calculatedValue !== null, 'v', (!is_array($calculatedValue) && !str_starts_with($calculatedValueString, '#')) ? StringHelper::formatNumber($calculatedValueString) : '0' @@ -1592,12 +1681,19 @@ class Worksheet extends WriterPart if (empty($xfi) && !$writeValue) { return; } + $styleArray = $this->getParentWriter() + ->getSpreadsheet() + ->getCellXfCollection(); + $font = $styleArray[$xfi] ?? null; + if ($font !== null) { + $font = $font->getFont(); + } $objWriter->startElement('c'); $objWriter->writeAttribute('r', $cellAddress); $mappedType = $pCell->getDataType(); if ($mappedType === DataType::TYPE_FORMULA) { if ($this->useDynamicArrays) { - if (preg_match(PhpspreadsheetWorksheet::FUNCTION_LIKE_GROUPBY, $cellValue) === 1) { + if (preg_match(PhpspreadsheetWorksheet::FUNCTION_LIKE_GROUPBY, $cellValueString) === 1) { $tempCalc = []; } else { $tempCalc = $pCell->getCalculatedValue(); @@ -1622,7 +1718,7 @@ class Worksheet extends WriterPart case 'inlinestr': // Inline string /** @var RichText|string */ $richText = $cellValue; - $this->writeCellInlineStr($objWriter, $mappedType, $richText); + $this->writeCellInlineStr($objWriter, $mappedType, $richText, $font); break; case 's': // String @@ -1657,6 +1753,7 @@ class Worksheet extends WriterPart */ private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet, bool $includeCharts = false): void { + /** @var mixed[][][][] */ $unparsedLoadedData = $worksheet->getParentOrThrow()->getUnparsedLoadedData(); $hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingOriginalIds']); $chartCount = ($includeCharts) ? $worksheet->getChartCollection()->count() : 0; @@ -1675,6 +1772,7 @@ class Worksheet extends WriterPart $rId = reset($drawingOriginalIds); } + /** @var string $rId */ $objWriter->writeAttribute('r:id', $rId); $objWriter->endElement(); } @@ -1685,6 +1783,7 @@ class Worksheet extends WriterPart private function writeLegacyDrawing(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void { // If sheet contains comments, add the relationships + /** @var mixed[][][][] */ $unparsedLoadedData = $worksheet->getParentOrThrow()->getUnparsedLoadedData(); if (count($worksheet->getComments()) > 0 || isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['legacyDrawing'])) { $objWriter->startElement('legacyDrawing'); @@ -1708,11 +1807,12 @@ class Worksheet extends WriterPart private function writeAlternateContent(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void { - if (empty($worksheet->getParentOrThrow()->getUnparsedLoadedData()['sheets'][$worksheet->getCodeName()]['AlternateContents'])) { - return; - } + /** @var string[][][] */ + $unparsedSheet = $worksheet->getParentOrThrow()->getUnparsedLoadedData()['sheets'] ?? []; + $unparsedSheet = $unparsedSheet[$worksheet->getCodeName()] ?? []; + $unparsedSheet = $unparsedSheet['AlternateContents'] ?? []; - foreach ($worksheet->getParentOrThrow()->getUnparsedLoadedData()['sheets'][$worksheet->getCodeName()]['AlternateContents'] as $alternateContent) { + foreach ($unparsedSheet as $alternateContent) { $objWriter->writeRaw($alternateContent); } }