Project

General

Profile

Download (6.65 KB) Statistics
| Branch: | Tag: | Revision:

calebasse / calebasse / facturation / invoice_template.py @ 017f4158

1
# -*- coding: utf-8 -*-
2

    
3
import os
4
import tempfile
5

    
6
import cairo
7
import pango
8
import pangocairo
9
import pyPdf
10
from StringIO import StringIO
11

    
12
from ..pdftk import PdfTk
13

    
14

    
15
class InvoiceTemplate(object):
16
    fields = {
17
            'NUM_FINESS': {
18
                'type': 'text',
19
                'pos': (380, 72),
20
            },
21
            'NUM_LOT': {
22
                'type': 'text',
23
                'pos': (570, 85),
24
            },
25
            'NUM_FACTURE': {
26
                'type': 'text',
27
                'pos': (570, 96),
28
            },
29
            'NUM_ENTREE': {
30
                'type': 'text',
31
                'pos': (570, 107),
32
            },
33
            'ABSENCE_SIGNATURE': {
34
                'type': 'bool',
35
                'pos': (672.5, 130),
36
            },
37
            'IDENTIFICATION_ETABLISSEMENT': {
38
                'type': 'multiline',
39
                'pos': (45, 85),
40
            },
41
            'DATE_ELABORATION': {
42
                'type': 'text',
43
                'pos': (720, 58),
44
            },
45
            'NOM_BENEFICIAIRE': {
46
                'pos': (150, 144),
47
            },
48
            'NIR_BENEFICIAIRE': {
49
                'pos': (130, 163),
50
            },
51
            'DATE_NAISSANCE_RANG': {
52
                'pos': (350 ,163),
53
            },
54
            'CODE_ORGANISME': {
55
                'pos': (170, 175),
56
            },
57
            'DATE_ENTREE': {
58
                'pos': (92, 187),
59
            },
60
            'DATE_SORTIE': {
61
                'pos': (360, 187),
62
            },
63
            'NOM_ASSURE': {
64
                'pos': (530, 144),
65
            },
66
            'NIR_ASSURE': {
67
                'pos': (520, 163),
68
            },
69
            'ADRESSE_ASSURE': {
70
                'pos': (460, 177),
71
            },
72
            'TABLEAU1': {
73
                'type': 'array',
74
                'size': 5,
75
                'y': 323,
76
                'lineheight': 10,
77
                'cols': [
78
                    38,
79
                    65,
80
                    91.5,
81
                    114,
82
                    172,
83
                    240,
84
                    303,
85
                    333,
86
                    414.5] },
87
            'TABLEAU2': {
88
                'type': 'array',
89
                'size': 5,
90
                'y': 323,
91
                'lineheight': 10,
92
                'x': 395.5,
93
                'cols': [
94
                    38,
95
                    65,
96
                    91.5,
97
                    114,
98
                    172,
99
                    240,
100
                    303,
101
                    333,
102
                    414.5] },
103
            'SOUS_TOTAL1': {
104
                    'pos': (340, 475),
105
            },
106
            'SOUS_TOTAL2': {
107
                    'pos': (740, 475),
108
            },
109
            'TOTAL': {
110
                    'pos': (330, 500),
111
            },
112
            'COUNTER': {
113
                    'pos': (800, 570),
114
            },
115
            'SUBTITLE': {
116
                    'pos': (300, 50),
117
                    'size': 10,
118
                    'border': True,
119
            },
120
            'PART_OBLIGATOIRE': {
121
                    'pos': (495, 513),
122
                    'type': 'bool',
123
            },
124
            'PART_COMPLEMENTAIRE': {
125
                    'pos': (632, 513),
126
                    'type': 'bool',
127
            },
128

    
129
    }
130

    
131
    def __init__(self, template_path=None, prefix='tmp', suffix=''):
132
        self.prefix = prefix
133
        self.suffix = suffix
134
        self.template_path = template_path
135

    
136
    def draw_field(self, ctx, field, value, size=7):
137
        _type = field.get('type', 'text')
138
        size = field.get('size', size)
139
        if _type == 'bool':
140
            x, y = field['pos']
141
            if value:
142
                ctx.move_to(x, y-10)
143
                pangocairo_context = pangocairo.CairoContext(ctx)
144
                pangocairo_context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
145

    
146
                layout = pangocairo_context.create_layout()
147
                font = pango.FontDescription("Georgia %s" % size)
148
                layout.set_font_description(font)
149

    
150
                layout.set_text(u'\u2714')
151
                pangocairo_context.update_layout(layout)
152
                pangocairo_context.show_layout(layout)
153
        if _type in ('text', 'multiline'):
154
            x, y = field['pos']
155
            ctx.move_to(x, y)
156
            pangocairo_context = pangocairo.CairoContext(ctx)
157
            pangocairo_context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
158

    
159
            layout = pangocairo_context.create_layout()
160
            font = pango.FontDescription("Georgia Bold %s" % size)
161
            layout.set_font_description(font)
162

    
163
            layout.set_text(unicode(value))
164
            pangocairo_context.update_layout(layout)
165
            if field.get('border'):
166
                a, b, width, height = layout.get_pixel_extents()[1]
167
                ctx.save()
168
                ctx.set_source_rgb(1, 1, 1)
169
                ctx.rectangle(x-2, y-2, width+4, height+4)
170
                ctx.fill()
171
                ctx.set_source_rgb(0, 0, 0)
172
                ctx.rectangle(x-2, y-2, width+4, height+4)
173
                ctx.set_line_width(0.1)
174
                ctx.stroke()
175
                ctx.restore()
176
            ctx.move_to(x, y)
177
            pangocairo_context.show_layout(layout)
178
        if _type == 'array':
179
            field = field.copy()
180
            y = field['y']
181
            offset = field.get('x', 0)
182
            for row in value:
183
                for x, v in zip(field['cols'], row):
184
                    sub = {
185
                            'pos': (offset+x, y),
186
                            'size': size,
187
                    }
188
                    self.draw_field(ctx, sub, v, 7)
189
                y += field['lineheight']
190

    
191
    def generate(self, content, delete=True):
192
        width, height = 842,595
193
        with tempfile.NamedTemporaryFile(prefix=self.prefix,
194
                suffix=self.suffix, delete=False) as temp_out_pdf:
195
            try:
196
                overlay = tempfile.NamedTemporaryFile(prefix='overlay',
197
                        suffix='.pdf')
198
                surface = cairo.PDFSurface (overlay.name, width, height)
199
                ctx = cairo.Context (surface)
200
                ctx.set_source_rgb(0, 0, 0)
201
                for key, value in content.iteritems():
202
                    field = self.fields[key]
203
                    self.draw_field(ctx, field, value)
204
                ctx.show_page()
205
                surface.finish()
206
                pdftk = PdfTk()
207
                pdftk.background(overlay.name, self.template_path, temp_out_pdf.name)
208
                overlay.close()
209
                return temp_out_pdf.name
210
            except:
211
                if delete:
212
                    try:
213
                        os.unlink(temp_out_pdf.name)
214
                    except:
215
                        pass
216
                raise
(7-7/16)