276 lines
12 KiB
JavaScript
276 lines
12 KiB
JavaScript
// ==UserScript==
|
|
// @name Idea Invoice Famica
|
|
// @namespace http://tampermonkey.net/
|
|
// @version 0.2
|
|
// @description Rozszerza funkcjonalność faktur IdeaERP o dodawanie numeru EORI i ulepszone drukowanie/generowanie PDF dla faktur Famica Ltd.
|
|
// @author You
|
|
// @match https://emma.ideaerp.pl/my/invoices*
|
|
// @icon https://emma.ideaerp.pl/web/image/res.company/1/favicon/
|
|
// @downloadURL https://n8n.emma.net.pl/webhook/invoice-famica
|
|
// @updateURL https://n8n.emma.net.pl/webhook/invoice-famica
|
|
// @grant none
|
|
// ==/UserScript==
|
|
|
|
/**
|
|
* IDEA INVOICE FAMICA - Skrypt Rozszerzający Przetwarzanie Faktur
|
|
*
|
|
* Ten skrypt użytkownika Tampermonkey rozszerza interfejs faktur IdeaERP poprzez
|
|
* dodanie trzech niestandardowych przycisków usprawniających workflow przetwarzania faktur.
|
|
*
|
|
* FUNKCJE:
|
|
* - Dodaje numer EORI (GB174521806000) do informacji o nabywcy na fakturach
|
|
* - Ulepszone drukowanie z prawidłową widocznością nagłówków tabel i cieniowania
|
|
* - Funkcjonalność generowania PDF z zachowaniem formatowania
|
|
*
|
|
* SZCZEGÓŁY TECHNICZNE:
|
|
* - Działa w systemie wyświetlania faktur opartym na iframe
|
|
* - Używa wstrzykiwania CSS do wymuszenia dostosowania kolorów przy drukowaniu
|
|
* - Implementuje obsługę MediaQueryList kompatybilną z różnymi przeglądarkami
|
|
* - Zapobiega duplikowaniu przycisków poprzez znaczniki dataset
|
|
*
|
|
* SPOSÓB UŻYCIA:
|
|
* 1. "Dodaj EORI" - Dodaje numer EORI do sekcji nabywcy na fakturze
|
|
* 2. "Wydrukuj z EORI" - Otwiera okno drukowania z ulepszonym formatowaniem
|
|
* 3. "Pobierz z EORI" - Prowadzi użytkownika przez zapisanie faktury jako PDF z formatowaniem
|
|
*
|
|
* HISTORIA ZMIAN:
|
|
* v0.2 (2025-09-24)
|
|
* - Dodano ulepszoną funkcjonalność drukowania z poprawkami widoczności nagłówków tabel
|
|
* - Zaimplementowano zachowanie cieniowania wierszy w wydruku
|
|
* - Dodano funkcjonalność pobierania PDF z instrukcją dla użytkownika
|
|
* - Naprawiono problemy kompatybilności MediaQueryList między przeglądarkami
|
|
* - Ulepszona obsługa błędów i mechanizmy czyszczenia
|
|
*
|
|
* v0.1 (2025-09-24)
|
|
* - Pierwsze wydanie z podstawową funkcjonalnością dodawania EORI
|
|
* - Podstawowe tworzenie przycisków i manipulacja zawartością iframe
|
|
* - Implementacja MutationObserver do wykrywania dynamicznej zawartości
|
|
*/
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
function addButtons() {
|
|
const targetDivs = document.querySelectorAll('.o_download_pdf.btn-toolbar');
|
|
|
|
targetDivs.forEach(targetDiv => {
|
|
// Check if buttons are already added
|
|
if (targetDiv.dataset.customButtonsAdded) {
|
|
return;
|
|
}
|
|
|
|
// Create "Dodaj EORI" button
|
|
const eoriButtonGroup = document.createElement('div');
|
|
eoriButtonGroup.className = 'btn-group flex-grow-1 mr-1 mb-1';
|
|
const eoriButton = document.createElement('a');
|
|
eoriButton.className = 'btn btn-secondary btn-block';
|
|
eoriButton.href = '#';
|
|
eoriButton.innerHTML = '<i class="fa fa-plus"></i> Dodaj EORI';
|
|
eoriButton.onclick = function(e) {
|
|
e.preventDefault();
|
|
|
|
const iframe = document.getElementById('invoice_html');
|
|
if (!iframe || !iframe.contentWindow) {
|
|
alert('Ramka z fakturą nie została znaleziona.');
|
|
return false;
|
|
}
|
|
|
|
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
|
const nabywcaDiv = iframeDoc.querySelector('.i_nabywca.col-4');
|
|
|
|
if (!nabywcaDiv) {
|
|
alert('Sekcja nabywcy nie została znaleziona w fakturze.');
|
|
return false;
|
|
}
|
|
|
|
// Check if EORI is already added
|
|
if (iframeDoc.querySelector('.eori-number')) {
|
|
alert('Numer EORI został już dodany.');
|
|
return false;
|
|
}
|
|
|
|
const br = iframeDoc.createElement('br');
|
|
const eoriTextNode = iframeDoc.createTextNode('EORI Number: ');
|
|
const eoriSpan = iframeDoc.createElement('span');
|
|
eoriSpan.className = 'eori-number';
|
|
eoriSpan.innerText = 'GB174521806000';
|
|
|
|
nabywcaDiv.appendChild(br);
|
|
nabywcaDiv.appendChild(eoriTextNode);
|
|
nabywcaDiv.appendChild(eoriSpan);
|
|
|
|
return false;
|
|
};
|
|
eoriButtonGroup.appendChild(eoriButton);
|
|
|
|
// Create "Wydrukuj z EORI" button
|
|
const printEoriButtonGroup = document.createElement('div');
|
|
printEoriButtonGroup.className = 'btn-group flex-grow-1 mb-1';
|
|
const printEoriButton = document.createElement('a');
|
|
printEoriButton.className = 'btn btn-secondary btn-block';
|
|
printEoriButton.href = '#';
|
|
printEoriButton.innerHTML = '<i class="fa fa-print"></i> Wydrukuj z EORI';
|
|
printEoriButton.onclick = function(e) {
|
|
e.preventDefault();
|
|
|
|
const iframe = document.getElementById('invoice_html');
|
|
if (iframe && iframe.contentWindow) {
|
|
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
|
const iframeWin = iframe.contentWindow;
|
|
|
|
// Inject style to force printing background colors and shadows
|
|
const style = iframeDoc.createElement('style');
|
|
style.id = 'print-fix-styles';
|
|
style.innerHTML = `
|
|
@media print {
|
|
body, body * {
|
|
-webkit-print-color-adjust: exact !important;
|
|
color-adjust: exact !important;
|
|
print-color-adjust: exact !important;
|
|
}
|
|
.table-striped tbody tr:nth-of-type(odd) {
|
|
background-color: #f9f9f9 !important;
|
|
}
|
|
thead, thead *, thead th, thead th * {
|
|
color: black !important;
|
|
-webkit-text-fill-color: black !important;
|
|
visibility: visible !important;
|
|
}
|
|
}
|
|
`;
|
|
iframeDoc.head.appendChild(style);
|
|
|
|
const removePrintStyles = () => {
|
|
const styleToRemove = iframeDoc.getElementById('print-fix-styles');
|
|
if (styleToRemove) {
|
|
iframeDoc.head.removeChild(styleToRemove);
|
|
}
|
|
};
|
|
|
|
const mediaQueryList = iframeWin.matchMedia('print');
|
|
const handler = (mql) => {
|
|
if (!mql.matches) {
|
|
removePrintStyles();
|
|
// Use the correct method based on browser support
|
|
try {
|
|
if (mql.removeEventListener) {
|
|
mql.removeEventListener('change', handler);
|
|
} else if (mql.removeListener) {
|
|
mql.removeListener(handler);
|
|
}
|
|
} catch (e) {
|
|
// Ignore errors when removing listeners
|
|
console.log('Error removing print listener:', e);
|
|
}
|
|
}
|
|
};
|
|
|
|
try {
|
|
if (mediaQueryList.addEventListener) {
|
|
mediaQueryList.addEventListener('change', handler);
|
|
} else if (mediaQueryList.addListener) {
|
|
mediaQueryList.addListener(handler);
|
|
}
|
|
} catch (e) {
|
|
console.log('Error adding print listener:', e);
|
|
}
|
|
|
|
iframeWin.focus();
|
|
iframeWin.print();
|
|
|
|
} else {
|
|
window.print();
|
|
}
|
|
|
|
return false;
|
|
};
|
|
printEoriButtonGroup.appendChild(printEoriButton);
|
|
|
|
// Create "Pobierz z EORI" button
|
|
const downloadEoriButtonGroup = document.createElement('div');
|
|
downloadEoriButtonGroup.className = 'btn-group flex-grow-1 mr-1 mb-1';
|
|
const downloadEoriButton = document.createElement('a');
|
|
downloadEoriButton.className = 'btn btn-secondary btn-block';
|
|
downloadEoriButton.href = '#';
|
|
downloadEoriButton.innerHTML = '<i class="fa fa-download"></i> Pobierz z EORI';
|
|
downloadEoriButton.onclick = function(e) {
|
|
e.preventDefault();
|
|
|
|
const iframe = document.getElementById('invoice_html');
|
|
if (iframe && iframe.contentWindow) {
|
|
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
|
const iframeWin = iframe.contentWindow;
|
|
|
|
// Inject style to force printing background colors and shadows
|
|
const style = iframeDoc.createElement('style');
|
|
style.id = 'download-fix-styles';
|
|
style.innerHTML = `
|
|
@media print {
|
|
body, body * {
|
|
-webkit-print-color-adjust: exact !important;
|
|
color-adjust: exact !important;
|
|
print-color-adjust: exact !important;
|
|
}
|
|
.table-striped tbody tr:nth-of-type(odd) {
|
|
background-color: #f9f9f9 !important;
|
|
}
|
|
thead, thead *, thead th, thead th * {
|
|
color: black !important;
|
|
-webkit-text-fill-color: black !important;
|
|
visibility: visible !important;
|
|
}
|
|
}
|
|
`;
|
|
iframeDoc.head.appendChild(style);
|
|
|
|
// Show instruction to user
|
|
alert('W oknie drukowania wybierz "Zapisz jako PDF" jako drukarkę docelową.');
|
|
|
|
// Create a function to handle PDF saving
|
|
const saveAsPdf = () => {
|
|
iframeWin.print();
|
|
|
|
// Clean up styles after a delay
|
|
setTimeout(() => {
|
|
const styleToRemove = iframeDoc.getElementById('download-fix-styles');
|
|
if (styleToRemove) {
|
|
iframeDoc.head.removeChild(styleToRemove);
|
|
}
|
|
}, 1000);
|
|
};
|
|
|
|
iframeWin.focus();
|
|
setTimeout(saveAsPdf, 500);
|
|
|
|
} else {
|
|
window.print();
|
|
}
|
|
|
|
return false;
|
|
};
|
|
downloadEoriButtonGroup.appendChild(downloadEoriButton);
|
|
|
|
// Append new buttons to the target div
|
|
targetDiv.appendChild(eoriButtonGroup);
|
|
targetDiv.appendChild(printEoriButtonGroup);
|
|
targetDiv.appendChild(downloadEoriButtonGroup);
|
|
|
|
// Mark as buttons added
|
|
targetDiv.dataset.customButtonsAdded = 'true';
|
|
});
|
|
}
|
|
|
|
// Use MutationObserver to detect when new content is added to the page
|
|
const observer = new MutationObserver(function(mutations) {
|
|
mutations.forEach(function(mutation) {
|
|
if (mutation.addedNodes.length) {
|
|
addButtons();
|
|
}
|
|
});
|
|
});
|
|
|
|
observer.observe(document.body, {
|
|
childList: true,
|
|
subtree: true
|
|
});
|
|
})(); |