~stoq-dev/stoqnfe/master

« back to all changes in this revision

Viewing changes to stoqnfe/model.py

  • Committer: georgeyk
  • Date: 2009-10-28 16:25:15 UTC
  • mfrom: (12.1.13 stoqnfe-danfe2)
  • Revision ID: georgeyk.dev@gmail.com-20091028162515-8ajv4cujuqnqa9k2
Initial implementation of the DANF-e report.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import os
28
28
from xml.dom.minidom import parse, parseString
29
29
 
 
30
from kiwi.python import Settable
 
31
 
30
32
from stoqnfe.lib.configparser import get_config
31
33
from stoqnfe.lib.sign import add_nfe_signature
32
34
from stoqnfe.lib.utils import clean_xml
131
133
 
132
134
        filename = os.path.join(location, self.name + '.xml')
133
135
        open(filename, 'w').write(xml_str)
 
136
 
 
137
    #
 
138
    # DANF-e Accessors
 
139
    #
 
140
 
 
141
    def _get_text_attribute(self, tag):
 
142
        doc = self._get_document()
 
143
        elements = doc.getElementsByTagName(tag)
 
144
        if len(elements) > 0:
 
145
            return elements[0].childNodes[0].nodeValue.upper()
 
146
        return ''
 
147
 
 
148
    def _get_text_from_element(self, element, tag):
 
149
         nodes = element.getElementsByTagName(tag)
 
150
         if nodes:
 
151
             return nodes[0].childNodes[0].nodeValue
 
152
 
 
153
    def get_invoice_number(self):
 
154
        """Returns the invoice number of the NF-e.
 
155
        """
 
156
        number = '%09d' % int(self._get_text_attribute('nNF'))
 
157
        return '%s.%s.%s' % (number[:3], number[3:6], number[6:],)
 
158
 
 
159
    def get_serie(self):
 
160
        """Returns the NF-e serie.
 
161
        """
 
162
        return self._get_text_attribute('serie')
 
163
 
 
164
    def get_operation_nature(self):
 
165
        """Returns the description of the operation nature.
 
166
        """
 
167
        return self._get_text_attribute('natOp')
 
168
 
 
169
    def get_nfe_type(self):
 
170
        """Returns the nfe type as a string.
 
171
        """
 
172
        return self._get_text_attribute('tpNF')
 
173
 
 
174
    def get_key(self):
 
175
        """Returns the unique NF-e access key.
 
176
        """
 
177
        # Pg. 77 of the "Manual de Integração"
 
178
        doc = self._get_document()
 
179
        element = doc.getElementsByTagName('infNFe')[0]
 
180
        key = element.getAttribute('Id')[3:]
 
181
        # break the key in 11 parts
 
182
        parts = []
 
183
        init = 0
 
184
        for k in range(4, len(key) + 1, 4):
 
185
            parts.append(key[init:k])
 
186
            init = k
 
187
 
 
188
        return u" ".join(parts)
 
189
 
 
190
    def get_emission_date(self):
 
191
        """Returns the date when the NF-e was emitted.
 
192
        """
 
193
        return self._get_text_attribute('dEmi')
 
194
 
 
195
    def get_nfe_info(self):
 
196
        """Returns any additional information in the NF-e.
 
197
        """
 
198
        return self._get_text_attribute('infCpl')
 
199
 
 
200
    def _get_person_name(self, tag):
 
201
        doc = self._get_document()
 
202
        element = doc.getElementsByTagName(tag)[0]
 
203
        return self._get_text_from_element(element, 'xNome')
 
204
 
 
205
    def _get_person_address_district(self, tag):
 
206
        doc = self._get_document()
 
207
        element = doc.getElementsByTagName(tag)[0]
 
208
        return self._get_text_from_element(element, 'xBairro')
 
209
 
 
210
    def _get_person_address(self, tag, with_district=True):
 
211
        doc = self._get_document()
 
212
        element = doc.getElementsByTagName(tag)[0]
 
213
        street = self._get_text_from_element(element, 'xLgr')
 
214
        number = self._get_text_from_element(element, 'nro')
 
215
        addr = u'%s, %s' % (street, number)
 
216
        if with_district:
 
217
            return u'%s - %s' % (addr, self._get_person_address_district(tag))
 
218
        return addr
 
219
 
 
220
    def _get_person_document(self, tag):
 
221
        doc = self._get_document()
 
222
        element = doc.getElementsByTagName(tag)[0]
 
223
        cnpj = self._get_text_from_element(element, 'CNPJ')
 
224
        if cnpj:
 
225
            return cnpj
 
226
        return self._get_text_from_element(element, 'CPF')
 
227
 
 
228
    def _get_person_city(self, tag):
 
229
        doc = self._get_document()
 
230
        element = doc.getElementsByTagName(tag)[0]
 
231
        return self._get_text_from_element(element, 'xMun')
 
232
 
 
233
    def _get_person_state(self, tag):
 
234
        doc = self._get_document()
 
235
        element = doc.getElementsByTagName(tag)[0]
 
236
        return self._get_text_from_element(element, 'UF')
 
237
 
 
238
    def get_branch_name(self):
 
