Browse Source

Allow to define sqlachemy class at runtime

Need to define the sqlalchemy according to the dolibarr version.
DolibarrSQLAlchemy embeds now the classes.
Philippe Le Brouster 8 years ago
parent
commit
6458a236f2
2 changed files with 371 additions and 501 deletions
  1. 302 461
      himports/dolibarrAlchemy.py
  2. 69 40
      himports/dolibarrAlchemyHledger.py

+ 302 - 461
himports/dolibarrAlchemy.py

@@ -4,466 +4,8 @@ from __future__ import unicode_literals
 from sqlalchemy import Column, Integer, ForeignKey, UniqueConstraint
 from sqlalchemy import Column, Integer, ForeignKey, UniqueConstraint
 from sqlalchemy.orm import relationship, sessionmaker
 from sqlalchemy.orm import relationship, sessionmaker
 from sqlalchemy.ext.declarative import declarative_base, DeferredReflection
 from sqlalchemy.ext.declarative import declarative_base, DeferredReflection
-
 from sqlalchemy import create_engine, MetaData
 from sqlalchemy import create_engine, MetaData
 
 
-Base = declarative_base(cls=DeferredReflection)
-
-
-class Bank(Base):
-    __tablename__ = "llx_bank"
-    id = Column("rowid", Integer, primary_key=True)
-
-    fk_account = Column('fk_account', Integer, ForeignKey('llx_bank_account.rowid'))
-    account = relationship("BankAccount", backref="entries", lazy="subquery")
-    bankclass = relationship(
-        "BankClass", backref="bank", uselist=False,
-        lazy="subquery"
-    )
-
-    url_company = relationship(
-        "BankUrl", uselist=False, backref="bank_company", innerjoin=True,
-        primaryjoin="and_(Bank.id==BankUrl.fk_bank, " "BankUrl.type=='company')",
-        lazy="subquery",
-    )
-    url_payment = relationship(
-        "BankUrl", uselist=False, backref="bank_payement", innerjoin=True,
-        primaryjoin="and_(Bank.id==BankUrl.fk_bank, " "BankUrl.type=='payment')",
-        lazy="subquery",
-    )
-    url_payment_sc = relationship(
-        "BankUrl", uselist=False, backref="bank_payement_sc", innerjoin=True,
-        primaryjoin="and_(Bank.id==BankUrl.fk_bank, " "BankUrl.type=='payment_sc')",
-        lazy="subquery",
-    )
-    url_payment_supplier = relationship(
-        "BankUrl", uselist=False, backref="bank_payement_supplier", innerjoin=True,
-        primaryjoin="and_(Bank.id==BankUrl.fk_bank, " "BankUrl.type=='payment_supplier')",
-        lazy="subquery",
-    )
-    payment_tva = relationship(
-        "TVA", backref="bank",
-        lazy="subquery"
-    )
-
-
-class BankAccount(Base):
-    __tablename__ = "llx_bank_account"
-    id = Column("rowid", Integer, primary_key=True)
-
-
-class BankCateg(Base):
-    __tablename__ = "llx_bank_categ"
-    id = Column("rowid", Integer, primary_key=True)
-
-
-class BankClass(Base):
-    __tablename__ = "llx_bank_class"
-    id = Column('lineid', Integer, ForeignKey('llx_bank.rowid'), primary_key=True)
-    UniqueConstraint('lineid', 'fk_categ')
-
-    categ_id = Column('fk_categ', Integer, ForeignKey('llx_bank_categ.rowid'))
-    categ = relationship(
-        "BankCateg", backref="classes",
-        lazy="subquery",
-    )
-
-
-class BankUrl(Base):
-    __tablename__ = "llx_bank_url"
-    id = Column("rowid", Integer, primary_key=True)
-    fk_bank = Column('fk_bank', Integer, ForeignKey('llx_bank.rowid'))
-    url_id = Column('url_id', Integer)
-    societe = relationship(
-        "Societe", backref="bank_urls", uselist=False,
-        primaryjoin="and_(BankUrl.url_id==Societe.id, " "BankUrl.type=='company')",
-        foreign_keys=url_id,
-        lazy="subquery",
-    )
-    payment = relationship(
-        "Paiement", backref="bank_urls", uselist=False,
-        primaryjoin="and_(BankUrl.url_id==Paiement.id, " "BankUrl.type=='payment')",
-        foreign_keys=url_id,
-        lazy="subquery",
-        order_by="Paiement.datep,Paiement.id",
-    )
-    payment_sc = relationship(
-        "PaiementCharge", backref="bank_urls", uselist=False,
-        primaryjoin="and_(BankUrl.url_id==PaiementCharge.id, " "BankUrl.type=='payment_sc')",
-        foreign_keys=url_id,
-        lazy="subquery",
-        order_by="PaiementCharge.datep,PaiementCharge.id",
-    )
-    payment_supplier = relationship(
-        "PaiementFourn", backref="bank_urls", uselist=False,
-        primaryjoin="and_(BankUrl.url_id==PaiementFourn.id, " "BankUrl.type=='payment_supplier')",
-        foreign_keys=url_id,
-        lazy="subquery",
-        order_by="PaiementFourn.datep,PaiementFourn.id",
-    )
-
-
-class TVA(Base):
-    __tablename__ = "llx_tva"
-    id = Column("rowid", Integer, primary_key=True)
-    fk_bank = Column('fk_bank', Integer, ForeignKey('llx_bank.rowid'))
-
-
-class CotisationsSociales(Base):
-    __tablename__ = "llx_chargesociales"
-    id = Column("rowid", Integer, primary_key=True)
-
-    fk_type = Column('fk_type', Integer, ForeignKey('llx_c_chargesociales.id'))
-    type = relationship(
-        "CCotisationsSociales", backref="cotisations_sociales",
-        lazy="subquery",
-    )
-
-
-class CCotisationsSociales(Base):
-    __tablename__ = "llx_c_chargesociales"
-    id = Column("id", Integer, primary_key=True)
-
-
-class Commande(Base):
-    __tablename__ = "llx_commande"
-    id = Column("rowid", Integer, primary_key=True)
-
-
-class CommandeDet(Base):
-    __tablename__ = "llx_commandedet"
-    id = Column("rowid", Integer, primary_key=True)
-
-    fk_commande = Column("fk_commande", Integer, ForeignKey('llx_commande.rowid'))
-    commande = relationship(
-        "Commande", backref="details",
-        lazy="subquery",
-    )
-    fk_product = Column("fk_product", Integer, ForeignKey('llx_product.rowid'))
-    product = relationship(
-        "Product", backref="commande_details",
-        lazy="subquery",
-    )
-
-
-class Societe(Base):
-    __tablename__ = "llx_societe"
-    id = Column("rowid", Integer, primary_key=True)
-
-
-class PaiementFacture(Base):
-    __tablename__ = "llx_paiement_facture"
-    fk_paiement = Column(Integer, ForeignKey('llx_paiement.rowid'), primary_key=True)
-    fk_facture = Column(Integer, ForeignKey('llx_facture.rowid'), primary_key=True)
-    facture = relationship(
-        "Facture",
-        lazy="subquery",
-        order_by="Facture.facnumber"
-    )
-    paiement = relationship(
-        "Paiement",
-        lazy="subquery",
-        order_by="Paiement.datep,Paiement.id",
-    )
-
-
-class Paiement(Base):
-    __tablename__ = "llx_paiement"
-    id = Column("rowid", Integer, primary_key=True)
-    factures = relationship(
-        "PaiementFacture",
-        lazy="subquery",
-        order_by="PaiementFacture.fk_facture,PaiementFacture.rowid",
-    )
-
-
-class PaiementFournFactureFourn(Base):
-    __tablename__ = "llx_paiementfourn_facturefourn"
-    fk_paiementfourn = Column(Integer, ForeignKey('llx_paiementfourn.rowid'), primary_key=True)
-    fk_facturefourn = Column(Integer, ForeignKey('llx_facture_fourn.rowid'), primary_key=True)
-    facture = relationship(
-        "FactureFourn",
-        lazy="subquery",
-    )
-    paiement = relationship(
-        "PaiementFourn",
-        lazy="subquery",
-        order_by="PaiementFourn.datep,PaiementFourn.id",
-    )
-
-
-class PaiementFourn(Base):
-    __tablename__ = "llx_paiementfourn"
-    id = Column("rowid", Integer, primary_key=True)
-    factures = relationship(
-        "PaiementFournFactureFourn",
-        lazy="subquery",
-    )
-
-
-class PaiementCharge(Base):
-    __tablename__ = "llx_paiementcharge"
-    id = Column("rowid", Integer, primary_key=True)
-
-    fk_bank = Column("fk_bank", Integer, ForeignKey('llx_bank.rowid'))
-    bank = relationship(
-        "Bank", backref="paiementcharges",
-        lazy="subquery",
-    )
-    fk_charge = Column(Integer, ForeignKey('llx_chargesociales.rowid'))
-    cotisation_sociale = relationship(
-        "CotisationsSociales", backref="paiement",
-        lazy="subquery"
-    )
-
-
-class Product(Base):
-    __tablename__ = "llx_product"
-    id = Column("rowid", Integer, primary_key=True)
-
-
-class FactureFourn(Base):
-    __tablename__ = "llx_facture_fourn"
-    id = Column("rowid", Integer, primary_key=True)
-
-    fk_soc = Column(Integer, ForeignKey('llx_societe.rowid'))
-    societe = relationship(
-        'Societe',
-        backref="factures_fournisseurs",
-        lazy="subquery",
-    )
-
-    details = relationship(
-        'FactureFournDet',
-        lazy="subquery",
-    )
-
-
-class Facture(Base):
-    __tablename__ = "llx_facture"
-    id = Column("rowid", Integer, primary_key=True)
-
-    fk_soc = Column(Integer, ForeignKey('llx_societe.rowid'))
-    societe = relationship(
-        'Societe',
-        backref="factures",
-        lazy="joined",
-    )
-
-    details = relationship(
-        'FactureDet',
-        lazy="subquery",
-    )
-
-
-class FactureDet(Base):
-    __tablename__ = "llx_facturedet"
-    id = Column("rowid", Integer, primary_key=True)
-
-    fk_facture = Column(Integer, ForeignKey('llx_facture.rowid'))
-    facture = relationship(
-        'Facture',
-        lazy="subquery",
-    )
-
-    fk_product = Column(Integer, ForeignKey('llx_product.rowid'))
-    product = relationship(
-        'Product',
-        backref="facture_det",
-        lazy="subquery",
-    )
-
-    fk_code_ventilation = Column(Integer, ForeignKey('llx_accountingaccount.rowid'))
-    accounting_account = relationship(
-        'AccountingAccount',
-        backref="facture_det",
-        lazy="subquery",
-    )
-
-
-class FactureFournDet(Base):
-    __tablename__ = "llx_facture_fourn_det"
-    id = Column("rowid", Integer, primary_key=True)
-
-    fk_facture_fourn = Column(Integer, ForeignKey('llx_facture_fourn.rowid'))
-    facture = relationship(
-        'FactureFourn',
-        lazy="subquery",
-    )
-
-    fk_product = Column(Integer, ForeignKey('llx_product.rowid'))
-    product = relationship(
-        'Product',
-        backref="facture_fourn_det",
-        lazy="subquery",
-    )
-
-    fk_code_ventilation = Column(Integer, ForeignKey('llx_accountingaccount.rowid'))
-    accounting_account = relationship(
-        'AccountingAccount',
-        backref="facture_fourn_det",
-        lazy="subquery",
-    )
-
-
-class AccountingAccount(Base):
-    __tablename__ = "llx_accountingaccount"
-    id = Column("rowid", Integer, primary_key=True)
-
-
-MYSQL_QUERIES = {
-    "bank": """SELECT DISTINCT b.rowid as b_rowid,
-                  ba.ref as ba_ref,
-                  ba.label as ba_label,
-                  ba.account_number as ba_account_number,
-                  b.datev as b_datev,
-                  b.dateo as b_dateo,
-                  b.label as b_label,
-                  b.num_chq as b_num_chq,
-                  -b.amount as _b_amount,
-                    b.amount as b_amount,
-                  b.num_releve as b_num_releve,
-                  b.datec as b_datec,
-                  bu.url_id as bu_url_id,
-                  s.nom as s_nom,
-                  s.code_compta as s_code_compta,
-                  s.code_compta_fournisseur as s_code_compta_fournisseur,
-                  bca.label as bca_label,
-                  bca.rowid as   bca_rowid,
-                  bcl.lineid as bcl_lineid,
-                  ccs.code as ccs_code,
-                  ccs.libelle as ccs_label
-              FROM (llx_bank_account as ba, llx_bank as b)
-              LEFT JOIN llx_bank_url as bu ON (bu.fk_bank = b.rowid AND bu.type = 'company')
-              LEFT JOIN llx_societe as s ON bu.url_id = s.rowid
-              LEFT JOIN llx_bank_class as   bcl ON bcl.lineid = b.rowid
-              LEFT JOIN llx_bank_categ as bca ON bca.rowid = bcl.fk_categ
-              LEFT JOIN llx_paiementcharge as p ON p.fk_bank = b.rowid
-              LEFT JOIN llx_chargesociales as cs ON cs.rowid = p.fk_charge
-              LEFT JOIN llx_c_chargesociales as ccs ON cs.fk_type = ccs.id
-              WHERE ba.rowid = b.fk_account AND ba.entity = 1 and b.num_releve <> ''
-              ORDER BY b.datev, b.num_releve;""",
-
-    "sells": """SELECT DISTINCT s.rowid as s_rowid,
-                  s.nom as s_nom,
-                  s.address as s_address,
-                  s.zip as s_zip,
-                  s.town as s_town,
-                  c.code as c_code,
-                  s.phone as s_phone,
-                  s.siren as s_siren,
-                  s.siret as s_siret,
-                  s.ape as s_ape,
-                  s.idprof4 as s_idprof4,
-                  s.code_compta as s_code_compta,
-                  s.code_compta_fournisseur as s_code_compta_fournisseur,
-                  s.tva_intra as s_tva_intra,
-                  f.rowid as f_rowid,
-                  f.facnumber as f_facnumber,
-                  f.datec as f_datec,
-                  f.datef as f_datef,
-                  f.date_lim_reglement as f_date_lim_reglement,
-                  f.total as f_total,
-                  f.total_ttc as f_total_ttc,
-                  f.tva as f_tva,
-                  f.paye as f_paye,
-                  f.fk_statut as f_fk_statut,
-                  f.note_private as f_note_private,
-                  f.note_public as f_note_public,
-                  fd.rowid as fd_rowid,
-                  fd.label as fd_label,
-                  fd.description as fd_description,
-                  fd.subprice as fd_subprice,
-                  fd.tva_tx as fd_tva_tx,
-                  fd.qty as fd_qty,
-                  fd.total_ht as fd_total_ht,
-                  fd.total_tva as fd_total_tva,
-                  fd.total_ttc as fd_total_ttc,
-                  fd.date_start as fd_date_start,
-                  fd.date_end as fd_date_end,
-                  fd.special_code as fd_special_code,
-                  fd.product_type as fd_product_type,
-                  fd.fk_product as fd_fk_product,
-                  p.ref as p_ref,
-                  p.label as p_label,
-                  p.accountancy_code_sell as p_accountancy_code_sell,
-                  a.account_number as a_account_number
-                FROM llx_societe as s
-                LEFT JOIN llx_c_pays as c on s.fk_pays = c.rowid, llx_facture as f
-                LEFT JOIN llx_facture_extrafields as extra ON f.rowid = extra.fk_object , llx_facturedet as fd
-                LEFT JOIN llx_product as p on (fd.fk_product = p.rowid)
-                LEFT JOIN llx_accountingaccount as a ON fd.fk_code_ventilation = a.rowid
-                WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_facture AND f.entity = 1""",
-
-    "suppliers": """SELECT DISTINCT s.rowid as s_rowid,
-                  s.nom as s_nom,
-                  s.address as s_address,
-                  s.zip as s_zip,
-                  s.town as s_town,
-                  s.code_compta_fournisseur as s_code_supplier,
-                  c.code as c_code,
-                  s.phone as s_phone,
-                  s.siren as s_siren,
-                  s.siret as s_siret,
-                  s.ape as s_ape,
-                  s.idprof4 as s_idprof4,
-                  s.idprof5 as s_idprof5,
-                  s.idprof6 as s_idprof6,
-                  s.tva_intra as s_tva_intra,
-                  f.rowid as f_rowid,
-                  f.ref as f_ref,
-                  f.ref_supplier as f_ref_supplier,
-                  f.datec as f_datec,
-                  f.datef as f_datef,
-                  f.total_ht as f_total_ht,
-                  f.total_ttc as f_total_ttc,
-                  f.total_tva as f_total_tva,
-                  f.paye as f_paye,
-                  f.fk_statut as f_fk_statut,
-                  f.note_public as f_note_public,
-                  fd.rowid as fd_rowid,
-                  fd.description as fd_description,
-                  fd.tva_tx as fd_tva_tx,
-                  fd.qty as fd_qty,
-                  fd.remise_percent as fd_remise_percent,
-                  fd.total_ht as fd_total_ht,
-                  fd.total_ttc as fd_total_ttc,
-                  fd.tva as fd_tva,
-                  fd.product_type as fd_product_type,
-                  fd.fk_product as fd_fk_product,
-                  p.ref as p_ref,
-                  p.label as p_label,
-                  p.accountancy_code_buy as p_accountancy_code_buy,
-                  a.account_number as a_account_number FROM llx_societe as s
-                  LEFT JOIN llx_c_pays as c
-                    ON s.fk_pays = c.rowid, llx_facture_fourn as f
-                  LEFT JOIN llx_facture_fourn_extrafields as extra
-                    ON f.rowid = extra.fk_object, llx_facture_fourn_det as fd
-                  LEFT JOIN llx_product as p on (fd.fk_product = p.rowid)
-                  LEFT JOIN llx_accountingaccount as a
-                    ON fd.fk_code_ventilation = a.rowid
-                    WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_facture_fourn AND f.entity = 1""",
-
-    "social": """SELECT DISTINCT cc.libelle as cc_libelle,
-                  c.rowid as c_rowid,
-                  c.libelle as c_libelle,
-                  c.date_ech as c_date_ech,
-                  c.periode as c_periode,
-                  c.amount as c_amount,
-                  c.paye as c_paye,
-                  p.rowid as p_rowid,
-                  p.datep as p_datep,
-                  p.amount as p_amount,
-                  p.num_paiement as p_num_paiement,
-                  cc.accountancy_code as cc_acc_code,
-                  cc.code as cc_code FROM llx_c_chargesociales as cc,
-                  llx_chargesociales as c
-                  LEFT JOIN llx_paiementcharge as p
-                    ON p.fk_charge = c.rowid
-                    WHERE c.fk_type = cc.id AND c.entity = 1""",
-
-}
-
 
 
 class DolibarrSQLAlchemy(object):
 class DolibarrSQLAlchemy(object):
 
 
