Last active
January 2, 2025 13:23
-
-
Save thibaultmol/2a8fe7f2e78319f954c64c274beb25f2 to your computer and use it in GitHub Desktop.
Breex Snelle invoer chatgpt api
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//see other scripts. This is purely here for the name at the top |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Billit Invoice AI data extractor | |
// @version 1.1 | |
// @description Extracts various data from the images in Snelle Invoer by sending it to through openai | |
// @author Thibaultmol | |
// @match https://my.breex.be/* | |
// @match https://my.billit.be/* | |
// @updateURL https://gist.github.com/thibaultmol/2a8fe7f2e78319f954c64c274beb25f2/raw/071d4e05e06ae002e7ed76a1bf2d0ed8735fdd6f/billit_data-extractor.user.js | |
// @downloadURL https://gist.github.com/thibaultmol/2a8fe7f2e78319f954c64c274beb25f2/raw/071d4e05e06ae002e7ed76a1bf2d0ed8735fdd6f/billit_data-extractor.user.js | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// European country codes for IBAN | |
const EUROPEAN_COUNTRY_CODES = [ | |
'AD', 'AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', | |
'ES', 'FI', 'FR', 'GB', 'GI', 'GR', 'HR', 'HU', 'IE', 'IS', | |
'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', | |
'PT', 'RO', 'SE', 'SI', 'SK', 'SM', 'VA' | |
]; | |
// Function to get current domain | |
function getCurrentDomain() { | |
return window.location.hostname; | |
} | |
// Function to convert IBAN with spaces to format needed for URL | |
function formatIBANForUrl(iban) { | |
return iban.replace(/\s+/g, ''); | |
} | |
// Function to check if string matches IBAN pattern | |
function isIBAN(text) { | |
const cleanText = text.trim().replace(/\s+/g, ''); | |
// Check if starts with any valid country code followed by 2 digits | |
const countryCodePattern = EUROPEAN_COUNTRY_CODES.join('|'); | |
const ibanRegex = new RegExp(`^(${countryCodePattern})\\d{2}[\\dA-Z]+$`); | |
return ibanRegex.test(cleanText); | |
} | |
// Function to convert span to link | |
function convertSpanToLink() { | |
const spans = document.querySelectorAll('span.form-control-plaintext'); | |
const currentDomain = getCurrentDomain(); | |
spans.forEach(span => { | |
const text = span.textContent.trim(); | |
if (isIBAN(text)) { | |
const formattedIBAN = formatIBANForUrl(text); | |
const link = document.createElement('a'); | |
link.href = `https://${currentDomain}/Payment/Index?Search=${formattedIBAN}`; | |
link.textContent = text; | |
link.className = 'form-control-plaintext'; | |
link.style.textDecoration = 'underline'; | |
span.parentNode.replaceChild(link, span); | |
} | |
}); | |
} | |
// Initial conversion | |
convertSpanToLink(); | |
// Monitor for dynamic content changes | |
const observer = new MutationObserver((mutations) => { | |
convertSpanToLink(); | |
}); | |
observer.observe(document.body, { | |
childList: true, | |
subtree: true | |
}); | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Billit Missing Order Numbers Checker | |
// @version 1.2 | |
// @description Adds a button to check for missing order numbers on the Incoming invoices page | |
// @author Thibaultmol | |
// @match https://my.breex.be/Order/Income/Invoice/* | |
// @match https://my.billit.be/Order/Income/Invoice/* | |
// @updateURL https://gist.github.com/thibaultmol/2a8fe7f2e78319f954c64c274beb25f2/raw/071d4e05e06ae002e7ed76a1bf2d0ed8735fdd6f/billit_find-missing-invoices.user.js | |
// @downloadURL https://gist.github.com/thibaultmol/2a8fe7f2e78319f954c64c274beb25f2/raw/071d4e05e06ae002e7ed76a1bf2d0ed8735fdd6f/billit_find-missing-invoices.user.js | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
function findMissingNumbers(numbers) { | |
numbers = numbers.map(n => parseInt(n)).sort((a, b) => a - b); | |
let missing = []; | |
for(let i = 0; i < numbers.length - 1; i++) { | |
let diff = numbers[i + 1] - numbers[i]; | |
if(diff > 1) { | |
for(let j = 1; j < diff; j++) { | |
missing.push(numbers[i] + j); | |
} | |
} | |
} | |
return missing.sort((a, b) => b - a); | |
} | |
function checkMissingNumbers() { | |
let orderNumbers = []; | |
document.querySelectorAll('td[sortcolumn="OrderNumber"]').forEach(td => { | |
orderNumbers.push(td.textContent.trim()); | |
}); | |
let missingNumbers = findMissingNumbers(orderNumbers); | |
if(missingNumbers.length > 0) { | |
alert('Missing order numbers:\n' + missingNumbers.join(', ')); | |
} else { | |
alert('No missing order numbers found!'); | |
} | |
} | |
function addButton() { | |
// Remove existing button if present | |
const existingButton = document.querySelector('.check-missing-btn'); | |
if (existingButton) { | |
existingButton.remove(); | |
} | |
const buttonRow = document.querySelector('.buttonRow'); | |
if(buttonRow) { | |
const newButton = document.createElement('button'); | |
newButton.className = 'btn-sm btn-secondary btn hideOnPost check-missing-btn'; | |
newButton.type = 'button'; | |
newButton.innerHTML = '<i class="fas fa-search"></i><span class="ml-2">Check Missing</span>'; | |
newButton.addEventListener('click', checkMissingNumbers); | |
newButton.style.setProperty('--bs-btn-focus-box-shadow', '0 0 0 0.2rem rgba(41, 255, 114, 0.5)'); | |
newButton.style.setProperty('box-shadow', '0px 0px 0px 4px inset rgba(41, 255, 114, 0.5)', 'important'); | |
const btnGroup = buttonRow.querySelector('.btn-group'); | |
buttonRow.insertBefore(newButton, btnGroup); | |
} | |
} | |
// Initial button add | |
addButton(); | |
// Watch for AJAX content updates | |
const observer = new MutationObserver((mutations) => { | |
for (const mutation of mutations) { | |
if (mutation.target.id === 'OrderList' && | |
mutation.type === 'childList' && | |
mutation.addedNodes.length > 0) { | |
// Wait a brief moment for the DOM to settle | |
setTimeout(addButton, 100); | |
break; | |
} | |
} | |
}); | |
// Start observing the document with the configured parameters | |
observer.observe(document.body, { | |
childList: true, | |
subtree: true | |
}); | |
// Also watch for URL changes via History API | |
const originalPushState = history.pushState; | |
history.pushState = function() { | |
setTimeout(addButton, 100); | |
return originalPushState.apply(this, arguments); | |
}; | |
const originalReplaceState = history.replaceState; | |
history.replaceState = function() { | |
setTimeout(addButton, 100); | |
return originalReplaceState.apply(this, arguments); | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment