Script pour import Sage 100 et i7 (et Ciel ?)
Posté : sam. mars 10, 2018 1:22 pm
Je me suis fait un script Python de conversion d'un fichier comptable provenant de Sage 100 et i7 vers le format CSV accepté par OpenConcerto.
Outre la conversion pure et dure des écritures comptables, il me permet :
- de contourner le bug de comptes multiples décrit dans le deuxième message de ce topic.
- de faire des ajustements personnels sur la numérotation des codes comptables.
- de contourner un bug assez vicieux sur les lettres accentuées qui passaient parfois mal. L'écriture "magique" rajoutée en début de fichier CSV m'a l'air de résoudre ce problème, mais je ne peux apporter aucune garantie.
Par contre, je n'ai pas trouvé de contournement sur le bug des codes journaux non présents.. pourtant bien présents.
Comment utiliser ce script :
- enregistrer le script dans un fichier pnmtocsv.py
- lancer le script avec en paramètre le fichier provenant de Sage. Exempe :
- le script va produire 2 fichiers : societeA.csv et societeA_court.csv
- importer d'abord dans OpenConcerto le fichier societeA_court.csv
- supprimer ces mêmes écritures qui viennent d'être importées.
- importer le fichier complet societeA.csv
Optionnel :
Entre les 2 imports, je fais quelques étapes. Lorsque je crée une société sous OpenConcerto, je prends le plan comptable de base. Donc je n'ai pas forcément tous les comptes lorsque je vais importer les écritures en provenance de Sage. Je pourrais partir sur un plan complet, mais je préfère n'avoir que les comptes vraiment utiles.
Donc après le premier import, je sors une balance pour voir les comptes qu'Openconcerto a dû créer (libellé "Création automatique"). Je supprime ensuite les écritures du premier import puis pour chaque compte "Création automatique", je regarde s'il existe dans le plan comptable complet. Si oui, je supprime le compte dans le PCE (le plan comptable de l'entreprise) puis j'importe ce compte depuis le plan comptable général. Cela me permet juste d'avoir le bon libellé pour le compte.
Je mets le code ci-dessous car le forum interdit en pièce jointe des .py ou même des .txt
Outre la conversion pure et dure des écritures comptables, il me permet :
- de contourner le bug de comptes multiples décrit dans le deuxième message de ce topic.
- de faire des ajustements personnels sur la numérotation des codes comptables.
- de contourner un bug assez vicieux sur les lettres accentuées qui passaient parfois mal. L'écriture "magique" rajoutée en début de fichier CSV m'a l'air de résoudre ce problème, mais je ne peux apporter aucune garantie.
Par contre, je n'ai pas trouvé de contournement sur le bug des codes journaux non présents.. pourtant bien présents.
Comment utiliser ce script :
- enregistrer le script dans un fichier pnmtocsv.py
- lancer le script avec en paramètre le fichier provenant de Sage. Exempe :
Code : Tout sélectionner
python3 pnmtocsv.py societeA.pnm
- importer d'abord dans OpenConcerto le fichier societeA_court.csv
- supprimer ces mêmes écritures qui viennent d'être importées.
- importer le fichier complet societeA.csv
Optionnel :
Entre les 2 imports, je fais quelques étapes. Lorsque je crée une société sous OpenConcerto, je prends le plan comptable de base. Donc je n'ai pas forcément tous les comptes lorsque je vais importer les écritures en provenance de Sage. Je pourrais partir sur un plan complet, mais je préfère n'avoir que les comptes vraiment utiles.
Donc après le premier import, je sors une balance pour voir les comptes qu'Openconcerto a dû créer (libellé "Création automatique"). Je supprime ensuite les écritures du premier import puis pour chaque compte "Création automatique", je regarde s'il existe dans le plan comptable complet. Si oui, je supprime le compte dans le PCE (le plan comptable de l'entreprise) puis j'importe ce compte depuis le plan comptable général. Cela me permet juste d'avoir le bon libellé pour le compte.
Je mets le code ci-dessous car le forum interdit en pièce jointe des .py ou même des .txt
Code : Tout sélectionner
# Convertit un/des fichier(s) d'écritures comptables .pnm en fichier CSV pour
# l'erp OpenConcerto
#
# Le format .pnm est généré par Sage Comptabilité Ligne 100 et i7 en exportant
# au "Format Trésorerie Sage et Ciel"
#
# En sortie, le fichier sera au format CSV accepté par OpenConcerto
#
# Le chemin et le ficher .pnm doit être indiqué après l'appel du script :
# ex : pnmtocsv.py socA.pnm
# pnmtocsv.py chemin/socB.pnm
#
# Plusieurs fichiers peuvent être indiqués :
# ex : pnmtocsv.py socA.pnm chemin/socB.pnm
#
# En raison d'un bug dans la fonction d'importation dans OpenConcerto 5.2, le
# script va générer deux fichiers CSV :
# - socA.csv est le fichier "normal" contenant toutes les écritures
# - socA_court.csv est un fichier "réduit" contenant le minimum d'écritures (au
# maximum une par code comptable) avec un montant symbolique
# C'est ce fichier court qu'il faut en premier lieu importer. Comme cela,
# OpenConcerto ne va créer qu'une seule fois les codes comptables qu'il ne
# connait pas.
# Ensuite, il faut supprimer ces écritures importées, puis importer le premier
# fichier CSV.
#
# Le script a été testé sous environnement Linux et Python 3.5
import sys
from pathlib import Path
# liste des codecs qui serviront à produire les fichiers en sortie
#codecs = ['utf_8','iso8859_15', 'cp1252', 'cp850', 'cp858']
codecs = ['utf8']
# Récupération et vérification des fichiers données en ligne de commandes
societes = []
for a in sys.argv[1:] :
p = Path(a)
if p.is_file() and p.suffix == '.pnm' :
societes.append(p)
else :
print("le fichier", p, "sera ignoré, ce n'est pas un fichier .pnm")
for societe in societes :
set_codes_comptables = set()
for codec in codecs :
with open(str(societe), 'r', encoding='cp850') as file_pnm :
date_fichier_court = '01/01/1970'
with open(str(societe.with_suffix('.csv')), 'w', encoding=codec) as file_export :
for n, line in enumerate(file_pnm) : # on lit les lignes une par une
# La première ligne du fichier .pnm contient un entête inutile
if n == 0 :
continue
# Pour chaque ligne, on découpe et récupère les éléments nécessaires :
# Code journal
journal = line[0:2].strip()
# Date au format JJ/MM/AAAA (en contradiction avec la boite de dialogue d'import)
date = line[3:9].strip()
date = list(date)
date.insert(4,'/20')
date.insert(2,'/')
date = ''.join(date)
# Compte comptable suit plusieurs règles personnelles
# - suppression des zéros en fin de compte sauf si le compte ne tient que sur 2 chiffres
# (ex: on ne veut pas 51210000 mais 5121, on ne veut pas 11 mais 110)
# - des exceptions sont gérées (par exemple, on veut le compte 44860 et non 4486)
# - dans le cas d'un compte de tiers, c'est celui-ci qui est pris en compte
# - pour les comptes de tiers, on fait une conversion en rajoutant un 1 entre le 40 (et 41)
# et le nom du compte (ex : 40TOTO devient 401TOTO)
compte_comptable = line[11:24].strip().rstrip('0') #on enlève les 0 à la fin du compte
if len(compte_comptable) < 3 : # On augmente la longueur du compte comptable à 3 chiffres
compte_comptable = compte_comptable + '0'
if compte_comptable == '4486' : # On doit garder le compte 44860 qui est le compte de la taxe d'apprentissage
compte_comptable = '44860'
compte_tiers = line[24:38].strip() # On enlève les blancs
if compte_tiers : # le compte tiers est prioritaire au compte comptable
compte_comptable = compte_tiers[1:3] + '1' + compte_tiers[3:]
# Numéro de la pièce
num_piece = line[38:51].strip()
# Libellé de l'écriture
libelle = line[51:77].strip()
# Le champs 'sens' indique si l'écriture lue est à mettre au débit ou crédit
sens = line[83:84].strip()
montant = line[84:104].strip()
if sens == 'D' :
debit = montant
credit = '0'
else :
debit = '0'
credit = montant
# on mémorise dans un set les comptes comptables qui seront utilisés (ils seront donc uniques)
set_codes_comptables.add(compte_comptable)
# Avant la première ligne du fichier CSV, on insère une écriture spéciale.
# Cette écriture, d'un montant nul mais avec des accents semble suffisante
# pour que le reste des écritures s'importent correctement avec les accents
if n == 1 :
file_export.write(date + ';OD;471;1;éàôâ;0;0\n')
date_fichier_court = date
# On formate la ligne à produire puis on l'enregistre dans le fichier CSV
ligne_export = [date, journal, compte_comptable, num_piece, libelle, debit, credit]
file_export.write(';'.join(ligne_export)+'\n')
# Génère un fichier CSV avec seulement une écriture par compte
# pour contourner le bug de la création multiple des comptes
# inconnues lors de l'importation.
# Les écritures sont non nulles pour sortir une balance de
# vérification des comptes utilisées.
# Toutes les écritures un 1 au débit, sauf la dernière pour
# l'équilibrage
with open(str(p.with_name(p.stem + '_court.csv')), 'w', encoding=codec) as file_pre_export :
date = date_fichier_court
journal = 'OD'
num_piece = ''
libelle = ''
debit = '1'
credit = '0'
list_comptes = list(set_codes_comptables)
list_comptes.sort()
nb_compte = len(list_comptes)
last_compte = list_comptes.pop() # on met de coté le dernier compte pour l'équilibrage
for compte_comptable in list_comptes :
ligne_export = [date, '"' + journal + '"', compte_comptable, num_piece, libelle, debit, credit]
file_pre_export.write(';'.join(ligne_export)+'\n')
# Dernière ligne pour l'équilibrage des écritures
ligne_export = [date, '"' + journal + '"', last_compte, num_piece, libelle, '0', str(nb_compte - 1)]
file_pre_export.write(';'.join(ligne_export)+'\n')