Blog de développement

Rapprochement Bancaire

Dernière Modification le :
2000-01-01

Le rapprochement bancaire est une étape importante pour un site de commerce electronique B2B, où typiquement, le paiement des facture se fait par virement et non pas par carte de crédit. Les banques offrent plus ou moins de services, avec un accès plus ou moins simple. Ma banque traditionnelle offre un service concu il y a bien longtemps, un peu obsolète et derrière un rideau de fer. SHINE nous apporte, à compter de 2024, un service très facile à automatiser, y compris pour les comptes basiques. Ils envoient un lien qui permet de télécharger un ZIP avecles releves bancaires sous plusieurs format dont PDF et csv. L'exploitation en est donc facilitée.

Listener: téléchargement du ZIP

Vous recevez sur des boites mails de votre choix un lien vers un fichier ZIP, placé sur Google cloud... J'ai paramétré la messagerie de notre comptabilité pour qu'elle envoie ce message vers une boite relevée par notre Listener...

A reception du Mail, le listener l'intercepte, l'analyse et le télécharge. Le rapprochement et le relevé sont mensuels, le lien fourni par la banque est valide 7 jours... Donc la mission de récupérer le ZIP est confiée au listener. Elle aurait pu aussi bien être confiée à un script au service comptable...

La banque envoie le lien vers le 6 du mois... Le 6 du mois, le listener se met en mode écoute, jusqu'à 6 + 7 ...A chaque cycle, le listener interroge les boites mails et identifie le mail de la banque sur la base du nom de l'expéditeur, du titre et du contenu

Analyse du contenu

Da


sPattern="https://storage"	'.googleapis.com"
		'href=3Dhttps://storage.googleapis.com/shFkOBlN5753msPT%2Bc8pbdEm6A%3D%3D class=3D"btn"
		If InStr(1,sContent, sPattern,1) > 0  then
			sContent = Right (sContent, len(sContent)-InStr(1,sContent, sPattern,1)+1)
			sContent = trim(Left(sContent, InStr(1,sContent, ")",1)-1))
			sContent = replace(sContent,"=" & VbCrLf, "")
			sContent = replace(sContent,"=3D" , "=")
			sContent = replace(sContent,"&" , "&")
			
			'MsgBox sContent
			If InStr(1,sContent, ".zip",1) = 0  then sContent = ""
			If InStr(1,sContent, "granuloshop",1) = 0  then sContent = ""
			If InStr(1,sContent, "shine",1) = 0  then sContent = ""
End If

Expression reguliere avec CHAT-GPT

Puisqu'il nous faut recupérer: le lien, le nom du ZIP, la date d'expiration, voire davantage selon les cas, nous utilisons une expression régulière. Or, CHAT-GPT est assez bon à ce petit jeu. Le Mail, lu comme un texte simple est encodé et on y voit que = suivi de Cr+LF y est ajouté pour être au format e mail, donc on le retire...
If InStr(1,sContent, ".zip",1) = 0  then sContent = ""
			If InStr(1,sContent, "granuloshop",1) = 0  then sContent = ""
			If InStr(1,sContent, "shine",1) = 0  then sContent = ""

Voici un exemple de prompt:

Je programme en VBS . Avec comme modèle: href=3Dhttps://xxxx.com/shinexxxx/GRXXX_01-2024_02-2024EXPORT.zip?GoogleAccessId=xxxx.com&Expires=3D1707750677&Signature=yyyy%3D class= Me faire une expression régulière où: href=3Dhttps://xxxx.com/ , shine, Expires= ainsi que class= sont des invariants à ne pas capturer GRXXX_01-2024_02-2024EXPORT.zip et 1707750677 sont des variables à capturer Pour créer une expression régulière qui correspond à votre besoin, nous pouvons utiliser la structure suivante. Cette structure suppose que GRXXX_01-2024_02-2024EXPORT.zip et 1707750677 sont les parties variables de l'URL que vous souhaitez capturer, et que href=3Dhttps://xxxx.com/, shine, Expires= ainsi que class= sont les invariants à ne pas capturer. Les parties variables seront capturées à l'aide de groupes, que vous pourrez ensuite référencer selon vos besoins. La structure de base de l'expression régulière serait donc :
href=3Dhttps:\/\/xxxx\.com\/shine(.+)\/(GRXXX_01-2024_02-2024EXPORT\.zip)\?GoogleAccessId=xxxx\.com&Expires=3D(\d+)&Signature=.+ class=