@@ -490,11 +32,10 @@ class DolibarrSQLAlchemy(object):
             self.mysql_port,
             self.mysql_port,
             self.mysql_database
             self.mysql_database
         )
         )
-        print engine_str
+
         self.engine = create_engine(engine_str, echo=self.echo, encoding=str("iso8859-1"), convert_unicode=True)
         self.engine = create_engine(engine_str, echo=self.echo, encoding=str("iso8859-1"), convert_unicode=True)
-        self.metadata = MetaData(bind=self.engine)
 
 
-        Base.prepare(self.engine)
+        self.prepare()
 
 
         # create a configured "Session" class
         # create a configured "Session" class
         Session = sessionmaker(bind=self.engine)
         Session = sessionmaker(bind=self.engine)
@@ -502,5 +43,305 @@ class DolibarrSQLAlchemy(object):
         # create a Session
         # create a Session
         self.session = Session(autocommit=True)
         self.session = Session(autocommit=True)
 
 
+    def prepare(self):
+        version = self.engine.execute("SELECT value FROM llx_const WHERE name='MAIN_VERSION_LAST_UPGRADE'").fetchone()[0]
+        self.metadata = MetaData(bind=self.engine, info={'dolibarr_version': version})
+
+        Base = declarative_base(bind=self.engine, metadata=self.metadata)
+
+        class DolibarrBase(DeferredReflection, Base):
+            __abstract__ = True
+
+
+        class Bank(DolibarrBase):
+            __tablename__ = "llx_bank"
+            id = Column("rowid", Integer, primary_key=True)
+
+            fk_account = Column('fk_account', Integer, ForeignKey('llx_bank_account.rowid'))
+            account = relationship("BankAccount", backref="entries", lazy="subquery")
+            bankclass = relationship(
+                "BankClass", backref="bank", uselist=False,
+                lazy="subquery"
+            )
+
+            url_company = relationship(
+                "BankUrl", uselist=False, backref="bank_company", innerjoin=True,
+                primaryjoin="and_(Bank.id==BankUrl.fk_bank, " "BankUrl.type=='company')",
+                lazy="subquery",
+            )
+            url_payment = relationship(
+                "BankUrl", uselist=False, backref="bank_payement", innerjoin=True,
+                primaryjoin="and_(Bank.id==BankUrl.fk_bank, " "BankUrl.type=='payment')",
+                lazy="subquery",
+            )
+            url_payment_sc = relationship(
+                "BankUrl", uselist=False, backref="bank_payement_sc", innerjoin=True,
+                primaryjoin="and_(Bank.id==BankUrl.fk_bank, " "BankUrl.type=='payment_sc')",
+                lazy="subquery",
+            )
+            url_payment_supplier = relationship(
+                "BankUrl", uselist=False, backref="bank_payement_supplier", innerjoin=True,
+                primaryjoin="and_(Bank.id==BankUrl.fk_bank, " "BankUrl.type=='payment_supplier')",
+                lazy="subquery",
+            )
+            payment_tva = relationship(
+                "TVA", backref="bank",
+                lazy="subquery"
+            )
+
+        class BankAccount(DolibarrBase):
+            __tablename__ = "llx_bank_account"
+            id = Column("rowid", Integer, primary_key=True)
+
+        class BankCateg(DolibarrBase):
+            __tablename__ = "llx_bank_categ"
+            id = Column("rowid", Integer, primary_key=True)
+
+        class BankClass(DolibarrBase):
+            __tablename__ = "llx_bank_class"
+            id = Column('lineid', Integer, ForeignKey('llx_bank.rowid'), primary_key=True)
+            UniqueConstraint('lineid', 'fk_categ')
+
+            categ_id = Column('fk_categ', Integer, ForeignKey('llx_bank_categ.rowid'))
+            categ = relationship(
+                "BankCateg", backref="classes",
+                lazy="subquery",
+            )
+
+        class BankUrl(DolibarrBase):
+            __tablename__ = "llx_bank_url"
+            id = Column("rowid", Integer, primary_key=True)
+            fk_bank = Column('fk_bank', Integer, ForeignKey('llx_bank.rowid'))
+            url_id = Column('url_id', Integer)
+            societe = relationship(
+                "Societe", backref="bank_urls", uselist=False,
+                primaryjoin="and_(BankUrl.url_id==Societe.id, " "BankUrl.type=='company')",
+                foreign_keys=url_id,
+                lazy="subquery",
+            )
+            payment = relationship(
+                "Paiement", backref="bank_urls", uselist=False,
+                primaryjoin="and_(BankUrl.url_id==Paiement.id, " "BankUrl.type=='payment')",
+                foreign_keys=url_id,
+                lazy="subquery",
+                order_by="Paiement.datep,Paiement.id",
+            )
+            payment_sc = relationship(
+                "PaiementCharge", backref="bank_urls", uselist=False,
+                primaryjoin="and_(BankUrl.url_id==PaiementCharge.id, " "BankUrl.type=='payment_sc')",
+                foreign_keys=url_id,
+                lazy="subquery",
+                order_by="PaiementCharge.datep,PaiementCharge.id",
+            )
+            payment_supplier = relationship(
+                "PaiementFourn", backref="bank_urls", uselist=False,
+                primaryjoin="and_(BankUrl.url_id==PaiementFourn.id, " "BankUrl.type=='payment_supplier')",
+                foreign_keys=url_id,
+                lazy="subquery",
+                order_by="PaiementFourn.datep,PaiementFourn.id",
+            )
+
+        class TVA(DolibarrBase):
+            __tablename__ = "llx_tva"
+            id = Column("rowid", Integer, primary_key=True)
+            fk_bank = Column('fk_bank', Integer, ForeignKey('llx_bank.rowid'))
+
+        class CotisationsSociales(DolibarrBase):
+            __tablename__ = "llx_chargesociales"
+            id = Column("rowid", Integer, primary_key=True)
+
+            fk_type = Column('fk_type', Integer, ForeignKey('llx_c_chargesociales.id'))
+            type = relationship(
+                "CCotisationsSociales", backref="cotisations_sociales",
+                lazy="subquery",
+            )
+
+        class CCotisationsSociales(DolibarrBase):
+            __tablename__ = "llx_c_chargesociales"
+            id = Column("id", Integer, primary_key=True)
+
+        class Commande(DolibarrBase):
+            __tablename__ = "llx_commande"
+            id = Column("rowid", Integer, primary_key=True)
+
+        class CommandeDet(DolibarrBase):
+            __tablename__ = "llx_commandedet"
+            id = Column("rowid", Integer, primary_key=True)
+
+            fk_commande = Column("fk_commande", Integer, ForeignKey('llx_commande.rowid'))
+            commande = relationship(
+                "Commande", backref="details",
+                lazy="subquery",
+            )
+            fk_product = Column("fk_product", Integer, ForeignKey('llx_product.rowid'))
+            product = relationship(
+                "Product", backref="commande_details",
+                lazy="subquery",
+            )
+
+        class Societe(DolibarrBase):
+            __tablename__ = "llx_societe"
+            id = Column("rowid", Integer, primary_key=True)
+
+        class PaiementFacture(DolibarrBase):
+            __tablename__ = "llx_paiement_facture"
+            fk_paiement = Column(Integer, ForeignKey('llx_paiement.rowid'), primary_key=True)
+            fk_facture = Column(Integer, ForeignKey('llx_facture.rowid'), primary_key=True)
+            facture = relationship(
+                "Facture",
+                lazy="subquery",
+                order_by="Facture.facnumber"
+            )
+            paiement = relationship(
+                "Paiement",
+                lazy="subquery",
+                order_by="Paiement.datep,Paiement.id",
+            )
+
+        class Paiement(DolibarrBase):
+            __tablename__ = "llx_paiement"
+            id = Column("rowid", Integer, primary_key=True)
+            factures = relationship(
+                "PaiementFacture",
+                lazy="subquery",
+                order_by="PaiementFacture.fk_facture,PaiementFacture.rowid",
+            )
+
+        class PaiementFournFactureFourn(DolibarrBase):
+            __tablename__ = "llx_paiementfourn_facturefourn"
+            fk_paiementfourn = Column(Integer, ForeignKey('llx_paiementfourn.rowid'), primary_key=True)
+            fk_facturefourn = Column(Integer, ForeignKey('llx_facture_fourn.rowid'), primary_key=True)
+            facture = relationship(
+                "FactureFourn",
+                lazy="subquery",
+            )
+            paiement = relationship(
+                "PaiementFourn",
+                lazy="subquery",
+                order_by="PaiementFourn.datep,PaiementFourn.id",
+            )
+
+        class PaiementFourn(DolibarrBase):
+            __tablename__ = "llx_paiementfourn"
+            id = Column("rowid", Integer, primary_key=True)
+            factures = relationship(
+                "PaiementFournFactureFourn",
+                lazy="subquery",
+            )
+
+        class PaiementCharge(DolibarrBase):
+            __tablename__ = "llx_paiementcharge"
+            id = Column("rowid", Integer, primary_key=True)
+
+            fk_bank = Column("fk_bank", Integer, ForeignKey('llx_bank.rowid'))
+            bank = relationship(
+                "Bank", backref="paiementcharges",
+                lazy="subquery",
+            )
+            fk_charge = Column(Integer, ForeignKey('llx_chargesociales.rowid'))
+            cotisation_sociale = relationship(
+                "CotisationsSociales", backref="paiement",
+                lazy="subquery"
+            )
+
+        class Product(DolibarrBase):
+            __tablename__ = "llx_product"
+            id = Column("rowid", Integer, primary_key=True)
+
+        class FactureFourn(DolibarrBase):
+            __tablename__ = "llx_facture_fourn"
+            id = Column("rowid", Integer, primary_key=True)
+
+            fk_soc = Column(Integer, ForeignKey('llx_societe.rowid'))
+            societe = relationship(
+                'Societe',
+                backref="factures_fournisseurs",
+                lazy="subquery",
+            )
+
+            details = relationship(
+                'FactureFournDet',
+                lazy="subquery",
+            )
+
+        class Facture(DolibarrBase):
+            __tablename__ = "llx_facture"
+            id = Column("rowid", Integer, primary_key=True)
+
+            fk_soc = Column(Integer, ForeignKey('llx_societe.rowid'))
+            societe = relationship(
+                'Societe',
+                backref="factures",
+                lazy="joined",
+            )
+
+            details = relationship(
+                'FactureDet',
+                lazy="subquery",
+            )
+
+        class FactureDet(DolibarrBase):
+            __tablename__ = "llx_facturedet"
+            id = Column("rowid", Integer, primary_key=True)
+
+            fk_facture = Column(Integer, ForeignKey('llx_facture.rowid'))
+            facture = relationship(
+                'Facture',
+                lazy="subquery",
+            )
+
+            fk_product = Column(Integer, ForeignKey('llx_product.rowid'))
+            product = relationship(
+                'Product',
+                backref="facture_det",
+                lazy="subquery",
+            )
+
+            fk_code_ventilation = Column(Integer, ForeignKey('llx_accountingaccount.rowid'))
+            accounting_account = relationship(
+                'AccountingAccount',
+                backref="facture_det",
+                lazy="subquery",
+            )
+
+
+        class FactureFournDet(DolibarrBase):
+            __tablename__ = "llx_facture_fourn_det"
+            id = Column("rowid", Integer, primary_key=True)
+
+            fk_facture_fourn = Column(Integer, ForeignKey('llx_facture_fourn.rowid'))
+            facture = relationship(
+                'FactureFourn',
+                lazy="subquery",
+            )
+
+            fk_product = Column(Integer, ForeignKey('llx_product.rowid'))
+            product = relationship(
+                'Product',
+                backref="facture_fourn_det",
+                lazy="subquery",
+            )
+
+            fk_code_ventilation = Column(Integer, ForeignKey('llx_accountingaccount.rowid'))
+            accounting_account = relationship(
+                'AccountingAccount',
+                backref="facture_fourn_det",
+                lazy="subquery",
+            )
+
+
+        class AccountingAccount(DolibarrBase):
+
+            __tablename__ = "llx_accountingaccount"
+            id = Column("rowid", Integer, primary_key=True)
+
+
+        self.Bank = Bank
+        self.Facture = Facture
+        self.FactureFourn = FactureFourn
+        self.CotisationsSociales = CotisationsSociales
+
+        DolibarrBase.prepare(self.engine)
+
     def disconnect(self):
     def disconnect(self):
         self.session.close()
         self.session.close()

