def purchase_ncf_validate(self):
        if not self.journal_id.purchase_type == 'normal':
            return

        number = self.move_name if self.move_name else None

        if not ncf.is_valid(number):
            raise UserError(
                _("NCF mal digitado\n\n"
                  "El comprobante *{}* no tiene la estructura correcta "
                  "valide si lo ha digitado correctamente".format(number)))

        if number[-10:-8] not in ('01', '03', '04', '11', '12', '13', '14',
                                  '15'):
            raise ValidationError(
                _("NCF *{}* NO corresponde con el tipo de documento\n\n"
                  "Verifique lo ha digitado correctamente y que no sea un "
                  "Comprobante Consumidor Final (02)".format(number)))

        if self.id:
            ncf_in_draft = self.search_count([
                ('id', '!=', self.id), ('partner_id', '=', self.partner_id.id),
                ('move_name', '=', number),
                ('state', 'in', ('draft', 'cancel'))
            ])

        else:
            ncf_in_draft = self.search_count([
                ('partner_id', '=', self.partner_id.id),
                ('move_name', '=', number),
                ('state', 'in', ('draft', 'cancel'))
            ])

        if ncf_in_draft:
            raise UserError(
                _("NCF en Factura Borrador o Cancelada\n\n"
                  "El comprobante *{}* ya se encuentra "
                  "registrado con este mismo proveedor en una factura "
                  "en borrador o cancelada".format(number)))

        ncf_exist = self.search_count([('partner_id', '=', self.partner_id.id),
                                       ('number', '=', number),
                                       ('state', 'in', ('open', 'paid'))])
        if ncf_exist:
            raise UserError(
                _("NCF Duplicado\n\n"
                  "El comprobante *{}* ya se encuentra registrado con el"
                  " mismo proveedor en otra factura".format(number)))

        if self.journal_id.ncf_remote_validation and not ncf.check_dgii(
                self.partner_id.vat, number):
            raise UserError(
                _(u"NCF NO pasó validación en DGII\n\n"
                  u"¡El número de comprobante *{}* del proveedor "
                  u"*{}* no pasó la validación en "
                  "DGII! Verifique que el NCF y el RNC del "
                  u"proveedor estén correctamente "
                  u"digitados, o si los números de ese NCF se "
                  "le agotaron al proveedor".format(number,
                                                    self.partner_id.name)))
    def invoice_refund(self):
        active_id = self._context.get("active_id", False)
        if active_id:
            invoice = self.env["account.invoice"].browse(active_id)

            if self.supplier_ncf:
                if self.filter_refund == 'debit' and self.supplier_ncf[
                        -10:-8] != '03':
                    raise ValidationError(
                        _(u"Las Notas de Débito deben ser tipo 03, este NCF no es de este tipo."
                          ))
                elif self.filter_refund != 'debit' and self.supplier_ncf[
                        -10:-8] != '04':
                    raise ValidationError(
                        _(u"Las Notas de Crédito deben ser tipo 04, este NCF no es de este tipo."
                          ))

            if self.supplier_ncf and invoice.journal_id.ncf_remote_validation:
                if not ncf.check_dgii(invoice.partner_id.vat,
                                      self.supplier_ncf):
                    raise UserError(
                        _(u"NCF NO pasó validación en DGII\n\n"
                          u"¡El número de comprobante *{}* del proveedor "
                          u"*{}* no pasó la validación en "
                          "DGII! Verifique que el NCF y el RNC del "
                          u"proveedor estén correctamente "
                          u"digitados, o si los números de ese NCF se "
                          "le agotaron al proveedor".format(
                              self.supplier_ncf, invoice.partner_id.name)))

        return super(AccountInvoiceRefund, self).invoice_refund()
