Commit 49a19399 authored by plb's avatar plb
Browse files

Add comments + configuration template

parent 2300c702
......@@ -4,154 +4,264 @@ from __future__ import unicode_literals
import datetime
#
# GENERAL
# OUTPUT_DIR : The base directory where to put the ledger files
#
OUTPUT_DIR = "./out"
OUTPUT_DIR = "./"
#
# OUTPUT_FILES : The file paths template for each journal.
# - bank : the bank entries
# - sells : the sell entries
# - suppliers : the supplier entries
# - social : the social entries (tax, etc.)
# - pc : chart of accounts
OUTPUT_FILES = {
"bank": "%year%/ecritures.d/banque.journal",
"sells": "%year%/ecritures.d/vente.journal",
"suppliers": "%year%/ecritures.d/achat.journal",
"bank": "exercices/%year%/ecritures.d/banque.journal",
"sells": "exercices/%year%/ecritures.d/vente.journal",
"suppliers": "exercices/%year%/ecritures.d/achat.journal",
"social": "exercices/%year%/ecritures.d/cotisations_sociales.journal",
"pc": "plan.journal",
}
#
# MYSQL_SETTINGS : Database definition
#
MYSQL_SETTINGS = {
"host": "localhost",
"database": "dolibarr_test",
"user": "dolibarr_test",
"password": "dae1ohCu",
"port": 3306,
"host": "127.0.0.1",
"database": "dolibarr",
"user": "dolibarr_ro",
"password": "",
"port": 13306,
}
#
# Describe accounting year if not standard (from 1st january to 31 december)
# ACCOUNTING_YEARS : Describe the accounting years if not standard (from 1st january to 31 december).
# For exemple the first accounting year could start before the 1st january
#
ACCOUNTING_YEARS = {
("2012", "2011/01/01", "2012/12/31")
}
TVA_REFS = {
'tva_deductible': '4456',
'tva_collecte': '4457',
#
# TVA_TYPE : Sort of value-added tax. Possible values :
# - 'standard' : the value added tax is on delivery for goods (billing date), on payment for services (payment date).
# - 'service_sur_debit' : the value added tax is on delivery for goods (billing date), and on billing date for services.
TVA_TYPE = "standard"
#
# PC_REFS: define the account references. This is a dictionnary of account.
#
PC_REFS = {
"tva_a_decaisser": "44551",
"tva_deductible": "44562",
"tva_deductible_1960": "445621",
"tva_deductible_2000": "445622",
"tva_deductible_immo": "44566",
"tva_deductible_immo_1960": "445661",
"tva_deductible_immo_2000": "445662",
"tva_collecte": "44571",
"tva_collecte_1960": "445711",
"tva_collecte_2000": "445712",
"tva_regul": "4458",
"tva_regul_1960": "44581",
"tva_regul_2000": "44582",
"default_supplier": "4011999",
"default_client": "4111999",
"default_tier": "4999999",
"default_bank": "512999",
"default_income": "7069999",
"default_expense": "6199999",
"fn_custom_codes": [
lambda e: u"261" if e.label == u"Souscription part sociale" and e.datev == datetime.date(year=2011, month=9, day=27) else None,
lambda e: u"1681" if e.bankclass.categ.id == 7 else None,
],
}
SOCIAL_REFS = {
"TAXCFE": "447",
"TAXPENALITE": "447",
}
#
# Plan comptables (nom, description)
#
PC_NAMES = {
'1' : 'capitaux',
'11' : 'capitaux:report à nouveau',
'117' : 'capitaux:report à nouveau:positif',
'119' : 'capitaux:report à nouveau:négatif',
'12' : 'capitaux:résultat',
'120' : 'capitaux:résultat:positif',
'129' : 'capitaux:résultat:négatif',
'2' : 'immobilisations',
'201' : "immobilisations:incorporelles:frais d'établissement",
'21' : "immobilisations:corporelles",
'2183' : "immobilisations:corporelles:matériel informatique",
'2184' : "immobilisations:corporelles:mobilier",
'281' : "immobilisations:amortissements",
'2801' : "immobilisations:amortissements:incorporelles",
'2818' : "immobilisations:amortissements:corporelles",
'28183' : "immobilisations:amortissements:corporelles:matériel informatique",
'28184' : "immobilisations:amortissements:corporelles:mobilier",
'4' : "tiers",
'40' : "tiers:fournisseurs",
'401101' : "tiers:fournisseurs:telehouse",
'401102' : "tiers:fournisseurs:Liazo",
'401103' : "tiers:fournisseurs:Absolight",
'401104' : "tiers:fournisseurs:Tata Communication",
'401105' : "tiers:fournisseurs:Lost Oasis",
'401106' : "tiers:fournisseurs:RIPE NCC",
'401107' : "tiers:fournisseurs:Crédit Mutuel",
'401108' : "tiers:fournisseurs:LCD International",
'401109' : "tiers:fournisseurs:CICP",
'401110' : "tiers:fournisseurs:Alturna Network",
'401111' : "tiers:fournisseurs:GANDI SAS",
'401112' : "tiers:fournisseurs:AS Info",
'41' : "tiers:clients",
'411101' : "tiers:clients:Altern B",
'411102' : "tiers:clients:FDN",
'411103' : "tiers:clients:Globenet",
'411104' : "tiers:clients:Linagora",
'411105' : "tiers:clients:Gixe",
'411106' : "tiers:clients:LAutreNet",
'411107' : "tiers:clients:Rézine",
'411108' : "tiers:clients:Tetaneutral",
'411109' : "tiers:clients:Grenode",
'411110' : "tiers:clients:Franciliens",
'411111' : "tiers:clients:Illyse",
'411112' : "tiers:clients:Ilico",
'411113' : "tiers:clients:Octopuce",
'411114' : "tiers:clients:Artefact",
'411115' : "tiers:clients:NDN",
'411116' : "tiers:clients:LDN",
'411117' : "tiers:clients:Neutrinet",
'411118' : "tiers:clients:AssoDIUT",
'411119' : "tiers:clients:Rhizome",
'411120' : "tiers:clients:BeTech",
'411121' : "tiers:clients:personne physique",
'445' : "tiers:etat:tva",
'4456' : "tiers:etat:tva:déductible",
'4457' : "tiers:etat:tva:collecté",
'468' : "tiers:divers",
'4686' : "tiers:divers:charges à payer",
'5' : "finances",
'512' : "finances:banque",
'5121' : "finances:banque:Crédit Mutuel",
'5122' : "finances:banque:GIE",
'532' : "finances:chèques à encaisser",
'6' : "charges",
'60' : "charges:achats",
'604' : "charges:achats:prestation de services",
'606' : "charges:achats:non-stockés",
'6061' : "charges:achats:non-stockés:fournitures non stockables",
'6063' : "charges:achats:non-stockés:fournitures d'entretien et petits équipements",
'6064' : "charges:achats:non-stockés:fournitures administratives",
'6068' : "charges:achats:non-stockés:autres matières et fournitures",
'61' : "charges:services",
'613' : "charges:services:locations",
'613001' : "charges:services:locations:hosting",
'613002' : "charges:services:locations:lir",
'616' : "charges:services:assurances",
'62' : "charges:autres services",
'6227' : "charges:autres services:frais d'actes",
'626' : "charges:autres services:pce",
'626001' : "charges:autres services:pce:internet",
'625' : "charges:autres services:déplacement, missions,réceptions",
'627' : "charges:autres services:banque",
'628' : "charges:autres services:divers",
'6281' : "charges:autres services:divers:cotisations",
'651' : "charges:redevances",
'672' : "charges:charges sur exercices antérieur",
'6811' : "charges:amortissements",
'68111' : "charges:amortissements:incorporelles",
'68112' : "charges:amortissements:corporelles",
'7' : "produits",
'706' : "produits:services",
'706001' : "produits:services:routage",
'706002' : "produits:services:commutation",
'706003' : "produits:services:lir",
'7060031' : "produits:services:lir:pi",
'7060032' : "produits:services:lir:pa",
'706004' : "produits:services:hosting",
'706005' : "produits:services:transit",
'7060050' : "produits:services:transit:bp-0",
'7060051' : "produits:services:transit:bp-a",
'7060052' : "produits:services:transit:bp-b",
'7060053' : "produits:services:transit:bp-c",
'7060054' : "produits:services:transit:bp-d",
'756' : "produits:cotisations",
'77' : "produits:exceptionnels",
'7718' : "produits:exceptionnels:dons manuels",
"1": "capitaux",
"11": "capitaux:report à nouveau",
"110": "capitaux:report à nouveau:créditeur",
"119": "capitaux:report à nouveau:débiteur",
"12": "capitaux:résultat",
"120": "capitaux:résultat:positif",
"129": "capitaux:résultat:négatif",
"16": "capitaux:emprunts et dettes",
"168": "capitaux:emprunts et dettes:autres",
"1681": "capitaux:emprunts et dettes:autres:emprunts",
"2": "immobilisations",
"201": "immobilisations:incorporelles:frais d établissement",
"21": "immobilisations:corporelles",
"2183": "immobilisations:corporelles:matériel informatique",
"2184": "immobilisations:corporelles:mobilier",
"26": "immobilisations:participations",
"261": "immobilisations:participations:titres",
"280": "immobilisations:amortissements:incorporelles",
"281": "immobilisations:amortissements:corporelles",
"2813": "immobilisations:amortissements:corporelles:matériel informatique",
"2814": "immobilisations:amortissements:corporelles:mobilier",
"4": "tiers",
"40": "tiers:fournisseurs",
"4011999": "tiers:fournisseurs:XXXXXX",
"41": "tiers:clients",
"4111999": "tiers:clients:XXXXXX",
"42": "tiers:comptes rattachés",
"425": "tiers:comptes rattachés:avances et accomptes",
"445": "tiers:etat:tva",
"44551": "tiers:etat:tva:à décaisser",
"4456": "tiers:etat:tva:déductible",
"44562": "tiers:etat:tva:déductible:immobilisations",
"445621": "tiers:etat:tva:déductible:immobilisations:1960",
"445622": "tiers:etat:tva:déductible:immobilisations:2000",
"44566": "tiers:etat:tva:déductible:autres",
"445661": "tiers:etat:tva:déductible:autres:1960",
"445662": "tiers:etat:tva:déductible:autres:2000",
"44567": "tiers:etat:tva:déductible:crédit à reporter",
"44571": "tiers:etat:tva:collecté",
"445711": "tiers:etat:tva:collecté:1960",
"445712": "tiers:etat:tva:collecté:2000",
"4458": "tiers:etat:tva:à régulariser",
"44581": "tiers:etat:tva:à régulariser:1960",
"44582": "tiers:etat:tva:à régulariser:2000",
"447": "tiers:etat:autres impôts",
"467": "tiers:autres",
"468": "tiers:divers",
"4686": "tiers:divers:charges à payer",
"4999999": "tiers:XXXXXX",
"5": "finances",
"512": "finances:banque",
"512999": "finances:banque:XXXXXX",
"532": "finances:chèques à encaisser",
"6": "charges",
"60": "charges:achats",
"604": "charges:achats:prestation de services",
"606": "charges:achats:non-stockés",
"6061": "charges:achats:non-stockés:fournitures non stockables",
"6063": "charges:achats:non-stockés:fournitures d entretien et petits équipements",
"6064": "charges:achats:non-stockés:fournitures administratives",
"6068": "charges:achats:non-stockés:autres matières et fournitures",
"61": "charges:services",
"613": "charges:services:locations",
"616": "charges:services:assurances",
"62": "charges:autres services",
"6227": "charges:autres services:frais d actes",
"621": "charges:autres services:personnel extérieur à l entreprise",
"624": "charges:autres services:transport de biens et transports collectifs du personnel",
"625": "charges:autres services:déplacement missions réceptions",
"626": "charges:autres services:pce",
"627": "charges:autres services:banque",
"628": "charges:autres services:divers",
"6281": "charges:autres services:divers:cotisations",
"63": "charges:impots",
"6351": "charges:impots:autres:direct",
"63511": "charges:impots:autres:direct:cet",
"651": "charges:redevances",
"671": "charges:exceptionnelles",
"6712": "charges:exceptionnelles:pénalités fiscales",
"672": "charges:charges sur exercices antérieur",
"6811": "charges:amortissements",
"68111": "charges:amortissements:incorporelles",
"68112": "charges:amortissements:corporelles",
"6999999": "charges:XXXXXX",
"7": "produits",
"706": "produits:services",
"756": "produits:cotisations",
"758": "produits:divers",
"7585": "produits:divers:dons manuels",
"77": "produits:exceptionnels",
"7999999": "produits:XXXXXX",
}
PC_DESCRIPTIONS = {
'41' : 'Clients et comptes rattachés',
'5121': 'CC Crédit Mutuel',
'5122': 'Compte GIE',
"1": "Capitaux",
"11": "Report à nouveau",
"117": "Report positif",
"119": "Report négatif",
"12": "Résultat",
"120": "Résultat positif",
"129": "Résultat négatif",
"16": "Emprunts et dettes assimilés",
"168": "Autres Emprunts et dettes assimilés",
"1681": "Autres Emprunts assimilés",
"2": "Immobilisations",
"201": "Frais d'établissement",
"21": "Immobilisations corporelles",
"2183": "Matériel informatique",
"26": "Participations",
"261": "Titres de participation",
"280": "Amortissements incorporelles",
"281": "Amortissements corporelles",
"2813": "Amortissements du matériel informatique",
"2814": "Amortissements du mobiliers",
"4": "Tiers",
"40": "Fournisseurs",
"4011999": "tiers:fournisseurs:XXXXXX",
"41": "Clients",
"4111999": "tiers:clients:XXXXXX",
"42": "Comptes rattachés",
"425": "Avances et accomptes",
"445": "Taxe sur la Valeur Ajoutée",
"44551": "TVA à décaisser",
"4456": "TVA déductible",
"44562": "TVA déductible sur immobilisations",
"44566": "TVA déductible autres",
"44567": "TVA déductible à reporter",
"4457": "TVA collectée",
"44571": "TVA collectée sur CA",
"447": "Autres impôts taxes et versements assimilés",
"467": "Autres Tiers",
"468": "Tiers divers",
"4686": "Charges à payer",
"5": "Finances",
"512": "Banque",
"512999": "finances:banque:XXXXXX",
"532": "Chèques à encaisser",
"6": "Charges",
"60": "Achats",
"604": "Prestation de services",
"606": "Achats non-stockés",
"6061": "Fournitures non stockables",
"6063": "Fournitures d'entretien et petits équipements",
"6064": "Fournitures administratives",
"6068": "Autres matières et fournitures",
"61": "Services",
"613": "Locations",
"616": "Assurances",
"62": "Autres services",
"6227": "Frais d'actes",
"621": "Frais de personnel extérieur à l'entreprise",
"624": "Frais de transport de biens et transports collectifs du personnel",
"625": "Frais de déplacement",
"626": "Frais de postes et des communications électroniques",
"626101": "Boîte postale",
"627": "Services bancaires et assimilés",
"628": "Services divers",
"6281": "Cotisations",
"63": "Impôts, Taxes",
"6351": "Impôts directs",
"63511": "Contribution Economique Teritorriale",
"651": "Redevances",
"671": "Charges exceptionnelles",
"6712": "Amendes, Pénalités fiscales",
"672": "Charges sur exercices antérieur",
"6811": "Amortissements",
"68111": "Amortissements incorporelles",
"68112": "Amortissements corporelles",
"6999999": "charges:XXXXXX",
"7": "Produits",
"706": "Services",
"756": "Cotisations",
"77": "Produits exceptionnels",
"7718": "Dons manuels",
"7999999": "produits:XXXXXX",
}
......@@ -7,21 +7,24 @@ import datetime
from himports.dolibarrAlchemy import *
#
# HledgerEntry : Base class for an hledger entry
#
class HledgerEntry(object):
accounting_years = settings.get('ACCOUNTING_YEARS')
pc_default_tiers = settings.get('PC_REFS')['default_tiers']
pc_default_tier = settings.get('PC_REFS')['default_tier']
pc_default_client = settings.get('PC_REFS')['default_client']
pc_default_supplier = settings.get('PC_REFS')['default_supplier']
pc_default_produit = settings.get('PC_REFS')['default_produit']
pc_default_charge = settings.get('PC_REFS')['default_charge']
pc_default_income = settings.get('PC_REFS')['default_income']
pc_default_expense = settings.get('PC_REFS')['default_expense']
pc_default_bank = settings.get('PC_REFS')['default_bank']
tva_type = settings.get('TVA_TYPE')
# the sql_class corresponding the hledger class
sql_class = None
# Date permettant de déterminer dans quel exercice comptable
# l'écriture doit se trouver
# Date defining the current accounting year
k_accounting_date = None
def __init__(self, e):
......@@ -31,20 +34,25 @@ class HledgerEntry(object):
for attr in self.k_accounting_date.split('.'):
self.accounting_date = getattr(self.accounting_date, attr)
# Retrieve all entries corresponding to cls.sql_class
@classmethod
def get_entries(cls, session):
return [cls(i) for i in session.query(cls.sql_class).all()]
# get_ledger : Print ledger output. Only defined in derived class
def get_ledger(self):
print "WARNING: get_ledger not done"
return u""
# check_pc : verify the accounting chart corresponding to the entry. Only defined in derived class.
def check_pc(self):
return ()
# get_year: return the year corresponding to the current entry. Only defined in derived class.
def get_year(self):
raise Exception("TODO: get_year not implemented for class %s" % (self.__class__))
# get_accounting_year: return the accouting year corresponding to the current entry.
def get_accounting_year(self):
date = self.accounting_date
if isinstance(date, datetime.datetime):
......@@ -55,19 +63,24 @@ class HledgerEntry(object):
return str(date.year)
# _value: return the value in float with 4 digits
@staticmethod
def _value(value):
return '{number:.{digits}f}'.format(number=value, digits=4)
#
# HledgerJournal: A complete Hledger journal. This is a base class.
#
class HledgerJournal(object):
def __init__(self, session, cls_entry):
self.entries = cls_entry.get_entries(session)
# get_entries: return the journal entries
def get_entries(self):
return self.entries
# get_by_year: return the journal entries by accounting year.
def get_by_year(self):
by_year = {}
for entry in self.get_entries():
......@@ -78,6 +91,7 @@ class HledgerJournal(object):
by_year[entry_year].append(entry)
return by_year
# check_pc: verify there is an account for earch entry on the current journal
def check_pc(self):
pc_missing = set()
for entry in self.get_entries():
......@@ -86,10 +100,19 @@ class HledgerJournal(object):
return pc_missing
#
# HledgerBankEntry: a bank entry
#
class HledgerBankEntry(HledgerEntry):
sql_class = Bank
k_accounting_date = 'datev'
# get_third_code: retrieve the third code corresponding to the entry. It could be
# a supplier payment
# a tax payment
# a customer payment
# a value-added tax payment
# any payment defined in the function PC_REFS['fn_custom_codes']
@classmethod
def get_third_code(cls, e):
third_code = ""
......@@ -122,10 +145,11 @@ class HledgerBankEntry(HledgerEntry):
break
if third_code == "":
third_code = cls.pc_default_tiers
third_code = cls.pc_default_tier
return third_code
# get_description: retrieve the description of the payment
@classmethod
def get_description(self, e):
s_nom = ""
......@@ -152,6 +176,7 @@ class HledgerBankEntry(HledgerEntry):
return s_description
# get_ledger: see @HledgerEntry.get_ledger
def get_ledger(self):
e = self.e
s = ""
......@@ -180,7 +205,7 @@ class HledgerBankEntry(HledgerEntry):
if e.url_payment_supplier:
for f in e.url_payment_supplier.payment_supplier.factures:
tvas = HledgerSupplierEntry.get_tva_paiement_amounts(f.facture, journal="bank")
tvas = HledgerSupplierEntry.get_tva_payment_amounts(f.facture, journal="bank")
for k in tvas:
s += " %(account_tva)s \t %(amount_tva)s\n" % {
'account_tva': settings.get_ledger_account(k),
......@@ -188,7 +213,7 @@ class HledgerBankEntry(HledgerEntry):
}
elif e.url_payment:
for f in e.url_payment.payment.factures:
tvas = HledgerSellEntry.get_tva_paiement_amounts(f.facture, journal="bank")
tvas = HledgerSellEntry.get_tva_payment_amounts(f.facture, journal="bank")
for k in tvas:
s += " %(account_tva)s \t %(amount_tva)s\n" % {
'account_tva': settings.get_ledger_account(k),
......@@ -199,25 +224,33 @@ class HledgerBankEntry(HledgerEntry):
return s
# get_entries: return the bank entries ordered by value date
@classmethod
def get_entries(cls, session):
return [cls(e) for e in session.query(cls.sql_class).order_by(Bank.datev, Bank.num_releve).all()]
class HledgerFactureEntry(HledgerEntry):
#
# HledgerBillingEntry: An entry corresponding to a bill (Supplier or Client)
#
class HledgerBillingEntry(HledgerEntry):
# get_entries: return the bill entries ordered by billing date
@classmethod
def get_entries(cls, session):
return [cls(e) for e in session.query(cls.sql_class).order_by(cls.sql_class.datef).all()]
# is_tva_facture: return if the value added tax must be processed on the billing date
@classmethod
def is_tva_facture(cls, ed):
return ed.productcls.tva_type == 'service_sur_debit' and ed.product_type == 1
# is_tva_paiement: return if the value-added tax must be processed on the payment date
@classmethod
def is_tva_paiement(cls, ed):
return cls.tva_type != 'service_sur_debit' or ed.product_type != 1
# get_tva_amounts: return the amount of value-added taxes.
@classmethod
def get_tva_amounts(cls, e, journal):
......@@ -257,6 +290,8 @@ class HledgerFactureEntry(HledgerEntry):
return tvas
# get_tva_regul_account: retourn the reference corresponding to the
# value-added tax regulation account
@classmethod
def get_tva_regul_account(cls, ed):
tx = int(float(ed.tva_tx) * 100)
......@@ -265,22 +300,25 @@ class HledgerFactureEntry(HledgerEntry):
return settings.get('PC_REFS')[key]
# Calcul de la tva à décaisser à paiement de la facture
#
# Cela du type de produit (bien ou service) et du type de tva
# get_tva_billing_amounts: return the value-added tax amount to collect
@classmethod
def get_tva_facture_amounts(cls, e, journal):
def get_tva_billing_amounts(cls, e, journal):
return cls.get_tva_amounts(e, journal)
# get_tva_payment_amounts: return value-added tax amount to deduce
@classmethod
def get_tva_paiement_amounts(cls, e, journal):
def get_tva_payment_amounts(cls, e, journal):
return cls.get_tva_amounts(e, journal)
class HledgerSupplierEntry(HledgerFactureEntry):
#
# HledgerSupplierEntry: Billing entry corresponding to a supplier
#
class HledgerSupplierEntry(HledgerBillingEntry):
sql_class = FactureFourn
k_accounting_date = 'datef'
# check: check if the entry is coherent
def check(self):
e = self.e
......@@ -300,17 +338,19 @@ class HledgerSupplierEntry(HledgerFactureEntry):
if total_tva > 1e-10:
print "Erreur dans l'écriture %s: total tva = %s" % (e.ref_supplier, total_tva)
# getMissingPC: retrieve missing accounts
def getMissingPC(self):
pc_missing = []
if e.societe.code_compta_fournisseur == "":
pc_missing.append("tiers:fournisseur: %s %s" % (e.societe.nom, s.societe.ape))
for ed in e.details:
if self.get_product_account_code(ed) == self.pc_default_charge:
if self.get_product_account_code(ed) == self.pc_default_expense:
pc_missing.append("achat: %s - %s" % (e.ref_supplier, ed.description.splitlines()[0]))
return pc_missing
# get_ledger: return the corresponding ledger entries
def get_ledger(self):
e = self.e
self.check()
......@@ -334,7 +374,7 @@ class HledgerSupplierEntry(HledgerFactureEntry):
'amount_ht': self._value(-ed.total_ht)
}
tvas = self.get_tva_facture_amounts(self.e, journal="supplier")
tvas = self.get_tva_billing_amounts(self.e, journal="supplier")
for k in tvas:
s += " %(compte_tva)s \t %(amount_tva)s\n" % {
'compte_tva': settings.get_ledger_account(k),
......@@ -343,6 +383,7 @@ class HledgerSupplierEntry(HledgerFactureEntry):
return s
# get_tva_account: return the value-added tax account