+ 69 - 40
himports/dolibarrAlchemyHledger.py

@@ -4,7 +4,7 @@ from __future__ import unicode_literals
 import settings
 import settings
 import datetime
 import datetime
 
 
-from himports.dolibarrAlchemy import *
+from himports.dolibarrAlchemy import DolibarrSQLAlchemy
 
 
 
 
 #
 #
@@ -21,14 +21,19 @@ class HledgerEntry(object):
 
 
     tva_type = settings.get('TVA_TYPE')
     tva_type = settings.get('TVA_TYPE')
 
 
+    # the sql class need to be defined in the derived classes
+    def _sql_class(self):
+        assert(False)
+
     # the sql_class corresponding the hledger class
     # the sql_class corresponding the hledger class
-    sql_class = None
+    sql_class = property(_sql_class)
 
 
     # Date defining the current accounting year
     # Date defining the current accounting year
     k_accounting_date = None
     k_accounting_date = None
 
 
-    def __init__(self, e):
+    def __init__(self, dolibarr_alchemy, e):
         super(HledgerEntry, self).__init__()
         super(HledgerEntry, self).__init__()
+        self.dolibarr_alchemy = dolibarr_alchemy
         self.e = e
         self.e = e
         self.accounting_date = e
         self.accounting_date = e
         for attr in self.k_accounting_date.split('.'):
         for attr in self.k_accounting_date.split('.'):
