pycompta-render to html or json

authorNicolas Chauvat <nicolas.chauvat@logilab.fr>
changesetec3c8780159b
branchdefault
phasedraft
hiddenyes
parent revision#c6867471f9a2 rapports configurables (closes #257021)
child revision#ce6734da378d [comptas] extrait immobilisations de Compta et permet plusieurs sous-compta
files modified by this revision
bin/pycompta-render
lib/render_html.py
lib/render_json.py
main.py
# HG changeset patch
# User Nicolas Chauvat <nicolas.chauvat@logilab.fr>
# Date 1381702235 -7200
# Mon Oct 14 00:10:35 2013 +0200
# Node ID ec3c8780159b5b3f902a22797e74fa092a46e99e
# Parent c6867471f9a2a6ce249f015999752cb23ec0b3ad
pycompta-render to html or json

diff --git a/bin/pycompta-render b/bin/pycompta-render
@@ -1,44 +1,18 @@
1  #!/usr/bin/python
2 
3  import sys
4  import os.path as osp
5 -import glob
6 -import codecs
7 -import xml.etree.ElementTree as ET
8 -from pycompta.lib import render_html
9 -
10 -target = sys.argv[1]
11 -if not target.endswith('/'): target += '/'
12 -basedir = osp.dirname(target)
13 -planc = {}
14 -for compte in ET.parse(osp.join(target, 'plan-comptable.xml')).findall('.//compte'):
15 -    planc[compte.get('numero')] = compte.get('nom')
16 -cr_precedent = ET.parse(osp.join(target, 'compte-resultat_precedent.xml'))
17 -bilan_precedent = ET.parse(osp.join(target, 'bilan_precedent.xml'))
18 +from pycompta.main import render_mod
19 
20 -for path in glob.glob(osp.join(basedir,'*.xml')):
21 -    basename = osp.basename(path)
22 -    if basename.startswith('journal'):
23 -        dest = path.replace('journal', 'journal2').replace('.xml', '.html')
24 -        print 'rendering journal', dest
25 -        render_html.write_journal(codecs.open(dest,'w','utf-8'), ET.parse(path), planc)
26 -    elif basename.startswith('grand-livre'):
27 -        dest = path.replace('grand-livre', 'balance2').replace('.xml', '.html')
28 -        print 'rendering balance', dest, 'from', path
29 -        render_html.write_balance(codecs.open(dest,'w','utf-8'), ET.parse(path), planc)
30 -        dest = path.replace('grand-livre', 'grand-livre2').replace('.xml', '.html')
31 -        print 'rendering grand-livre', dest, 'from', path
32 -        render_html.write_grandlivre(codecs.open(dest,'w','utf-8'), ET.parse(path), planc)
33 -        dest = path.replace('grand-livre', 'tva2').replace('.xml', '.html')
34 -        print 'rendering tva', dest, 'from', path
35 -        render_html.write_tva(codecs.open(dest,'w','utf-8'), ET.parse(path), planc)
36 -    elif basename.startswith('compte-resultat'):
37 -        dest = path.replace('compte-resultat', 'compte-resultat2').replace('.xml', '.html')
38 -        print 'rendering compte-resultat', dest, 'from', path
39 -        render_html.write_compte_resultat(codecs.open(dest,'w','utf-8'), ET.parse(path), planc, cr_precedent)
40 -    elif basename.startswith('bilan-immo'):
41 -        pass
42 -    elif basename.startswith('bilan') and not basename.startswith('bilan_precedent'):
43 -        dest = path.replace('bilan', 'bilan2').replace('.xml', '.html')
44 -        print 'rendering bilan', dest, 'from', path
45 -        render_html.write_bilan(codecs.open(dest,'w','utf-8'), ET.parse(path), planc, bilan_precedent)
46 +if __name__ == '__main__':
47 +    format = sys.argv[1]
48 +    target = sys.argv[2]
49 +    if not target.endswith('/'): target += '/'
50 +    basedir = osp.dirname(target)
51 +
52 +    if format == 'html':
53 +        from pycompta.lib import render_html as mod
54 +    if format == 'json':
55 +        from pycompta.lib import render_json as mod
56 +
57 +    render_mod(mod, basedir)
diff --git a/lib/render_html.py b/lib/render_html.py
@@ -22,10 +22,12 @@
58  TRHIGHLIGHT = u'''<tr onmouseover="addElementClass(this, 'highlighted');" ''' \
59      '''onmouseout="removeElementClass(this, 'highlighted')">'''
60 
61  SOCIETE = '%soc%'
62 
63 +EXTENSION = '.html'
64 +
65  # FIXME: move javascript to lib ?
66 
67  def fmc(compte, key, empty_if_zero=True):
68      return format_montant(compte.get(key), empty_if_zero)
69 
diff --git a/lib/render_json.py b/lib/render_json.py
@@ -0,0 +1,60 @@
70 +# -*- coding: utf-8 -*-
71 +
72 +import json
73 +
74 +SOCIETE = 'SOCIETE'
75 +EXTENSION = '.json'
76 +
77 +def write_journal(output, journal, planc):
78 +    jnl = journal.getroot()
79 +    out = {}
80 +    out['title'] = u'Comptabilité %s -- Journal du %s au %s' % (SOCIETE, jnl.get('debut'), jnl.get('fin'))
81 +    out['debit'] = jnl.get('debit')
82 +    out['credit'] = jnl.get('credit')
83 +    out['ecritures'] = []
84 +    ecritures = sorted((ecr for ecr in journal.findall('ecriture')), key=lambda x: x.get('date'))
85 +    for ecr in ecritures:
86 +        item = {'num': ecr.get('e_num'),
87 +                'date': ecr.get('date'),
88 +                'label': ecr.findtext('libelle'),
89 +                'debits': [],
90 +                'credits': [],
91 +                }
92 +        for part in sorted((deb for deb in ecr.findall('debit')), key=lambda x: x.get('compte')):
93 +            item['debits'].append({'compte':part.get('compte'), 'montant': part.get('montant')})
94 +        for part in sorted((deb for deb in ecr.findall('credit')), key=lambda x: x.get('compte')):
95 +            item['credits'].append({'compte':part.get('compte'), 'montant': part.get('montant')})
96 +        txt = u''
97 +        if ecr.get('ref'):
98 +            txt += u'Cf %s <br />' % ecr.get('ref')
99 +        for reg in ecr.findall('reglement'):
100 +            txt += u'Réglement %s %s <br />' % (reg.get('type',''), reg.text)
101 +        out['ecritures'].append(item)
102 +    json.dump(out, output)
103 +
104 +def write_grandlivre(*args):
105 +    pass
106 +
107 +def write_balance(*args):
108 +    pass
109 +
110 +def write_compte_resultat(output, resultat, planc, crprecedent):
111 +    crnode = resultat.getroot()
112 +    out = {}
113 +    out['title'] = u'Comptabilité %s -- Compte résulat du %s au %s' % (
114 +        SOCIETE, crnode.get('debut'), crnode.get('fin'))
115 +    out['debut'] = crnode.get('debut')
116 +    out['fin'] = crnode.get('fin')
117 +    pnode = crnode.find('produits')
118 +    #out['produits'] = dict([ (poste.get('id'), poste) for poste in pnode.findall('poste') ])
119 +    cnode = crnode.find('charges')
120 +    #out['charges'] = dict([ (poste.get('id'), poste) for poste in cnode.findall('poste') ])
121 +    print out
122 +    json.dump(out, output)
123 +    return
124 +
125 +def write_bilan(*args):
126 +    pass
127 +
128 +def write_tva(*args):
129 +    pass
diff --git a/main.py b/main.py
@@ -10,10 +10,13 @@
130  import sys
131  import os
132  import os.path as osp
133  import optparse
134  import logging
135 +import glob
136 +import codecs
137 +import xml.etree.ElementTree as ET
138 
139  if sys.stdout.isatty():
140      from logilab.common.logging_ext import set_color_formatter
141      set_color_formatter()
142 
@@ -131,10 +134,54 @@
143      else :
144          compta_prev = None
145 
146      return compta, compta_prev
147 
148 +def planc2dict(filename):
149 +    planc = {}
150 +    for compte in ET.parse(filename).findall('.//compte'):
151 +        planc[compte.get('numero')] = compte.get('nom')
152 +    return planc
153 +
154 +def render_mod(mod, basedir, filenames=None):
155 +    planc = planc2dict(osp.join(basedir, 'plan-comptable.xml'))
156 +    cr_precedent = ET.parse(osp.join(basedir, 'compte-resultat_precedent.xml'))
157 +    bilan_precedent = ET.parse(osp.join(basedir, 'bilan_precedent.xml'))
158 +    societe = ET.parse(osp.join(basedir, 'societe.xml'))
159 +
160 +    ext = mod.EXTENSION
161 +
162 +    if filenames is None:
163 +        filenames = glob.glob(osp.join(basedir,'*.xml'))
164 +
165 +    for path in filenames:
166 +        basename = osp.basename(path)
167 +        if basename.startswith('journal'):
168 +            dest = path.replace('.xml', ext)
169 +            print 'rendering journal', dest
170 +            mod.write_journal(codecs.open(dest,'w','utf-8'), ET.parse(path), planc)
171 +        elif basename.startswith('grand-livre'):
172 +            dest = path.replace('grand-livre', 'balance').replace('.xml', ext)
173 +            print 'rendering balance', dest, 'from', path
174 +            mod.write_balance(codecs.open(dest,'w','utf-8'), ET.parse(path), planc)
175 +            dest = path.replace('.xml', ext)
176 +            print 'rendering grand-livre', dest, 'from', path
177 +            mod.write_grandlivre(codecs.open(dest,'w','utf-8'), ET.parse(path), planc)
178 +            dest = path.replace('grand-livre', 'tva').replace('.xml', ext)
179 +            print 'rendering tva', dest, 'from', path
180 +            mod.write_tva(codecs.open(dest,'w','utf-8'), ET.parse(path), planc)
181 +        elif basename.startswith('compte-resultat'):
182 +            dest = path.replace('.xml', ext)
183 +            print 'rendering compte-resultat', dest, 'from', path
184 +            mod.write_compte_resultat(codecs.open(dest,'w','utf-8'), ET.parse(path), planc, cr_precedent)
185 +        elif basename.startswith('bilan-immo'):
186 +            pass
187 +        elif basename.startswith('bilan') and not basename.startswith('bilan_precedent'):
188 +            dest = path.replace('.xml', ext)
189 +            print 'rendering bilan', dest, 'from', path
190 +            mod.write_bilan(codecs.open(dest,'w','utf-8'), ET.parse(path), planc, bilan_precedent)
191 +
192  ## MAIN ########################################################################
193 
194  def mk_optparser():
195      usage = "usage: %prog [options] <source> <target>"
196      parser = optparse.OptionParser(usage)
@@ -178,10 +225,11 @@
197      if options.fo or (options.pdf and options.fo is None) :
198          render.render_fo(*job)
199      if options.pdf :
200          render.render_pdf(*job)
201 
202 +# XXX move to bin/pycompta
203  def run(args):
204      """
205      Programme principal
206      """
207      # parse command-line
@@ -233,6 +281,5 @@
208          stats = stats.load('stones.prof')
209          stats.sort_stats('time', 'calls')
210          stats.print_stats(30)
211      else:
212          return run_standard(config, debut, fin, prev, options)
213 -