Exemple #3
0
    def _check_fiscal_purchase(self):
        for rec in self.filtered(
                lambda r: r.company_id.country_id == self.env.ref("base.do")
                and r.l10n_latam_document_type_id.l10n_do_ncf_type is not False
                and r.type == "in_invoice" and r.l10n_latam_document_number):
            l10n_latam_document_number = rec.l10n_latam_document_number
            l10n_latam_document_type = rec.l10n_latam_document_type_id.l10n_do_ncf_type

            if l10n_latam_document_number and l10n_latam_document_type == "fiscal":
                if l10n_latam_document_number[-10:-8] == "02":
                    raise ValidationError(
                        _("NCF *{}* does not correspond with the fiscal type\n\n"
                          "You cannot register Consumo NCF (02) for purchases"
                          ).format(l10n_latam_document_number))

                try:
                    from stdnum.do import ncf as ncf_validation

                    if len(l10n_latam_document_number
                           ) == "11" and not ncf_validation.check_dgii(
                               rec.partner_id.vat, l10n_latam_document_number):
                        raise ValidationError(
                            _("NCF rejected by DGII\n\n"
                              "NCF *{}* of supplier *{}* was rejected by DGII's "
                              "validation service. Please validate if the NCF and "
                              "the supplier RNC are type correctly. Otherwhise "
                              "your supplier might not have this sequence approved "
                              "yet.").format(l10n_latam_document_number,
                                             rec.partner_id.name))

                except (ImportError, IOError) as err:
                    _logger.debug(err)
Exemple #4
0
    def validate_fiscal_purchase(self):
        for inv in self.filtered(
                lambda i: i.type == "in_invoice" and i.state == "draft"):
            ncf = inv.reference if inv.reference else None
            if ncf and ncf_dict.get(inv.fiscal_type_id.prefix) == "fiscal":
                if ncf[-10:-8] == "02" or ncf[1:3] == "32":
                    raise ValidationError(
                        _("NCF *{}* does not correspond with the fiscal type\n\n"
                          "You cannot register Consumo (02 or 32) for purchases"
                          ).format(ncf))

                elif inv.fiscal_type_id.requires_document and not inv.partner_id.vat:
                    raise ValidationError(
                        _("Partner [{}] {} doesn't have RNC/Céd, "
                          "is required for NCF type {}").format(
                              inv.partner_id.id,
                              inv.partner_id.name,
                              inv.fiscal_type_id.name,
                          ))

                elif not ncf_validation.is_valid(ncf):
                    raise UserError(
                        _("NCF wrongly typed\n\n"
                          "This NCF *{}* does not have the proper structure, "
                          "please validate if you have typed it correctly.").
                        format(ncf))

                # TODO move this to l10n_do_external_validation_ncf
                elif (self.journal_id.l10n_do_ncf_remote_validation and
                      not ncf_validation.check_dgii(self.partner_id.vat, ncf)):
                    raise ValidationError(
                        _("NCF rejected by DGII\n\n"
                          "NCF *{}* of supplier *{}* was rejected by DGII's "
                          "validation service. Please validate if the NCF and "
                          "the supplier RNC are type correctly. Otherwhise "
                          "your supplier might not have this sequence approved "
                          "yet.").format(ncf, self.partner_id.name))

                ncf_in_invoice = (inv.search_count([
                    ("id", "!=", inv.id),
                    ("company_id", "=", inv.company_id.id),
                    ("partner_id", "=", inv.partner_id.id),
                    ("reference", "=", ncf),
                    ("state", "in", ("draft", "open", "paid", "cancel")),
                    ("type", "in", ("in_invoice", "in_refund")),
                ]) if inv.id else inv.search_count([
                    ("partner_id", "=", inv.partner_id.id),
                    ("company_id", "=", inv.company_id.id),
                    ("reference", "=", ncf),
                    ("state", "in", ("draft", "open", "paid", "cancel")),
                    ("type", "in", ("in_invoice", "in_refund")),
                ]))

                if ncf_in_invoice:
                    raise ValidationError(
                        _("NCF already used in another invoice\n\n"
                          "The NCF *{}* has already been registered in another "
                          "invoice with the same supplier. Look for it in "
                          "invoices with canceled or draft states").format(
                              ncf))