@@ -36,8 +41,8 @@ class HledgerEntry(object):
 
 
     # Retrieve all entries corresponding to cls.sql_class
     # Retrieve all entries corresponding to cls.sql_class
     @classmethod
     @classmethod
-    def get_entries(cls, session):
-        return [cls(i) for i in session.query(cls.sql_class).all()]
+    def get_entries(cls, dolibarr_alchemy):
+        return [cls(dolibarr_alchemy, i) for i in dolibarr_alchemy.session.query(cls.sql_class).all()]
 
 
     # get_ledger : Print ledger output. Only defined in derived class
     # get_ledger : Print ledger output. Only defined in derived class
     def get_ledger(self):
     def get_ledger(self):
@@ -73,8 +78,9 @@ class HledgerEntry(object):
 # HledgerJournal: A complete Hledger journal. This is a base class.
 # HledgerJournal: A complete Hledger journal. This is a base class.
 #
 #
 class HledgerJournal(object):
 class HledgerJournal(object):
-    def __init__(self, session, cls_entry):
-        self.entries = cls_entry.get_entries(session)
+    def __init__(self, dolibarr_alchemy, cls_entry):
+        self.dolibarr_alchemy = dolibarr_alchemy
+        self.entries = cls_entry.get_entries(dolibarr_alchemy)
 
 
     # get_entries: return the journal entries
     # get_entries: return the journal entries
     def get_entries(self):
     def get_entries(self):