239
        return self._get_person_name('emit')
 
240
 
 
241
    def get_branch_address(self):
 
242
        return self._get_person_address('emit')
 
243
 
 
244
    def get_branch_address_details(self):
 
245
        tag = 'emit'
 
246
        return u'%s/%s' % (self._get_person_city(tag),
 
247
                           self._get_person_state(tag),)
 
248
 
 
249
    def get_branch_document(self):
 
250
        return self._get_person_document('emit')
 
251
 
 
252
    def get_branch_state_register(self):
 
253
        doc = self._get_document()
 
254
        element = doc.getElementsByTagName('emit')[0]
 
255
        return self._get_text_from_element(element, 'IE')
 
256
 
 
257
    def get_branch_details(self):
 
258
        return u'%s: %s' % (_(u'IE'),
 
259
                            self.get_branch_state_register())
 
260
 
 
261
    def get_client_name(self):
 
262
        return self._get_person_name('dest')
 
263
 
 
264
    def get_client_document(self):
 
265
        return self._get_person_document('dest')
 
266
 
 
267
    def get_client_address(self):
 
268
        return self._get_person_address('dest', with_district=False)
 
269
 
 
270
    def get_client_district(self):
 
271
        return self._get_person_address_district('dest')
 
272
 
 
273
    def get_client_city(self):
 
274
        return self._get_person_city('dest')
 
275
 
 
276
    def get_client_state(self):
 
277
        return self._get_person_state('dest')
 
278
 
 
279
    def _get_tax_icms_value(self, tag):
 
280
        doc = self._get_document()
 
281
        element = doc.getElementsByTagName('ICMSTot')[0]
 
282
        node = element.getElementsByTagName(tag)[0]
 
283
        return u'%.2f' % float(node.childNodes[0].nodeValue)
 
284
 
 
285
    def get_base_icms_value(self):
 
286
        """Returns the base value of the ICMS tax.
 
287
        """
 
288
        return  self._get_tax_icms_value('vBC')
 
289
 
 
290
    def get_base_icms_st_value(self):
 
291
        """Returns the base value of ICMS tax for substitution.
 
292
        """
 
293
        return self._get_tax_icms_value('vBCST')
 
294
 
 
295
    def get_icms_value(self):
 
296
        """Returns the value of the ICMS tax.
 
297
        """
 
298
        return self._get_tax_icms_value('vICMS')
 
299
 
 
300
    def get_total_products(self):
 
301
        """Returns the total value of the products, the sum of products
 
302
        multiplied by its value.
 
303
        """
 
304
        return self._get_tax_icms_value('vProd')
 
305
 
 
306
    def get_freight_value(self):
 
307
        """Returns the freight value.
 
308
        """
 
309
        return self._get_tax_icms_value('vFrete')
 
310
 
 
311
    def get_secure_value(self):
 
312
        """Returns the secure value.
 
313
        """
 
314
        return self._get_tax_icms_value('vSeg')
 
315
 
 
316
    def get_discount_value(self):
 
317
        """Returns the discount value.
 
318
        """
 
319
        return self._get_tax_icms_value('vDesc')
 
320
 
 
321
    def get_expense_value(self):
 
322
        """Returns the expense value.
 
323
        """
 
324
        return self._get_tax_icms_value('vOutro')
 
325
 
 
326
    def get_ipi_total(self):
 
327
        """Returns the total value of the IPI tax.
 
328
        """
 
329
        return self._get_tax_icms_value('vIPI')
 
330
 
 
331
    def get_total_value(self):
 
332
        """Returns the total value of the NF-e.
 
333
        """
 
334
        return self._get_tax_icms_value('vNF')
 
335
 
 
336
    def get_freight_type(self):
 
337
        """Returns the freight type as a string.
 
338
        """
 
339
        return self._get_text_attribute('modFrete')
 
340
 
 
341
    def get_products(self):
 
342
        """Returns a sequence of products, containing the following
 
343
        information:
 
344
            - code: product code
 
345
            - description: product description
 
346
            - cst: tributary situation code of the product
 
347
            - cfop: fiscal code of operations
 
348
            - unit: the comercial unit
 
349
            - quantity: the quantity of the product
 
350
            - unit_value: the value of one unit of the product
 
351
            - total: total value of the product (quantity * unit_value)
 
352
        """
 
353
        doc = self._get_document()
 
354
        elements = doc.getElementsByTagName('det')
 
355
        assert len(elements) > 0
 
356
        for element in elements:
 
357
            icms_node = element.getElementsByTagName('ICMS')[0]
 
358
            yield Settable(
 
359
                code=self._get_text_from_element(element, 'cProd'),
 
360
                description=self._get_text_from_element(element, 'xProd'),
 
361
                cst=self._get_text_from_element(icms_node, 'CST'),
 
362
                cfop= self._get_text_from_element(element, 'CFOP'),
 
363
                unit= self._get_text_from_element(element, 'uCom'),
 
364
                quantity= self._get_text_from_element(element, 'qCom'),
 
365
                unit_value= self._get_text_from_element(element, 'vUnCom'),
 
366
                total=self._get_text_from_element(element, 'vProd'),)