Exemple #5
0
    def validate_fiscal_purchase(self):
        NCF = self.reference if self.reference else None
        if NCF and self.journal_id.purchase_type == 'normal':
            if NCF[-10:-8] == '02':
                raise ValidationError(
                    _("NCF *{}* NO corresponde con el tipo de documento\n\n"
                      "No puede registrar Comprobantes Consumidor Final (02)").
                    format(NCF))

            elif not ncf_validation.is_valid(NCF):
                raise UserError(
                    _("NCF mal digitado\n\n"
                      "El comprobante *{}* no tiene la estructura correcta "
                      "valide si lo ha digitado correctamente").format(NCF))

            elif not self.partner_id.vat:
                raise ValidationError(
                    _(u"Proveedor sin RNC/Céd\n\n"
                      u"El proveedor *{}* no tiene RNC o Cédula y es requerido "
                      u"para registrar compras Fiscales").format(
                          self.partner_id.name))

            elif (self.journal_id.ncf_remote_validation
                  and not ncf_validation.check_dgii(self.partner_id.vat, NCF)):
                raise ValidationError(
                    _(u"NCF NO pasó validación en DGII\n\n"
                      u"¡El número de comprobante *{}* del proveedor "
                      u"*{}* no pasó la validación en "
                      "DGII! Verifique que el NCF y el RNC del "
                      u"proveedor estén correctamente "
                      u"digitados, o si los números de ese NCF se "
                      "le agotaron al proveedor").format(
                          NCF, self.partner_id.name))

            ncf_in_invoice = self.search_count([
                ('id', '!=', self.id), ('company_id', '=', self.company_id.id),
                ('partner_id', '=', self.partner_id.id),
                ('reference', '=', NCF),
                ('state', 'in', ('draft', 'open', 'paid', 'cancel')),
                ('type', 'in', ('in_invoice', 'in_refund'))
            ]) if self.id else self.search_count([('partner_id', '=',
                                                   self.partner_id.id),
                                                  ('company_id', '=',
                                                   self.company_id.id),
                                                  ('reference', '=', NCF),
                                                  ('state', 'in',
                                                   ('draft', 'open',
                                                    'paid', 'cancel')),
                                                  ('type',
                                                   'in', ('in_invoice',
                                                          'in_refund'))])

            if ncf_in_invoice:
                raise ValidationError(
                    _("NCF Duplicado en otra Factura\n\n"
                      "El comprobante *{}* ya se encuentra "
                      "registrado con este mismo proveedor en una factura "
                      "en borrador o cancelada").format(NCF))
 def test_check_dgii(self):
     """Test stdnum.do.ncf.check_dgii()"""
     # Test a normal valid number
     result = ncf.check_dgii('130546312', 'A010010011500000038')
     self.assertTrue(result)
     self.assertIn('name', result.keys())
     self.assertIn('rnc', result.keys())
     self.assertIn('ncf', result.keys())
     self.assertIn('validation_message', result.keys())
     self.assertEqual(result['rnc'], '130546312')
     self.assertEqual(result['ncf'], 'A010010011500000038')
     # Test an invalid combination
     self.assertIsNone(ncf.check_dgii('501620371', 'A010010011500000038'))
     # Another valid example
     self.assertTrue(ncf.check_dgii('1-31-56633-2', 'A010010010100000001'))
     self.assertTrue(ncf.check_dgii('1-31-56633-2', 'A010010010100000100'))
     # These types have not been requested with the regulator
     self.assertFalse(ncf.check_dgii('1-31-56633-2', 'A030010010100000001'))
     self.assertFalse(ncf.check_dgii('1-31-56633-2', 'A010020010100000001'))
     # Test the new format
     result = ncf.check_dgii('130546312', 'B0100000005')
     self.assertTrue(result)
     self.assertIn('name', result.keys())
     self.assertIn('rnc', result.keys())
     self.assertIn('ncf', result.keys())
     self.assertIn('validation_message', result.keys())
     self.assertEqual(result['rnc'], '130546312')
     self.assertEqual(result['ncf'], 'B0100000005')
 def test_check_dgii(self):
     """Test stdnum.do.ncf.check_dgii()"""
     # Test a normal valid number
     result = ncf.check_dgii('130546312', 'A010010011500000038')
     self.assertTrue(result)
     self.assertIn('name', result.keys())
     self.assertIn('rnc', result.keys())
     self.assertIn('ncf', result.keys())
     self.assertIn('validation_message', result.keys())
     self.assertEqual(result['rnc'], '130546312')
     self.assertEqual(result['ncf'], 'A010010011500000038')
     # Test an invalid combination
     self.assertIsNone(ncf.check_dgii('501620371', 'A010010011500000038'))
     # Another valid example
     self.assertTrue(ncf.check_dgii('1-31-56633-2', 'A010010010100000001'))
     self.assertTrue(ncf.check_dgii('1-31-56633-2', 'A010010010100000100'))
     # These types have not been requested with the regulator
     self.assertFalse(ncf.check_dgii('1-31-56633-2', 'A030010010100000001'))
     self.assertFalse(ncf.check_dgii('1-31-56633-2', 'A010020010100000001'))
     # Test the new format
     result = ncf.check_dgii('130546312', 'B0100000005')
     self.assertTrue(result)
     self.assertIn('name', result.keys())
     self.assertIn('rnc', result.keys())
     self.assertIn('ncf', result.keys())
     self.assertIn('validation_message', result.keys())
     self.assertEqual(result['rnc'], '130546312')
     self.assertEqual(result['ncf'], 'B0100000005')
 def test_check_dgii(self):
     """Test stdnum.do.ncf.check_dgii()"""
     # Test a normal valid number
     result = ncf.check_dgii('130546312', 'A010010011500000038')
     self.assertTrue(result)
     self.assertIn('name', result.keys())
     self.assertIn('rnc', result.keys())
     self.assertIn('ncf', result.keys())
     self.assertIn('validation_message', result.keys())
     self.assertEqual(result['rnc'], '130546312')
     self.assertEqual(result['ncf'], 'A010010011500000038')
     # Test an invalid combination
     self.assertIsNone(ncf.check_dgii('501620371', 'A010010011500000038'))
     # Another valid example
     self.assertTrue(ncf.check_dgii('1-31-56633-2', 'A010010010100000001'))
     self.assertTrue(ncf.check_dgii('1-31-56633-2', 'A010010010100000100'))
     # These types have not been requested with the regulator
     self.assertFalse(ncf.check_dgii('1-31-56633-2', 'A030010010100000001'))
     self.assertFalse(ncf.check_dgii('1-31-56633-2', 'A010020010100000001'))
     # Test the new format
     result = ncf.check_dgii('130546312', 'B0100000005')
     self.assertTrue(result)
     self.assertIn('name', result.keys())
     self.assertIn('rnc', result.keys())
     self.assertIn('ncf', result.keys())
     self.assertIn('validation_message', result.keys())
     self.assertEqual(result['rnc'], '130546312')
     self.assertEqual(result['ncf'], 'B0100000005')
     # Test the ENCF
     result = ncf.check_dgii('101010632',
                             'E310049533639',
                             buyer_rnc='22400559690',
                             security_code='hnI63Q')
     self.assertTrue(result)
     self.assertIn('status', result.keys())
     self.assertEqual(result['issuing_rnc'], '101010632')
     self.assertEqual(result['buyer_rnc'], '22400559690')
     self.assertEqual(result['ncf'], 'E310049533639')
     self.assertIn('issuing_date', result.keys())
     self.assertIn('signature_date', result.keys())
     self.assertIn('total', result.keys())
     self.assertIn('total_itbis', result.keys())
     self.assertIn('validation_message', result.keys())