@@ -104,9 +110,18 @@ class HledgerJournal(object):
 # HledgerBankEntry: a bank entry
 # HledgerBankEntry: a bank entry
 #
 #
 class HledgerBankEntry(HledgerEntry):
 class HledgerBankEntry(HledgerEntry):
-    sql_class = Bank
     k_accounting_date = 'datev'
     k_accounting_date = 'datev'
 
 
+    def _sql_class(self):
+        return self.dolibarr_alchemy.Bank
+
+    # get_entries: return the bank entries ordered by value date
+    @classmethod
+    def get_entries(cls, dolibarr_alchemy):
+        Bank = dolibarr_alchemy.Bank
+        entries = dolibarr_alchemy.session.query(Bank).order_by(Bank.datev, Bank.num_releve).all()
+        return [cls(dolibarr_alchemy, e) for e in entries]
+
     # get_third_code: retrieve the third code corresponding to the entry. It could be
     # get_third_code: retrieve the third code corresponding to the entry. It could be
     #       a supplier payment
     #       a supplier payment
     #       a tax payment
     #       a tax payment
@@ -205,7 +220,7 @@ class HledgerBankEntry(HledgerEntry):
 
 
         if e.url_payment_supplier:
         if e.url_payment_supplier:
             for f in e.url_payment_supplier.payment_supplier.factures:
             for f in e.url_payment_supplier.payment_supplier.factures:
