dolibarrAlchemyHledger.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. import settings
  4. import datetime
  5. from himports.dolibarrAlchemy import DolibarrSQLAlchemy
  6. #
  7. # HledgerEntry : Base class for an hledger entry
  8. #
  9. class HledgerEntry(object):
  10. accounting_years = settings.get('ACCOUNTING_YEARS')
  11. pc_default_tier = settings.get('PC_REFS')['default_tier']
  12. pc_default_client = settings.get('PC_REFS')['default_client']
  13. pc_default_supplier = settings.get('PC_REFS')['default_supplier']
  14. pc_default_income = settings.get('PC_REFS')['default_income']
  15. pc_default_expense = settings.get('PC_REFS')['default_expense']
  16. pc_default_bank = settings.get('PC_REFS')['default_bank']
  17. tva_type = settings.get('TVA_TYPE')
  18. # the sql class need to be defined in the derived classes
  19. def _sql_class(self):
  20. assert(False)
  21. # the sql_class corresponding the hledger class
  22. sql_class = property(_sql_class)
  23. # Date defining the current accounting year
  24. k_accounting_date = None
  25. def __init__(self, dolibarr_alchemy, e):
  26. super(HledgerEntry, self).__init__()
  27. self.dolibarr_alchemy = dolibarr_alchemy
  28. self.e = e
  29. self.accounting_date = e
  30. for attr in self.k_accounting_date.split('.'):
  31. self.accounting_date = getattr(self.accounting_date, attr)
  32. # Retrieve all entries corresponding to cls.sql_class
  33. @classmethod
  34. def get_entries(cls, dolibarr_alchemy):
  35. return [cls(dolibarr_alchemy, i) for i in dolibarr_alchemy.session.query(cls.sql_class).all()]
  36. # get_ledger : Print ledger output. Only defined in derived class
  37. def get_ledger(self):
  38. print("WARNING: get_ledger not done")
  39. return u""
  40. # check_pc : verify the accounting chart corresponding to the entry. Only defined in derived class.
  41. def check_pc(self):
  42. return ()
  43. # get_year: return the year corresponding to the current entry. Only defined in derived class.
  44. def get_year(self):
  45. raise Exception("TODO: get_year not implemented for class %s" % (self.__class__))
  46. # get_accounting_year: return the accouting year corresponding to the current entry.
  47. def get_accounting_year(self):
  48. date = self.accounting_date
  49. if isinstance(date, datetime.datetime):
  50. date = date.date()
  51. for (year, dbegin, dend) in HledgerEntry.accounting_years:
  52. if date >= dbegin and date <= dend:
  53. return year
  54. return str(date.year)
  55. # _value: return the value in float with 4 digits
  56. @staticmethod
  57. def _value(value):
  58. return '{number:.{digits}f}'.format(number=value, digits=4)
  59. #
  60. # HledgerJournal: A complete Hledger journal. This is a base class.
  61. #
  62. class HledgerJournal(object):
  63. def __init__(self, dolibarr_alchemy, cls_entry):
  64. self.dolibarr_alchemy = dolibarr_alchemy
  65. self.entries = cls_entry.get_entries(dolibarr_alchemy)
  66. # get_entries: return the journal entries
  67. def get_entries(self):
  68. return self.entries
  69. # get_by_year: return the journal entries by accounting year.
  70. def get_by_year(self):
  71. by_year = {}
  72. for entry in self.get_entries():
  73. entry_year = entry.get_accounting_year()
  74. if entry_year not in by_year:
  75. by_year[entry_year] = []
  76. by_year[entry_year].append(entry)
  77. return by_year
  78. # check_pc: verify there is an account for earch entry on the current journal
  79. def check_pc(self):
  80. pc_missing = set()
  81. for entry in self.get_entries():
  82. pc_missing.update(entry.check_pc())
  83. return pc_missing
  84. #
  85. # HledgerBankEntry: a bank entry
  86. #
  87. class HledgerBankEntry(HledgerEntry):
  88. k_accounting_date = 'datev'
  89. def _sql_class(self):
  90. return self.dolibarr_alchemy.Bank
  91. # get_entries: return the bank entries ordered by value date
  92. @classmethod
  93. def get_entries(cls, dolibarr_alchemy):
  94. Bank = dolibarr_alchemy.Bank
  95. entries = dolibarr_alchemy.session.query(Bank).order_by(Bank.datev, Bank.num_releve).all()
  96. return [cls(dolibarr_alchemy, e) for e in entries]
  97. # get_third_code: retrieve the third code corresponding to the entry. It could be
  98. # a supplier payment
  99. # a tax payment
  100. # a customer payment
  101. # a value-added tax payment
  102. # any payment defined in the function PC_REFS['fn_custom_codes']
  103. @classmethod
  104. def get_third_code(cls, e):
  105. third_code = ""
  106. if e.url_payment_supplier:
  107. if e.url_company:
  108. third_code = e.url_company.societe.code_compta_fournisseur
  109. if e.url_payment_sc:
  110. code = e.url_payment_sc.payment_sc.cotisation_sociale.type.code
  111. if code in settings.get('SOCIAL_REFS'):
  112. third_code = settings.get('SOCIAL_REFS')[code]
  113. if e.url_payment:
  114. if e.url_company:
  115. third_code = e.url_company.societe.code_compta
  116. if e.payment_tva:
  117. third_code = settings.get('PC_REFS')['tva_a_decaisser']
  118. if third_code == "":
  119. fns = settings.get('PC_REFS')['fn_custom_codes']
  120. for fn in fns:
  121. try:
  122. third_code = fn(e)
  123. if third_code is None or not isinstance(third_code, basestring):
  124. third_code = ""
  125. except:
  126. third_code = ""
  127. if third_code != "":
  128. break
  129. if third_code == "":
  130. third_code = cls.pc_default_tier
  131. return third_code
  132. # get_description: retrieve the description of the payment
  133. @classmethod
  134. def get_description(self, e):
  135. s_nom = ""
  136. s_description = ""
  137. if e.url_company:
  138. s_nom = e.url_company.societe.nom
  139. if e.url_payment_supplier:
  140. f_ids = [f.facture.ref_supplier for f in e.url_payment_supplier.payment_supplier.factures]
  141. s_description = "Règlement facture fournisseur - %s - %s" % (
  142. s_nom,
  143. "|".join(f_ids),
  144. )
  145. if e.url_payment:
  146. f_ids = [f.facture.facnumber for f in e.url_payment.payment.factures]
  147. s_description = "Règlement facture client - %s - %s" % (
  148. s_nom,
  149. "|".join(f_ids),
  150. )
  151. if s_description == "":
  152. s_description = s_nom + " - " + e.label
  153. return s_description
  154. # get_ledger: see @HledgerEntry.get_ledger
  155. def get_ledger(self):
  156. e = self.e
  157. s = ""
  158. s_description = self.get_description(self.e)
  159. s += "%(date)s %(description)s\n" % {
  160. 'date': e.datev.strftime("%Y/%m/%d"),
  161. 'description': s_description
  162. }
  163. third_code = self.get_third_code(self.e)
  164. ba_code = e.account.account_number
  165. if ba_code == "":
  166. ba_code = self.pc_default_bank
  167. s += " %(account)s \t %(amount)s\n" % {
  168. 'account': settings.get_ledger_account(ba_code),
  169. 'amount': self._value(-e.amount)
  170. }
  171. s += " %(account)s \t %(amount)s\n" % {
  172. 'account': settings.get_ledger_account(third_code),
  173. 'amount': self._value(e.amount)
  174. }
  175. if self.tva_type != 'none':
  176. if e.url_payment_supplier:
  177. for f in e.url_payment_supplier.payment_supplier.factures:
  178. tvas = HledgerSupplierEntry.get_tva_payment_amounts(self.dolibarr_alchemy, f.facture, journal="bank")
  179. for k in tvas:
  180. s += " %(account_tva)s \t %(amount_tva)s\n" % {
  181. 'account_tva': settings.get_ledger_account(k),
  182. 'amount_tva': self._value(tvas[k] * (f.amount / f.facture.total_ttc))
  183. }
  184. elif e.url_payment:
  185. for f in e.url_payment.payment.factures:
  186. tvas = HledgerSellEntry.get_tva_payment_amounts(self.dolibarr_alchemy, f.facture, journal="bank")
  187. for k in tvas:
  188. s += " %(account_tva)s \t %(amount_tva)s\n" % {
  189. 'account_tva': settings.get_ledger_account(k),
  190. 'amount_tva': self._value(tvas[k] * (f.amount / f.facture.total_ttc))
  191. }
  192. else:
  193. pass
  194. return s
  195. #
  196. # HledgerBillingEntry: An entry corresponding to a bill (Supplier or Client)
  197. #
  198. class HledgerBillingEntry(HledgerEntry):
  199. # is_tva_facture: return if the value added tax must be processed on the billing date
  200. @classmethod
  201. def is_tva_facture(cls, ed):
  202. return ed.productcls.tva_type == 'service_sur_debit' and ed.product_type == 1
  203. # is_tva_paiement: return if the value-added tax must be processed on the payment date
  204. @classmethod
  205. def is_tva_paiement(cls, ed):
  206. return cls.tva_type != 'service_sur_debit' or ed.product_type != 1
  207. # get_tva_amounts: return the amount of value-added taxes.
  208. @classmethod
  209. def get_tva_amounts(cls, dolibarr_alchemy, e, journal):
  210. tvas = dict()
  211. for ed in e.details:
  212. if isinstance(e, dolibarr_alchemy.Facture):
  213. total_tva = -ed.total_tva
  214. elif isinstance(e, dolibarr_alchemy.FactureFourn):
  215. total_tva = ed.tva
  216. else:
  217. raise Exception("Should be either Facture or FactureFourn")
  218. if total_tva == 0:
  219. continue
  220. tva_account = cls.get_tva_account(ed)
  221. tva_regul = cls.get_tva_regul_account(ed)
  222. if journal == "bank":
  223. if ed.product_type == 1 and cls.tva_type == 'standard':
  224. if tva_regul not in tvas:
  225. tvas[tva_regul] = 0
  226. if tva_account not in tvas:
  227. tvas[tva_account] = 0
  228. tvas[tva_account] += -total_tva
  229. tvas[tva_regul] += total_tva
  230. elif journal == "sell" or journal == "supplier":
  231. if ed.product_type == 1 and cls.tva_type == 'standard':
  232. if tva_regul not in tvas:
  233. tvas[tva_regul] = 0
  234. tvas[tva_regul] += -total_tva
  235. else:
  236. if tva_account not in tvas:
  237. tvas[tva_account] = 0
  238. tvas[tva_account] += -total_tva
  239. return tvas
  240. # get_tva_regul_account: retourn the reference corresponding to the
  241. # value-added tax regulation account
  242. @classmethod
  243. def get_tva_regul_account(cls, ed):
  244. tx = int(float(ed.tva_tx) * 100)
  245. key = "tva_regul_%s" % (tx,)
  246. return settings.get('PC_REFS')[key]
  247. # get_tva_billing_amounts: return the value-added tax amount to collect
  248. @classmethod
  249. def get_tva_billing_amounts(cls, dolibarr_alchemy, e, journal):
  250. return cls.get_tva_amounts(dolibarr_alchemy, e, journal)
  251. # get_tva_payment_amounts: return value-added tax amount to deduce
  252. @classmethod
  253. def get_tva_payment_amounts(cls, dolibarr_alchemy, e, journal):
  254. return cls.get_tva_amounts(dolibarr_alchemy, e, journal)
  255. #
  256. # HledgerSupplierEntry: Billing entry corresponding to a supplier
  257. #
  258. class HledgerSupplierEntry(HledgerBillingEntry):
  259. k_accounting_date = 'datef'
  260. def _sql_class(self):
  261. return self.dolibarr_alchemy.FactureFourn
  262. # get_entries: return the bill entries ordered by billing date
  263. @classmethod
  264. def get_entries(cls, dolibarr_alchemy):
  265. FactureFourn = dolibarr_alchemy.FactureFourn
  266. return [cls(dolibarr_alchemy, e) for e in dolibarr_alchemy.session.query(FactureFourn).order_by(FactureFourn.datef).all()]
  267. # check: check if the entry is coherent
  268. def check(self):
  269. e = self.e
  270. total_ttc = e.total_ttc
  271. total_tva = e.total_tva
  272. total_ht = e.total_ht
  273. for ed in e.details:
  274. total_ttc -= ed.total_ttc
  275. total_tva -= ed.tva
  276. total_ht -= ed.total_ht
  277. if total_ttc > 1e-10:
  278. print("Erreur dans l'écriture %s: total ttc = %s" % (e.ref_supplier, total_ttc))
  279. if total_ht > 1e-10:
  280. print("Erreur dans l'écriture %s: total ht = %s" % (e.ref_supplier, total_ht))
  281. if total_tva > 1e-10:
  282. print("Erreur dans l'écriture %s: total tva = %s" % (e.ref_supplier, total_tva))
  283. # getMissingPC: retrieve missing accounts
  284. def getMissingPC(self):
  285. e = self.e
  286. pc_missing = []
  287. if e.societe.code_compta_fournisseur == "":
  288. pc_missing.append("tiers:fournisseur: %s %s" % (e.societe.nom, e.societe.ape))
  289. for ed in e.details:
  290. if self.get_product_account_code(ed) == self.pc_default_expense:
  291. pc_missing.append("achat: %s - %s" % (e.ref_supplier, ed.description.splitlines()[0]))
  292. return pc_missing
  293. # get_ledger: return the corresponding ledger entries
  294. def get_ledger(self):
  295. e = self.e
  296. self.check()
  297. s = ""
  298. s += "%(date)s %(description)s\n" % {
  299. 'date': e.datef.strftime("%Y/%m/%d"),
  300. 'description': e.ref_supplier + " - " + e.societe.nom,
  301. }
  302. s_code = self.get_supplier_code(self.e)
  303. s += " %(compte_tiers)s \t %(amount_ttc)s\n" % {
  304. 'compte_tiers': settings.get_ledger_account(s_code),
  305. 'amount_ttc': self._value(e.total_ttc),
  306. }
  307. # lignes compte fournisseur
  308. if self.tva_type == 'none':
  309. for ed in e.details:
  310. p_code = self.get_product_account_code(ed)
  311. s += " %(compte_produit)s \t %(amount_ttc)s\n" % {
  312. 'compte_produit': settings.get_ledger_account(p_code),
  313. 'amount_ttc': self._value(-ed.total_ttc)
  314. }
  315. else:
  316. for ed in e.details:
  317. p_code = self.get_product_account_code(ed)
  318. s += " %(compte_produit)s \t %(amount_ht)s\n" % {
  319. 'compte_produit': settings.get_ledger_account(p_code),
  320. 'amount_ht': self._value(-ed.total_ht)
  321. }
  322. # value-added tax
  323. if self.tva_type != 'none':
  324. tvas = self.get_tva_billing_amounts(self.dolibarr_alchemy, self.e, journal="supplier")
  325. for k in tvas:
  326. s += " %(compte_tva)s \t %(amount_tva)s\n" % {
  327. 'compte_tva': settings.get_ledger_account(k),
  328. 'amount_tva': self._value(tvas[k]),
  329. }
  330. return s
  331. # get_tva_account: return the value-added tax account
  332. @classmethod
  333. def get_tva_account(cls, ed):
  334. p_code = cls.get_product_account_code(ed)
  335. tx = int(float(ed.tva_tx) * 100)
  336. if p_code.startswith("2"):
  337. prefix = 'tva_deductible'
  338. else:
  339. prefix = 'tva_deductible_immo'
  340. key = "%s_%s" % (prefix, tx)
  341. tva_account = settings.get('PC_REFS')[key]
  342. return tva_account
  343. # get_product_account_code: return the account code for the product of the current entry
  344. @classmethod
  345. def get_product_account_code(cls, ed):
  346. p_code = ""
  347. if ed.accounting_account:
  348. p_code = ed.accounting_account.account_number
  349. elif ed.product:
  350. p_code = ed.product.accountancy_code_buy
  351. else:
  352. p_code = cls.pc_default_expense
  353. return p_code
  354. # get_supplier_code: return the supplier account code for the current entry
  355. @classmethod
  356. def get_supplier_code(cls, e):
  357. s_code = e.societe.code_compta_fournisseur
  358. if s_code == "":
  359. s_code = cls.pc_default_supplier
  360. return s_code
  361. #
  362. # HledgerSellEntry: The billing entry corresponding to a client
  363. #
  364. class HledgerSellEntry(HledgerBillingEntry):
  365. k_accounting_date = 'datef'
  366. def _sql_class(self):
  367. return self.dolibarr_alchemy.Facture
  368. # get_entries: return the bill entries ordered by billing date
  369. @classmethod
  370. def get_entries(cls, dolibarr_alchemy):
  371. Facture = dolibarr_alchemy.Facture
  372. return [cls(dolibarr_alchemy, e) for e in dolibarr_alchemy.session.query(Facture).order_by(Facture.datef).all()]
  373. # get_ledger: return the ledger corresping to this entry
  374. def get_ledger(self):
  375. e = self.e
  376. self.check()
  377. s = ""
  378. # Date et description
  379. s += "%(date)s %(description)s\n" % {
  380. 'date': e.datef.strftime("%Y/%m/%d"),
  381. 'description': e.facnumber + " - " + e.societe.nom,
  382. }
  383. # ligne pour compte client
  384. s_code = self.get_client_code(self.e)
  385. s += " %(compte_tiers)s %(amount_ttc)s\n" % {
  386. 'compte_tiers': settings.get_ledger_account(s_code),
  387. 'amount_ttc': self._value(-e.total_ttc),
  388. }
  389. # lignes pour compte de produits
  390. if self.tva_type == 'none':
  391. for ed in e.details:
  392. p_code = self.get_product_account_code(ed)
  393. s += " %(compte_produit)s %(amount_ttc)s\n" % {
  394. 'compte_produit': settings.get_ledger_account(p_code),
  395. 'amount_ttc': self._value(ed.total_ttc)
  396. }
  397. else:
  398. for ed in e.details:
  399. p_code = self.get_product_account_code(ed)
  400. s += " %(compte_produit)s %(amount_ht)s\n" % {
  401. 'compte_produit': settings.get_ledger_account(p_code),
  402. 'amount_ht': self._value(ed.total_ht)
  403. }
  404. # lignes pour la tva
  405. if self.tva_type != 'none':
  406. tvas = self.get_tva_billing_amounts(self.dolibarr_alchemy, self.e, journal="sell")
  407. for k in tvas:
  408. s += " %(compte_tva)s %(amount_tva)s\n" % {
  409. 'compte_tva': settings.get_ledger_account(k),
  410. 'amount_tva': self._value(tvas[k]),
  411. }
  412. return s
  413. # get_tva_account: return the value-added tax account for the given product
  414. @classmethod
  415. def get_tva_account(cls, ed):
  416. tx = int(float(ed.tva_tx) * 100)
  417. key = "tva_collecte_%s" % (tx,)
  418. return settings.get('PC_REFS')[key]
  419. # getMissingPC: return the missing account for this entry
  420. def getMissingPC(self):
  421. e = self.e
  422. pc_missing = []
  423. if e.societe.code_compta == "":
  424. pc_missing.append("tiers: %s %s" % (e.societe.nom, e.societe.ape))
  425. for ed in e.details:
  426. if self.get_product_account_code(ed) == self.pc_default_income:
  427. if ed.description != "":
  428. description = ed.description.splitlines()[0]
  429. else:
  430. description = ed.description
  431. pc_missing.append("produit: %s - %s - %s" % (e.societe.nom, e.facnumber, description))
  432. return pc_missing
  433. # get_product_account_code: return the account code for the product of the current entry
  434. @classmethod
  435. def get_product_account_code(cls, ed):
  436. p_code = ""
  437. if ed.accounting_account:
  438. p_code = ed.accounting_account.account_number
  439. elif ed.product:
  440. p_code = ed.product.accountancy_code_sell
  441. else:
  442. p_code = cls.pc_default_income
  443. return p_code
  444. # get_client_code: return the account code for the client entry
  445. @classmethod
  446. def get_client_code(cls, e):
  447. s_code = e.societe.code_compta
  448. if s_code == "":
  449. s_code = cls.pc_default_client
  450. return s_code
  451. # check: check if the entry is coherent
  452. def check(self):
  453. e = self.e
  454. total_ttc = e.total_ttc
  455. total_tva = e.tva
  456. total_ht = e.total
  457. for ed in e.details:
  458. total_ttc -= ed.total_ttc
  459. total_tva -= ed.total_tva
  460. total_ht -= ed.total_ht
  461. if total_ttc > 1e-10:
  462. print("Erreur dans l'écriture %s: total ttc = %s" % (e.facnumber, total_ttc))
  463. if total_ht > 1e-10:
  464. print("Erreur dans l'écriture %s: total ht = %s" % (e.facnumber, total_ht))
  465. if total_tva > 1e-10:
  466. print("Erreur dans l'écriture %s: total tva = %s" % (e.facnumber, total_tva))
  467. #
  468. # HledgerSocialEntry: A ledger entry corresponding to a tax
  469. #
  470. class HledgerSocialEntry(HledgerEntry):
  471. k_accounting_date = 'periode'
  472. def _sql_class(self):
  473. return self.dolibarr_alchemy.CotisationsSociales
  474. # get_entries: retrieve all the entries for this entry type
  475. @classmethod
  476. def get_entries(cls, dolibarr_alchemy):
  477. CotisationsSociales = dolibarr_alchemy.CotisationsSociales
  478. entries = dolibarr_alchemy.session.query(CotisationsSociales).order_by(CotisationsSociales.date_ech).all()
  479. return [cls(dolibarr_alchemy, e) for e in entries]
  480. # get_third_code: return the third accounting code for this entry
  481. @classmethod
  482. def get_third_code(cls, e):
  483. third_code = ""
  484. if e.type.code in settings.get('SOCIAL_REFS'):
  485. third_code = settings.get('SOCIAL_REFS')[e.type.code]
  486. if third_code == "":
  487. third_code = cls.pc_default_supplier
  488. return third_code
  489. # get_social_code: return the social accounting code for this entry
  490. @classmethod
  491. def get_social_code(cls, e):
  492. s_code = ""
  493. if e.type:
  494. s_code = e.type.accountancy_code
  495. if s_code == "":
  496. s_code = cls.pc_default_expense
  497. return s_code
  498. # getMissingPC: return the missing accounting code for this entry
  499. def getMissingPC(self):
  500. e = self.e
  501. pc_missing = []
  502. if self.get_social_code(self.e) == self.pc_default_expense:
  503. pc_missing.append("expenses: %s" % (e.libelle))
  504. if self.get_third_code(self.e) == self.pc_default_supplier:
  505. pc_missing.append("tiers: %s (%s)" % (e.libelle, e.type.code))
  506. return pc_missing
  507. # get_ledger: return the ledger for this entry
  508. def get_ledger(self):
  509. e = self.e
  510. s = ""
  511. s += "%(date)s %(description)s\n" % {
  512. 'date': e.periode.strftime("%Y/%m/%d"),
  513. 'description': e.libelle + " - " + e.type.libelle
  514. }
  515. third_code = self.get_third_code(self.e)
  516. s_code = self.get_social_code(self.e)
  517. s += " %(account)s \t %(amount)s\n" % {
  518. 'account': settings.get_ledger_account(third_code),
  519. 'amount': self._value(e.amount)
  520. }
  521. s += " %(account)s \t %(amount)s\n" % {
  522. 'account': settings.get_ledger_account(s_code),
  523. 'amount': self._value(-e.amount)
  524. }
  525. return s
  526. # check: -
  527. def check(self):
  528. pass
  529. #
  530. # HledgerDolibarrSQLAlchemy: Top class for retrieving all the journals
  531. #
  532. class HledgerDolibarrSQLAlchemy(DolibarrSQLAlchemy):
  533. def get_bank_journal(self):
  534. return HledgerJournal(self, HledgerBankEntry)
  535. def get_supplier_journal(self):
  536. return HledgerJournal(self, HledgerSupplierEntry)
  537. def get_sell_journal(self):
  538. return HledgerJournal(self, HledgerSellEntry)
  539. def get_social_journal(self):
  540. return HledgerJournal(self, HledgerSocialEntry)