Voici une explication détaillée de chaque partie de l'expression : href=3Dhttps:\/\/xxxx\.com\/shine : Cette partie correspond à l'invariant de début, avec l'échappement des caractères spéciaux comme . et /. (.+)\/ : Ce groupe capture tout ce qui se trouve entre shine et le / suivant GRXXX_01-2024_02-2024EXPORT.zip, supposant que vous avez un élément variable ici. Si cet élément n'est pas nécessaire, vous pouvez l'ajuster ou le supprimer. (GRXXX_01-2024_02-2024EXPORT\.zip) : Ce groupe capture spécifiquement le nom du fichier ZIP, avec l'échappement des caractères . pour s'assurer qu'ils sont traités littéralement. \?GoogleAccessId=xxxx\.com&Expires=3D(\d+)&Signature= : Cette partie inclut des invariants supplémentaires tout en capturant la partie variable de l'expiration avec (\d+), qui correspond à une séquence de chiffres. .+ class= : Cette partie correspond à la fin de l'URL, capturant tout jusqu'à class=, sans inclure cette dernière partie dans la capture. Notez que selon la structure exacte des URLs que vous traitez et la variabilité des éléments, vous pourriez avoir besoin d'ajuster l'expression régulière pour qu'elle corresponde exactement à vos besoins. Par exemple, si GRXXX_01-2024_02-2024EXPORT.zip change de format, vous devrez ajuster le groupe de capture correspondant pour s'assurer qu'il capture correctement la nouvelle structure.

Voici une expression régulière qui devrait fonctionner pour capturer les variables dans votre chaîne :

href=3Dhttps:\/\/[a-zA-Z0-9\.\_\-]+\/shine[a-zA-Z0-9\-]+\_(\w{3}[0-9]{2})-(\d{4})_(\w{3}[0-9]{2})-(\d{4})EXPORT\.zip\?GoogleAccessId=[a-zA-Z0-9\.\_\-]+&Expires=3D(\d+)&Signature=[a-zA-Z0-9\%\=\+\-]+\ class=

Les variables capturées seront dans les groupes 1 à 5, où : Groupe 1 : GRXXX (mois de début) ; Groupe 2 : 01-2024 (année de début) ; Groupe 3 : 02-2024 (mois de fin) ; Groupe 4 : EXPORT (invariant) ; Groupe 5 : 1707750677 (Expires)

Correction dans la dernière colonne

On peut manipuler les colonnes à importer ou pas... Mais il existe des cas où ca ne marche pas comme espéré: BCP n'est pas all-mighty. dans le fichier .csv dela banque, j'ai des champs vide que je souhaite ne PAS importer, ce sont des champs de rang élévés. On peut ne pas créer de colonnes pour les recevoir. Toutefois ces champs, qui apparaissent dans le CSV comme ;;;; vont se retrouver comme ;;;; en fin de la derniere colonne. On procède donc à un petit nettoyage après l'importation...

La.

Correction d'encodage

Le CSV fourni par la banque est en UTF-8. Avec BCP on peut importer en UTF-8... Pour des raisons historique ma table SQL est en Windows-1252, et je préfère reste à cet encodage, don j'utilise ICONV pour transcoder

"C:\...\iconv.exe" -f UTF-8 -t Windows-1252 "E:\...\xxx.csv" 1> "E:\...\xxxWindows-1252.csv" 

Conversion de date

Ma banque fourni la date banque au format 'Français' usuel. Pour entrer dans SQL on procède en 2 étapes: d'abord avec BCP, en mode texte dans une table de transfer. Puis avec ADODB.Recordset au format ISO :
Function ConvertDateFormatFrenchToISO(inputDate)     
	' // Séparer la date d'entrée en ses composants
	parts = Split(inputDate, "/")    
	' // Assumer l'entrée au format jj/mm/aaaa
	sday = parts(0)
	smonth = parts(1)
	syear = parts(2)    
	' // Reformater la date en aaaa-mm-jj
	ConvertDateFormatFrenchToISO = syear & "-" & smonth & "-" & sday
End Function

XXX

					    
XXX