-                tvas = HledgerSupplierEntry.get_tva_payment_amounts(f.facture, journal="bank")
+                tvas = HledgerSupplierEntry.get_tva_payment_amounts(self.dolibarr_alchemy, f.facture, journal="bank")
                 for k in tvas:
                 for k in tvas:
                     s += "    %(account_tva)s \t %(amount_tva)s\n" % {
                     s += "    %(account_tva)s \t %(amount_tva)s\n" % {
                         'account_tva': settings.get_ledger_account(k),
                         'account_tva': settings.get_ledger_account(k),
@@ -213,7 +228,7 @@ class HledgerBankEntry(HledgerEntry):
                     }
                     }
         elif e.url_payment:
         elif e.url_payment:
             for f in e.url_payment.payment.factures:
             for f in e.url_payment.payment.factures:
-                tvas = HledgerSellEntry.get_tva_payment_amounts(f.facture, journal="bank")
+                tvas = HledgerSellEntry.get_tva_payment_amounts(self.dolibarr_alchemy, f.facture, journal="bank")
                 for k in tvas:
                 for k in tvas:
                     s += "    %(account_tva)s \t %(amount_tva)s\n" % {
                     s += "    %(account_tva)s \t %(amount_tva)s\n" % {
                         'account_tva': settings.get_ledger_account(k),
                         'account_tva': settings.get_ledger_account(k),
@@ -224,22 +239,12 @@ class HledgerBankEntry(HledgerEntry):
 
 
         return s
         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()]
-
 
 
 #
 #
 # HledgerBillingEntry: An entry corresponding to a bill (Supplier or Client)
 # HledgerBillingEntry: An entry corresponding to a bill (Supplier or Client)
 #
 #
 class HledgerBillingEntry(HledgerEntry):
 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
     # is_tva_facture: return if the value added tax must be processed on the billing date
     @classmethod
     @classmethod
     def is_tva_facture(cls, ed):
     def is_tva_facture(cls, ed):
@@ -252,13 +257,13 @@ class HledgerBillingEntry(HledgerEntry):
 
 
     # get_tva_amounts: return the amount of value-added taxes.
     # get_tva_amounts: return the amount of value-added taxes.
     @classmethod
     @classmethod
-    def get_tva_amounts(cls, e, journal):
+    def get_tva_amounts(cls, dolibarr_alchemy, e, journal):
 
 
         tvas = dict()
         tvas = dict()
         for ed in e.details:
         for ed in e.details:
-            if isinstance(e, Facture):
+            if isinstance(e, dolibarr_alchemy.Facture):
                 total_tva = -ed.total_tva
                 total_tva = -ed.total_tva
-            elif isinstance(e, FactureFourn):
+            elif isinstance(e, dolibarr_alchemy.FactureFourn):
                 total_tva = ed.tva
                 total_tva = ed.tva
             else:
             else:
                 raise Exception("Should be either Facture or FactureFourn")
                 raise Exception("Should be either Facture or FactureFourn")
@@ -302,22 +307,31 @@ class HledgerBillingEntry(HledgerEntry):
 
 
     # get_tva_billing_amounts: return the value-added tax amount to collect
     # get_tva_billing_amounts: return the value-added tax amount to collect
     @classmethod
     @classmethod
-    def get_tva_billing_amounts(cls, e, journal):
-        return cls.get_tva_amounts(e, journal)
+    def get_tva_billing_amounts(cls, dolibarr_alchemy, e, journal):
+        return cls.get_tva_amounts(dolibarr_alchemy, e, journal)
 
 
     # get_tva_payment_amounts: return value-added tax amount to deduce
     # get_tva_payment_amounts: return value-added tax amount to deduce
     @classmethod
     @classmethod
-    def get_tva_payment_amounts(cls, e, journal):
-        return cls.get_tva_amounts(e, journal)
+    def get_tva_payment_amounts(cls, dolibarr_alchemy, e, journal):
+        return cls.get_tva_amounts(dolibarr_alchemy, e, journal)
 
 
 
 
 #
 #
 # HledgerSupplierEntry: Billing entry corresponding to a supplier
 # HledgerSupplierEntry: Billing entry corresponding to a supplier
 #
 #
 class HledgerSupplierEntry(HledgerBillingEntry):
 class HledgerSupplierEntry(HledgerBillingEntry):
-    sql_class = FactureFourn
+
     k_accounting_date = 'datef'
     k_accounting_date = 'datef'
 
 
+    def _sql_class(self):
+        return self.dolibarr_alchemy.FactureFourn
+
+    # get_entries: return the bill entries ordered by billing date
+    @classmethod
+    def get_entries(cls, dolibarr_alchemy):
+        FactureFourn = dolibarr_alchemy.FactureFourn
+        return [cls(dolibarr_alchemy, e) for e in dolibarr_alchemy.session.query(FactureFourn).order_by(FactureFourn.datef).all()]
+
     # check: check if the entry is coherent
     # check: check if the entry is coherent
     def check(self):
     def check(self):
         e = self.e
         e = self.e
@@ -340,9 +354,10 @@ class HledgerSupplierEntry(HledgerBillingEntry):
 
 
     # getMissingPC: retrieve missing accounts
     # getMissingPC: retrieve missing accounts
     def getMissingPC(self):
     def getMissingPC(self):
+        e = self.e
         pc_missing = []
         pc_missing = []
         if e.societe.code_compta_fournisseur == "":
         if e.societe.code_compta_fournisseur == "":
-            pc_missing.append("tiers:fournisseur: %s %s" % (e.societe.nom, s.societe.ape))
+            pc_missing.append("tiers:fournisseur: %s %s" % (e.societe.nom, e.societe.ape))
 
 
         for ed in e.details:
         for ed in e.details:
             if self.get_product_account_code(ed) == self.pc_default_expense:
             if self.get_product_account_code(ed) == self.pc_default_expense:
@@ -374,7 +389,7 @@ class HledgerSupplierEntry(HledgerBillingEntry):
                 'amount_ht': self._value(-ed.total_ht)
                 'amount_ht': self._value(-ed.total_ht)
             }
             }
 
 