Exemple #9
0
    def invoice_refund(self):
        active_id = self._context.get("active_id", False)
        if active_id:
            invoice = self.env["account.invoice"].browse(active_id)
            # TODO
            if self.refund_reference and self.is_fiscal_refund:
                ncf = self.refund_reference[0:3]
                ncf_digits = len(self.refund_reference)
                # TODO: Hacer las validaciones con el tipo de comprobante y no directo
                #  en e codigo.
                if (self._context.get("debit_note")
                        and ncf not in ("B03", "E33")):
                    raise UserError(
                        _("Debit Notes must be type B03 or E33, this NCF "
                          "structure does not comply."))
                elif ncf not in ("B04", "E34"):
                    raise UserError(
                        _(("Credit Notes must be type B04 or E34, this NCF (Type %s)"
                           " structure does not comply.") % ncf))
                elif (ncf_digits != 11 and ncf == 'B04') \
                        or (ncf_digits != 13 and ncf == 'E34'):
                    raise UserError(
                        _(("The number of fiscal sequence in this voucher is "
                           "incorrect, please double check the fiscal sequence"
                           )))

                # TODO move this to l10n_do_external_validation_ncf
                elif (len(self.refund_reference) == 11
                      and invoice.journal_id.l10n_do_ncf_remote_validation
                      and not ncf_validation.check_dgii(
                          invoice.partner_id.vat, self.refund_reference)):
                    raise ValidationError(
                        _("NCF rejected by DGII\n\n"
                          "NCF *{}* of supplier *{}* was rejected by DGII's "
                          "validation service. Please validate if the NCF and "
                          "the supplier RNC are type correctly. Otherwhise "
                          "your supplier might not have this sequence approved "
                          "yet.").format(self.refund_reference,
                                         self.partner_id.name))

        return super(AccountInvoiceRefund, self).invoice_refund()