-        tvas = self.get_tva_billing_amounts(self.e, journal="supplier")
+        tvas = self.get_tva_billing_amounts(self.dolibarr_alchemy, self.e, journal="supplier")
         for k in tvas:
         for k in tvas:
             s += "    %(compte_tva)s \t %(amount_tva)s\n" % {
             s += "    %(compte_tva)s \t %(amount_tva)s\n" % {
                 'compte_tva': settings.get_ledger_account(k),
                 'compte_tva': settings.get_ledger_account(k),
@@ -417,13 +432,22 @@ class HledgerSupplierEntry(HledgerBillingEntry):
             s_code = cls.pc_default_supplier
             s_code = cls.pc_default_supplier
         return s_code
         return s_code
 
 
+
 #
 #
 # HledgerSellEntry: The billing entry corresponding to a client
 # HledgerSellEntry: The billing entry corresponding to a client
 #
 #
 class HledgerSellEntry(HledgerBillingEntry):
 class HledgerSellEntry(HledgerBillingEntry):
-    sql_class = Facture
     k_accounting_date = 'datef'
     k_accounting_date = 'datef'
 
 
+    def _sql_class(self):
+        return self.dolibarr_alchemy.Facture
+
+    # get_entries: return the bill entries ordered by billing date
+    @classmethod
+    def get_entries(cls, dolibarr_alchemy):
+        Facture = dolibarr_alchemy.Facture
+        return [cls(dolibarr_alchemy, e) for e in dolibarr_alchemy.session.query(Facture).order_by(Facture.datef).all()]
+
     # get_ledger: return the ledger corresping to this entry
     # get_ledger: return the ledger corresping to this entry
     def get_ledger(self):
     def get_ledger(self):
         e = self.e
         e = self.e
@@ -453,7 +477,7 @@ class HledgerSellEntry(HledgerBillingEntry):
             }
             }
 
 
         # lignes pour la tva
         # lignes pour la tva
-        tvas = self.get_tva_billing_amounts(self.e, journal="sell")
+        tvas = self.get_tva_billing_amounts(self.dolibarr_alchemy, self.e, journal="sell")
         for k in tvas:
         for k in tvas:
             s += "    %(compte_tva)s  %(amount_tva)s\n" % {
             s += "    %(compte_tva)s  %(amount_tva)s\n" % {
                 'compte_tva': settings.get_ledger_account(k),
                 'compte_tva': settings.get_ledger_account(k),
@@ -474,7 +498,7 @@ class HledgerSellEntry(HledgerBillingEntry):
         e = self.e
         e = self.e
         pc_missing = []
         pc_missing = []
         if e.societe.code_compta == "":
         if e.societe.code_compta == "":
-            pc_missing.append("tiers: %s %s" % (e.societe.nom, s.societe.ape))
+            pc_missing.append("tiers: %s %s" % (e.societe.nom, e.societe.ape))
 
 
         for ed in e.details:
         for ed in e.details:
             if self.get_product_account_code(ed) == self.pc_default_income:
             if self.get_product_account_code(ed) == self.pc_default_income:
@@ -530,13 +554,17 @@ class HledgerSellEntry(HledgerBillingEntry):
 # HledgerSocialEntry: A ledger entry corresponding to a tax
 # HledgerSocialEntry: A ledger entry corresponding to a tax
 #
 #
 class HledgerSocialEntry(HledgerEntry):
 class HledgerSocialEntry(HledgerEntry):
-    sql_class = CotisationsSociales
     k_accounting_date = 'date_ech'
     k_accounting_date = 'date_ech'
 
 
+    def _sql_class(self):
+        return self.dolibarr_alchemy.CotisationsSociales
+
     # get_entries: retrieve all the entries for this entry type
     # get_entries: retrieve all the entries for this entry type
     @classmethod
     @classmethod
-    def get_entries(cls, session):
-        return [cls(e) for e in session.query(cls.sql_class).order_by(CotisationsSociales.date_ech).all()]
+    def get_entries(cls, dolibarr_alchemy):
+        CotisationsSociales = dolibarr_alchemy.CotisationsSociales
+        entries = dolibarr_alchemy.session.query(CotisationsSociales).order_by(CotisationsSociales.date_ech).all()
+        return [cls(dolibarr_alchemy, e) for e in entries]
 
 
     # get_third_code: return the third accounting code for this entry
     # get_third_code: return the third accounting code for this entry
     @classmethod
     @classmethod
@@ -560,6 +588,7 @@ class HledgerSocialEntry(HledgerEntry):
 
 
     # getMissingPC: return the missing accounting code for this entry
     # getMissingPC: return the missing accounting code for this entry
     def getMissingPC(self):
     def getMissingPC(self):
+        e = self.e
         pc_missing = []
         pc_missing = []
         if self.get_social_code(self.e) == self.pc_default_expense:
         if self.get_social_code(self.e) == self.pc_default_expense:
             pc_missing.append("expenses: %s" % (e.libelle))
             pc_missing.append("expenses: %s" % (e.libelle))
@@ -605,13 +634,13 @@ class HledgerSocialEntry(HledgerEntry):
 #
 #
 class HledgerDolibarrSQLAlchemy(DolibarrSQLAlchemy):
 class HledgerDolibarrSQLAlchemy(DolibarrSQLAlchemy):
     def get_bank_journal(self):
     def get_bank_journal(self):
-        return HledgerJournal(self.session, HledgerBankEntry)
+        return HledgerJournal(self, HledgerBankEntry)
 
 
     def get_supplier_journal(self):
     def get_supplier_journal(self):
-        return HledgerJournal(self.session, HledgerSupplierEntry)
+        return HledgerJournal(self, HledgerSupplierEntry)
 
 
     def get_sell_journal(self):
     def get_sell_journal(self):
-        return HledgerJournal(self.session, HledgerSellEntry)
+        return HledgerJournal(self, HledgerSellEntry)
 
 
     def get_social_journal(self):
     def get_social_journal(self):
-        return HledgerJournal(self.session, HledgerSocialEntry)
+        return HledgerJournal(self, HledgerSocialEntry)