TicketBAI - API

l10n_es_ticketbai_api
REPOSITORY
REPOSITORYOCA/l10n-spain
GIT
GIThttps://github.com/OCA/l10n-spain.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/l10n-spain/tree/16.0/l10n_es_ticketbai_api
VERSION
VERSION 1.1.4
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Binovo
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Binovo
COMMITTERS
COMMITTERSPedro M. Baeza, Weblate, OCA-git-bot, oca-ci, Aritz Olea, Andrii9090-tecnativa, luciaavanzosc, r.perez
WEBSITE
WEBSITEhttps://github.com/OCA/l10n-spain
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:53:40
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - base_setup
    - web
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES qrcode
xmlsig
xmltodict
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
res_config_settings_view_form_inherit_l10n_es_ticketbai_api res.config.settings.view.form.inherit.base.setup.inherit.ticketbai_api res.config.settings xpath Inherits base_setup.res_config_settings_view_form
tbai_certificate_form_view tbai.certificate.view.form tbai.certificate form New
tbai_certificate_search_view tbai.certificate.view.search tbai.certificate search New
tbai_certificate_tree_view tbai.certificate.view.tree tbai.certificate tree New
tbai_installation_form_view tbai.installation.view.form tbai.installation form New
tbai_installation_search_view tbai.installation.view.search tbai.installation search New
tbai_installation_tree_view tbai.installation.view.tree tbai.installation tree New
view_company_form_inherit res.company.form.inherit res.company xpath Inherits base.view_company_form
Models touched (14)

New fields (14)
  • tbai_certificate_id Many2one → tbai.certificate
    comodel_name='tbai.certificate' copy=False domain="[('company_id', '=', id)]" string='Certificate'
  • tbai_developer_id Many2one → res.partner
    comodel_name='res.partner' readonly=True related='tbai_installation_id.developer_id' string='Developer'
  • tbai_device_serial_number Char
    copy=False default='' args: 'Device Serial Number'
  • tbai_enabled Boolean
    copy=False args: 'Enable TicketBAI'
  • tbai_installation_id Many2one → tbai.installation
    comodel_name='tbai.installation' copy=False
  • tbai_last_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False string='Last TicketBAI Invoice sent'
  • tbai_license_key Char
    readonly=True related='tbai_installation_id.license_key' args: 'License Key'
  • tbai_pro_available Boolean
    copy=False args: 'Are Production URLs Available'
  • tbai_software_name Char
    help='Registered name at the Tax Agency.' readonly=True related='tbai_installation_id.name' string='Software Name'
  • tbai_software_version Char
    copy=False help='Version of the software.' related='tbai_installation_id.version' string='Software Version'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' copy=False string='TBAI Tax Agency'
  • tbai_test_available Boolean
    copy=False args: 'Are Tests URLs Available'
  • tbai_test_enabled Boolean
    copy=False args: 'Enable testing'
  • tbai_vat_regime_simplified Boolean
    copy=False args: 'Regime Simplified'
Public methods (7)
  • is_operation_in_surcharge_equivalence_or_simplified_regime(self)
  • onchange_tbai_enabled(self)
    @api.onchange('tbai_enabled')
  • onchange_tbai_tax_agency(self)
    @api.onchange('tbai_tax_agency_id')
  • tbai_build_software(self)
  • tbai_certificate_get_p12(self)
  • tbai_certificate_get_p12_buffer(self)
  • tbai_certificate_get_p12_password(self)

New fields (2)
  • tbai_device_serial_number Char
    readonly=False related='company_id.tbai_device_serial_number' string='Device Serial Number'
  • tbai_enabled Boolean
    readonly=True related='company_id.tbai_enabled'
Public methods (0)

No public methods.

New fields (3)
  • tbai_enabled Boolean
    compute='_compute_tbai_enabled'
  • tbai_partner_identification_number Char
    default='' help='Used when the identification type code is not VAT identification number.' args: 'TicketBAI Partner Identification Number'
  • tbai_partner_idtype Selection
    default=TicketBaiCustomerIdType.T02.value selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='TicketBAI Identification Type Code'
Public methods (5)
  • tbai_get_partner_country_code(self)
  • tbai_get_partner_vat_number(self)
  • tbai_get_value_apellidos_nombre_razon_social(self)
    V 1.2 <element name="ApellidosNombreRazonSocial" type="T:TextMax120Type"/> <maxLength value="120"/> :return: Name and surname, or business name
  • tbai_get_value_direccion(self)
    V 1.2 <element name="Direccion" type="T:TextMax250Type" minOccurs="0"/> <maxLength value="250"/>
  • tbai_get_value_nif(self)
    V 1.2 <element name="NIF" type="T:NIFType"/> <length value="9" /> <pattern value="(([a-z|A-Z]{1}\d{7}[a-z|A-Z]{1})|(\d{8}[a-z|A-Z]{1})| ([a-z|A-Z]{1}\d{8}))" /> :return: VAT Number for Customers from Spain or the Company associated partner.

New fields (4)
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • datas Binary
    attachment=True required=True args: 'P12 Certificate'
  • name Char
    required=True
  • password Char
    default=''
Public methods (2)
  • get_p12(self)
    :return: cryptography.pkcs12
  • get_p12_buffer(self)
    :return: p12 Buffer

New fields (5)
  • developer_id Many2one → res.partner
    comodel_name='res.partner' copy=False required=True string='Developer'
  • license_key Char
    copy=False required=True
  • name Char
    copy=False help='Registered name at the Tax Agency.' required=True string='Software Name'
  • vat Char
    related='developer_id.vat' args: 'TIN'
  • version Char
    copy=False help='Version of the software.' required=True string='Software Version'
Public methods (0)

No public methods.

New fields (36)
  • amount_total Char
    default=''
  • api_url Char
    compute='_compute_api_url' args: 'TicketBAI API URL'
  • company_id Many2one → res.company
    comodel_name='res.company' required=True
  • datas Binary
    attachment=True copy=False
  • datas_fname Char
    copy=False args: 'File Name'
  • description Char
    default='/'
  • expedition_date Char
    required=True
  • expedition_hour Char
    default=''
  • file_size Integer
    copy=False
  • is_invoice_refund Boolean
    help='TicketBAI Invoice is a refund (Substitution or Differences).'
  • name Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • operation_date Char
    default=''
  • previous_tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False
  • qr Binary
    attachment=True compute='_compute_tbai_qr' copy=False store=True string='QR'
  • qr_url Char
    compute='_compute_tbai_qr' copy=False store=True args: 'URL'
  • refund_code Selection
    help='BOE-A-1992-28740. Ley 37/1992, de 28 de diciembre, del Impuesto sobre el Valor Añadido. Artículo 80. Modificación de la base imponible.' selection=[(RefundCode.R1.value, 'Art. 80.1, 80.2, 80.6 and rights founded error'), (RefundCode.R2.value, 'Art. 80.3'), (RefundCode.R3.value, 'Art. 80.4'), (RefundCode.R4.value, 'Art. 80 - other'), (RefundCode.R5.value, 'Simplified Invoice')] string='Invoice Refund Reason Code'
  • refund_type Selection
    help='Refund Invoice Type (S/Substitution or I/Differences).' selection=[(RefundType.substitution.value, 'S'), (RefundType.differences.value, 'I')]
  • schema Selection
    help='\n * TicketBai: Invoice\n * AnulaTicketBai: Invoice Cancellation\n ' required=True selection=[(TicketBaiSchema.TicketBai.value, 'TicketBai'), (TicketBaiSchema.AnulaTicketBai.value, 'AnulaTicketBai')]
  • signature_value Char
    copy=False default=''
  • simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • state Selection
    copy=False default=TicketBaiInvoiceState.draft.value index=True required=True selection=[(TicketBaiInvoiceState.draft.value, 'Draft'), (TicketBaiInvoiceState.pending.value, 'Pending'), (TicketBaiInvoiceState.sent.value, 'Sent'), (TicketBaiInvoiceState.cancel.value, 'Cancelled'), (TicketBaiInvoiceState.error.value, 'Error')] string='Status'
  • substituted_invoice_amount_total_untaxed Char
    default='' help='\n Original Invoice Total Amount without Taxes. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n - Total Tax Amount: 21 €\n * Amount Total Untaxed: 100 €\n '
  • substituted_invoice_total_tax_amount Char
    default='' help='\n Original Invoice Total Tax Amount. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n * Total Tax Amount: 21 €\n '
  • substitutes_simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • tax_retention_amount_total Char
    default='' args: 'Invoice Tax Retention Total Amount'
  • tbai_customer_ids One2many → tbai.invoice.customer
    comodel_name='tbai.invoice.customer' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Recipients'
  • tbai_identifier Char
    compute='_compute_tbai_identifier' copy=False store=True args: 'TBAI Identifier'
  • tbai_invoice_line_ids One2many → tbai.invoice.line
    comodel_name='tbai.invoice.line' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Details'
  • tbai_invoice_refund_ids One2many → tbai.invoice.refund
    comodel_name='tbai.invoice.refund' copy=True inverse_name='tbai_invoice_id' string='Refunded Invoices'
  • tbai_response_ids One2many → tbai.response
    comodel_name='tbai.response' inverse_name='tbai_invoice_id' string='Responses'
  • tbai_tax_ids One2many → tbai.invoice.tax
    comodel_name='tbai.invoice.tax' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Taxes'
  • vat_regime_key Char
    default='' args: 'VAT Regime Key'
  • vat_regime_key2 Char
    default='' args: 'Second VAT Regime Key'
  • vat_regime_key3 Char
    default='' args: 'Third VAT Regime Key'
Public methods (45)
  • build_cabecera(self)
    V 1.2 Get TicketBAI version from the Company Tax Agency. <element name="Cabecera" type="T:Cabecera"/> <complexType name="Cabecera"> <sequence> <element name="IDVersionTBAI" type="T:IDVersionTicketBaiType"/> <enumeration value="1.2"/> </sequence> </complexType> :return: Tax Agency
  • build_cabecera_factura(self)
  • build_cancellation(self)
  • build_claves(self)
    V 1.2 The specification document indicates that at least 1 regime key is required. <element name="IDClave" type="T:IDClaveType" maxOccurs="3"/> <sequence> <element name="ClaveRegimenIvaOpTrascendencia" type="T:IdOperacionesTrascendenciaTributariaType"/> </sequence> :return: dict
  • build_datos_factura(self)
  • build_destinatarios(self)
    Support only for one customer.
  • build_detalle_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> <sequence> <element name="CausaExencion" type="T:CausaExencionType" /> <restriction base="string"> <enumeration value="E1"> ... <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalle_no_exenta(self)
    V 1.2 1. Inversión del Sujeto Pasivo (ISP) taxes (tax is paid by the customer). 2. Other taxes <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> <sequence> <element name="TipoNoExenta" type="T:TipoOperacionSujetaNoExentaType"/> <restriction base="string"> <enumeration value="S1"> <enumeration value="S2"> <element name="DesgloseIVA" type="T:DesgloseIVAType"/> <element name="DetalleIVA" type="T:DetalleIVAType" maxOccurs="6" /> <sequence> <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> <element name="TipoImpositivo" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaImpuesto" type="T:ImporteSgn12.2Type" minOccurs="0" /> <element name="TipoRecargoEquivalencia" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaRecargoEquivalencia" type="T:ImporteSgn12.2Type" minOccurs="0"/> <element name="OperacionEnRecargoDeEquivalenciaORegimenSimplificado" type="T:SiNoType" minOccurs="0"/> :return: list<OrderedDict>
  • build_detalle_no_sujeta(self)
    V 1.2 <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> <sequence> <element name="Causa" type="T:CausaNoSujetaType"/> <element name="Importe" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalles_factura(self)
  • build_emisor(self)
  • build_encadenamiento_factura_anterior(self)
  • build_entrega(self)
    V 1.2 <element name="Entrega" type="T:Entrega" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> :return: dict
  • build_factura(self)
  • build_factura_rectificativa(self)
  • build_facturas_rectificadas_sustituidas(self)
  • build_huella_tbai(self)
  • build_id_detalle_factura(self)
  • build_id_factura(self)
  • build_importe_rectificacion_sustitutiva(self)
  • build_invoice(self)
  • build_no_exenta(self)
    V 1.2 <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> :return: dict
  • build_no_sujeta(self)
    V 1.2 <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> <sequence> <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> </sequence> :return: OrderedDict
  • build_prestacion_servicios(self)
    V 1.2 <element name="PrestacionServicios" type="T:PrestacionServicios" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_sujeta(self)
    V 1.2 <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <sequence> <element name="Exenta" type="T:ExentaType" minOccurs="0" /> <element name="NoExenta" type="T:NoExentaType" minOccurs="0" /> :return: OrderedDict
  • build_sujetos(self)
  • build_tbai_invoice(self)
  • build_tipo_desglose(self)
  • cancel(self)
  • error(self)
  • get_exempted_taxes(self)
    * Subject to: - Exempted :return: Recordset of tbai.invoice.tax
  • get_next_pending_invoice(self, company_id=False, limit=1)
    @api.model
  • get_not_exempted_taxes(self)
    * Subject to: - Not exempted :return: Recordset of tbai.invoice.tax
  • get_not_subject_to_taxes(self)
    * Not subject to :return: Recordset of tbai.invoice.tax
  • get_subject_to_taxes(self)
    * Subject to :return: Recordset of tbai.invoice.tax
  • get_taxes(self)
    Filter TicketBai Taxes when Customer is not from Spain. * DesgloseTipoOperacion - PrestacionServicios - Entrega :return: Recordset of tbai.invoice.tax
  • get_tbai_xml_signed_and_signature_value(self)
  • get_tbai_xml_unsigned(self)
  • get_ticketbai_api(self, **kwargs)
  • mark_as_pending(self)
  • mark_as_sent(self)
  • mark_chain_as_error(self, invoice_to_error)
    @api.model
  • send(self, **kwargs)
  • send_pending_invoices(self)
    @api.model

New fields (8)
  • address Char
    default=''
  • country_code Char
    required=True
  • identification_number Char
    default='' help='Required Identification Number for non spanish customers.'
  • idtype Selection
    default=TicketBaiCustomerIdType.T02.value help='Required for non spanish customers.' selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='Identification Type Code'
  • name Char
    help='Name and surname, or business name.' required=True
  • nif Char
    default='' help='Spanish Fiscal Identification Number' args: 'NIF'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • zip Char
    default='' args: 'ZIP Code'
Public methods (0)

No public methods.

New fields (6)
  • amount_total Char
    help='String of float with 12 digits and 2 decimal points.' required=True
  • description Char
    required=True
  • discount_amount Char
    default='0.00' help='String of float with 12 digits and 2 decimal points.'
  • price_unit Char
    help='String of float with 12 digits and 8 decimal points.' required=True
  • quantity Char
    help='String of float with 12 digits and 2 decimal points.' required=True
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (4)
  • expedition_date Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (13)
  • amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Amount (%)'
  • amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.'
  • base Char
    default='' help='String of float with 12 digits and 3 decimal points.'
  • exempted_cause Selection
    help='\n E1: Exenta por el artículo 20 de la Norma Foral del IVA.\n E2: Exenta por el artículo 21 de la Norma Foral del IVA.\n E3: Exenta por el artículo 22 de la Norma Foral del IVA.\n E4: Exenta por el artículo 23 y 24 de la Norma Foral del IVA.\n E5: Exenta por el artículo 25 de la Norma Foral del IVA.\n E6: Exenta por otra causa.\n ' selection=[(ExemptedCause.E1.value, 'E1'), (ExemptedCause.E2.value, 'E2'), (ExemptedCause.E3.value, 'E3'), (ExemptedCause.E4.value, 'E4'), (ExemptedCause.E5.value, 'E5'), (ExemptedCause.E6.value, 'E6')]
  • is_exempted Boolean
  • is_subject_to Boolean
    args: 'Is Subject to'
  • not_exempted_type Selection
    help='\n S1: Sin inversión del sujeto pasivo.\n S2: Con inversión del sujeto pasivo.\n ' selection=[(NotExemptedType.S1.value, 'S1'), (NotExemptedType.S2.value, 'S2')]
  • not_subject_to_cause Selection
    help='\n OT:\n - No sujeto por el artículo 7 de la Norma Foral de IVA Otros supuestos de no\n sujeción.\n RL:\n - No sujeto por reglas de localización.\n ' selection=[(NotSubjectToCause.OT.value, 'OT'), (NotSubjectToCause.RL.value, 'RL')] string='Not Subject to Cause'
  • re_amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Surcharge Amount (%)'
  • re_amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Surcharge Amount Total'
  • surcharge_or_simplified_regime Selection
    default=SurchargeOrSimplifiedRegimeType.N.value selection=[(SurchargeOrSimplifiedRegimeType.N.value, 'N'), (SurchargeOrSimplifiedRegimeType.S.value, 'S')] string='Surcharge or Simplified Regime'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • type Selection
    selection=[(TicketBaiTaxType.service.value, 'Service'), (TicketBaiTaxType.provision_of_goods.value, 'Provision of goods')]
Public methods (0)

No public methods.

New fields (5)
  • state Selection
    required=True selection=[(TicketBaiResponseState.RECEIVED.value, 'Received'), (TicketBaiResponseState.REJECTED.value, 'Rejected'), (TicketBaiResponseState.REQUEST_ERROR.value, 'Request error'), (TicketBaiResponseState.BUILD_ERROR.value, 'Build error')] string='Status'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • tbai_response_message_ids One2many → tbai.response.message
    comodel_name='tbai.response.message' inverse_name='tbai_response_id'
  • xml Binary
    attachment=True string='XML Response'
  • xml_fname Char
    args: 'File Name'
Public methods (2)
  • prepare_tbai_api_error_values(self, msg)
    @api.model
  • prepare_tbai_response_values(self, response)
    @api.model

New fields (3)
  • code Char
    required=True
  • description Char
    required=True translate=True
  • tbai_response_id Many2one → tbai.response
    comodel_name='tbai.response' ondelete='cascade' required=True
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • name_get(self)
    @api.depends('code', 'description')

New fields (11)
  • name Char
    required=True string='Tax Agency name'
  • qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='QR Base URL'
  • rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoices'
  • sign_file_hash Char
    required=True string='Sign File HASH'
  • sign_file_url Char
    required=True string='Sign File URL'
  • tax_agency_version_ids One2many → tbai.tax.agency.version
    comodel_name='tbai.tax.agency.version' inverse_name='tbai_tax_agency_id'
  • test_qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='Test QR Base URL'
  • test_rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoices'
  • version Char
    compute='_compute_ticketbai_version' store=True string='TicketBAI version'
Public methods (1)
  • get_current_version(self)

New fields (10)
  • date_from Date
  • date_to Date
  • qr_base_url Char
    required=True string='QR Base URL'
  • rest_url_cancellation Char
    string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    string='REST API URL for Invoices'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' ondelete='restrict' required=True
  • test_qr_base_url Char
    string='Test - QR Base URL'
  • test_rest_url_cancellation Char
    string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    string='Test - REST API URL for Invoices'
  • version Char
    required=True string='TicketBAI version'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/l10n-spain
GIT
GIThttps://github.com/OCA/l10n-spain.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/l10n-spain/tree/15.0/l10n_es_ticketbai_api
VERSION
VERSION 1.1.4
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Binovo
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Binovo
COMMITTERS
COMMITTERSPedro M. Baeza, Jairo Llopis, Enric Tobella, OCA Transbot, Weblate, OCA-git-bot, oca-ci, Aritz Olea
WEBSITE
WEBSITEhttps://github.com/OCA/l10n-spain
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:46:29
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - base_setup
    - web
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES cryptography
qrcode
xmlsig
xmltodict
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
res_config_settings_view_form_inherit_l10n_es_ticketbai_api res.config.settings.view.form.inherit.base.setup.inherit.ticketbai_api res.config.settings xpath Inherits base_setup.res_config_settings_view_form
tbai_certificate_form_view tbai.certificate.view.form tbai.certificate form New
tbai_certificate_search_view tbai.certificate.view.search tbai.certificate search New
tbai_certificate_tree_view tbai.certificate.view.tree tbai.certificate tree New
tbai_installation_form_view tbai.installation.view.form tbai.installation form New
tbai_installation_search_view tbai.installation.view.search tbai.installation search New
tbai_installation_tree_view tbai.installation.view.tree tbai.installation tree New
view_company_form_inherit res.company.form.inherit res.company xpath Inherits base.view_company_form
Models touched (14)

New fields (14)
  • tbai_certificate_id Many2one → tbai.certificate
    comodel_name='tbai.certificate' copy=False domain="[('company_id', '=', id)]" string='Certificate'
  • tbai_developer_id Many2one → res.partner
    comodel_name='res.partner' readonly=True related='tbai_installation_id.developer_id' string='Developer'
  • tbai_device_serial_number Char
    copy=False default='' args: 'Device Serial Number'
  • tbai_enabled Boolean
    copy=False args: 'Enable TicketBAI'
  • tbai_installation_id Many2one → tbai.installation
    comodel_name='tbai.installation' copy=False
  • tbai_last_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False string='Last TicketBAI Invoice sent'
  • tbai_license_key Char
    readonly=True related='tbai_installation_id.license_key' args: 'License Key'
  • tbai_pro_available Boolean
    copy=False args: 'Are Production URLs Available'
  • tbai_software_name Char
    help='Registered name at the Tax Agency.' readonly=True related='tbai_installation_id.name' string='Software Name'
  • tbai_software_version Char
    copy=False help='Version of the software.' related='tbai_installation_id.version' string='Software Version'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' copy=False string='TBAI Tax Agency'
  • tbai_test_available Boolean
    copy=False args: 'Are Tests URLs Available'
  • tbai_test_enabled Boolean
    copy=False args: 'Enable testing'
  • tbai_vat_regime_simplified Boolean
    copy=False args: 'Regime Simplified'
Public methods (6)
  • onchange_tbai_enabled(self)
    @api.onchange('tbai_enabled')
  • onchange_tbai_tax_agency(self)
    @api.onchange('tbai_tax_agency_id')
  • tbai_build_software(self)
  • tbai_certificate_get_p12(self)
  • tbai_certificate_get_p12_buffer(self)
  • tbai_certificate_get_p12_password(self)

New fields (2)
  • tbai_device_serial_number Char
    readonly=False related='company_id.tbai_device_serial_number' string='Device Serial Number'
  • tbai_enabled Boolean
    readonly=True related='company_id.tbai_enabled'
Public methods (0)

No public methods.

New fields (3)
  • tbai_enabled Boolean
    compute='_compute_tbai_enabled'
  • tbai_partner_identification_number Char
    default='' help='Used when the identification type code is not VAT identification number.' args: 'TicketBAI Partner Identification Number'
  • tbai_partner_idtype Selection
    default=TicketBaiCustomerIdType.T02.value selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='TicketBAI Identification Type Code'
Public methods (5)
  • tbai_get_partner_country_code(self)
  • tbai_get_partner_vat_number(self)
  • tbai_get_value_apellidos_nombre_razon_social(self)
    V 1.2 <element name="ApellidosNombreRazonSocial" type="T:TextMax120Type"/> <maxLength value="120"/> :return: Name and surname, or business name
  • tbai_get_value_direccion(self)
    V 1.2 <element name="Direccion" type="T:TextMax250Type" minOccurs="0"/> <maxLength value="250"/>
  • tbai_get_value_nif(self)
    V 1.2 <element name="NIF" type="T:NIFType"/> <length value="9" /> <pattern value="(([a-z|A-Z]{1}\d{7}[a-z|A-Z]{1})|(\d{8}[a-z|A-Z]{1})| ([a-z|A-Z]{1}\d{8}))" /> :return: VAT Number for Customers from Spain or the Company associated partner.

New fields (4)
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • datas Binary
    attachment=True required=True args: 'P12 Certificate'
  • name Char
    required=True
  • password Char
    default=''
Public methods (2)
  • get_p12(self)
    :return: cryptography.pkcs12
  • get_p12_buffer(self)
    :return: p12 Buffer

New fields (5)
  • developer_id Many2one → res.partner
    comodel_name='res.partner' copy=False required=True string='Developer'
  • license_key Char
    copy=False required=True
  • name Char
    copy=False help='Registered name at the Tax Agency.' required=True string='Software Name'
  • vat Char
    related='developer_id.vat' args: 'TIN'
  • version Char
    copy=False help='Version of the software.' required=True string='Software Version'
Public methods (0)

No public methods.

New fields (36)
  • amount_total Char
    default=''
  • api_url Char
    compute='_compute_api_url' args: 'TicketBAI API URL'
  • company_id Many2one → res.company
    comodel_name='res.company' required=True
  • datas Binary
    attachment=True copy=False
  • datas_fname Char
    copy=False args: 'File Name'
  • description Char
    default='/'
  • expedition_date Char
    required=True
  • expedition_hour Char
    default=''
  • file_size Integer
    copy=False
  • is_invoice_refund Boolean
    help='TicketBAI Invoice is a refund (Substitution or Differences).'
  • name Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • operation_date Char
    default=''
  • previous_tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False
  • qr Binary
    attachment=True compute='_compute_tbai_qr' copy=False store=True string='QR'
  • qr_url Char
    compute='_compute_tbai_qr' copy=False store=True args: 'URL'
  • refund_code Selection
    help='BOE-A-1992-28740. Ley 37/1992, de 28 de diciembre, del Impuesto sobre el Valor Añadido. Artículo 80. Modificación de la base imponible.' selection=[(RefundCode.R1.value, 'Art. 80.1, 80.2, 80.6 and rights founded error'), (RefundCode.R2.value, 'Art. 80.3'), (RefundCode.R3.value, 'Art. 80.4'), (RefundCode.R4.value, 'Art. 80 - other'), (RefundCode.R5.value, 'Simplified Invoice')] string='Invoice Refund Reason Code'
  • refund_type Selection
    help='Refund Invoice Type (S/Substitution or I/Differences).' selection=[(RefundType.substitution.value, 'S'), (RefundType.differences.value, 'I')]
  • schema Selection
    help='\n * TicketBai: Invoice\n * AnulaTicketBai: Invoice Cancellation\n ' required=True selection=[(TicketBaiSchema.TicketBai.value, 'TicketBai'), (TicketBaiSchema.AnulaTicketBai.value, 'AnulaTicketBai')]
  • signature_value Char
    copy=False default=''
  • simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • state Selection
    copy=False default=TicketBaiInvoiceState.draft.value index=True required=True selection=[(TicketBaiInvoiceState.draft.value, 'Draft'), (TicketBaiInvoiceState.pending.value, 'Pending'), (TicketBaiInvoiceState.sent.value, 'Sent'), (TicketBaiInvoiceState.cancel.value, 'Cancelled'), (TicketBaiInvoiceState.error.value, 'Error')] string='Status'
  • substituted_invoice_amount_total_untaxed Char
    default='' help='\n Original Invoice Total Amount without Taxes. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n - Total Tax Amount: 21 €\n * Amount Total Untaxed: 100 €\n '
  • substituted_invoice_total_tax_amount Char
    default='' help='\n Original Invoice Total Tax Amount. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n * Total Tax Amount: 21 €\n '
  • substitutes_simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • tax_retention_amount_total Char
    default='' args: 'Invoice Tax Retention Total Amount'
  • tbai_customer_ids One2many → tbai.invoice.customer
    comodel_name='tbai.invoice.customer' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Recipients'
  • tbai_identifier Char
    compute='_compute_tbai_identifier' copy=False store=True args: 'TBAI Identifier'
  • tbai_invoice_line_ids One2many → tbai.invoice.line
    comodel_name='tbai.invoice.line' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Details'
  • tbai_invoice_refund_ids One2many → tbai.invoice.refund
    comodel_name='tbai.invoice.refund' copy=True inverse_name='tbai_invoice_id' string='Refunded Invoices'
  • tbai_response_ids One2many → tbai.response
    comodel_name='tbai.response' inverse_name='tbai_invoice_id' string='Responses'
  • tbai_tax_ids One2many → tbai.invoice.tax
    comodel_name='tbai.invoice.tax' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Taxes'
  • vat_regime_key Char
    default='' args: 'VAT Regime Key'
  • vat_regime_key2 Char
    default='' args: 'Second VAT Regime Key'
  • vat_regime_key3 Char
    default='' args: 'Third VAT Regime Key'
Public methods (45)
  • build_cabecera(self)
    V 1.2 Get TicketBAI version from the Company Tax Agency. <element name="Cabecera" type="T:Cabecera"/> <complexType name="Cabecera"> <sequence> <element name="IDVersionTBAI" type="T:IDVersionTicketBaiType"/> <enumeration value="1.2"/> </sequence> </complexType> :return: Tax Agency
  • build_cabecera_factura(self)
  • build_cancellation(self)
  • build_claves(self)
    V 1.2 The specification document indicates that at least 1 regime key is required. <element name="IDClave" type="T:IDClaveType" maxOccurs="3"/> <sequence> <element name="ClaveRegimenIvaOpTrascendencia" type="T:IdOperacionesTrascendenciaTributariaType"/> </sequence> :return: dict
  • build_datos_factura(self)
  • build_destinatarios(self)
    Support only for one customer.
  • build_detalle_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> <sequence> <element name="CausaExencion" type="T:CausaExencionType" /> <restriction base="string"> <enumeration value="E1"> ... <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalle_no_exenta(self)
    V 1.2 1. Inversión del Sujeto Pasivo (ISP) taxes (tax is paid by the customer). 2. Other taxes <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> <sequence> <element name="TipoNoExenta" type="T:TipoOperacionSujetaNoExentaType"/> <restriction base="string"> <enumeration value="S1"> <enumeration value="S2"> <element name="DesgloseIVA" type="T:DesgloseIVAType"/> <element name="DetalleIVA" type="T:DetalleIVAType" maxOccurs="6" /> <sequence> <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> <element name="TipoImpositivo" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaImpuesto" type="T:ImporteSgn12.2Type" minOccurs="0" /> <element name="TipoRecargoEquivalencia" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaRecargoEquivalencia" type="T:ImporteSgn12.2Type" minOccurs="0"/> <element name="OperacionEnRecargoDeEquivalenciaORegimenSimplificado" type="T:SiNoType" minOccurs="0"/> :return: list<OrderedDict>
  • build_detalle_no_sujeta(self)
    V 1.2 <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> <sequence> <element name="Causa" type="T:CausaNoSujetaType"/> <element name="Importe" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalles_factura(self)
  • build_emisor(self)
  • build_encadenamiento_factura_anterior(self)
  • build_entrega(self)
    V 1.2 <element name="Entrega" type="T:Entrega" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> :return: dict
  • build_factura(self)
  • build_factura_rectificativa(self)
  • build_facturas_rectificadas_sustituidas(self)
  • build_huella_tbai(self)
  • build_id_detalle_factura(self)
  • build_id_factura(self)
  • build_importe_rectificacion_sustitutiva(self)
  • build_invoice(self)
  • build_no_exenta(self)
    V 1.2 <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> :return: dict
  • build_no_sujeta(self)
    V 1.2 <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> <sequence> <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> </sequence> :return: OrderedDict
  • build_prestacion_servicios(self)
    V 1.2 <element name="PrestacionServicios" type="T:PrestacionServicios" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_sujeta(self)
    V 1.2 <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <sequence> <element name="Exenta" type="T:ExentaType" minOccurs="0" /> <element name="NoExenta" type="T:NoExentaType" minOccurs="0" /> :return: OrderedDict
  • build_sujetos(self)
  • build_tbai_invoice(self)
  • build_tipo_desglose(self)
  • cancel(self)
  • error(self)
  • get_exempted_taxes(self)
    * Subject to: - Exempted :return: Recordset of tbai.invoice.tax
  • get_next_pending_invoice(self, company_id=False, limit=1)
    @api.model
  • get_not_exempted_taxes(self)
    * Subject to: - Not exempted :return: Recordset of tbai.invoice.tax
  • get_not_subject_to_taxes(self)
    * Not subject to :return: Recordset of tbai.invoice.tax
  • get_subject_to_taxes(self)
    * Subject to :return: Recordset of tbai.invoice.tax
  • get_taxes(self)
    Filter TicketBai Taxes when Customer is not from Spain. * DesgloseTipoOperacion - PrestacionServicios - Entrega :return: Recordset of tbai.invoice.tax
  • get_tbai_xml_signed_and_signature_value(self)
  • get_tbai_xml_unsigned(self)
  • get_ticketbai_api(self, **kwargs)
  • mark_as_pending(self)
  • mark_as_sent(self)
  • mark_chain_as_error(self, invoice_to_error)
    @api.model
  • send(self, **kwargs)
  • send_pending_invoices(self)
    @api.model

New fields (8)
  • address Char
    default=''
  • country_code Char
    required=True
  • identification_number Char
    default='' help='Required Identification Number for non spanish customers.'
  • idtype Selection
    default=TicketBaiCustomerIdType.T02.value help='Required for non spanish customers.' selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='Identification Type Code'
  • name Char
    help='Name and surname, or business name.' required=True
  • nif Char
    default='' help='Spanish Fiscal Identification Number' args: 'NIF'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • zip Char
    default='' args: 'ZIP Code'
Public methods (0)

No public methods.

New fields (6)
  • amount_total Char
    help='String of float with 12 digits and 2 decimal points.' required=True
  • description Char
    required=True
  • discount_amount Char
    default='0.00' help='String of float with 12 digits and 2 decimal points.'
  • price_unit Char
    help='String of float with 12 digits and 8 decimal points.' required=True
  • quantity Char
    help='String of float with 12 digits and 2 decimal points.' required=True
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (4)
  • expedition_date Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (13)
  • amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Amount (%)'
  • amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.'
  • base Char
    default='' help='String of float with 12 digits and 3 decimal points.'
  • exempted_cause Selection
    help='\n E1: Exenta por el artículo 20 de la Norma Foral del IVA.\n E2: Exenta por el artículo 21 de la Norma Foral del IVA.\n E3: Exenta por el artículo 22 de la Norma Foral del IVA.\n E4: Exenta por el artículo 23 y 24 de la Norma Foral del IVA.\n E5: Exenta por el artículo 25 de la Norma Foral del IVA.\n E6: Exenta por otra causa.\n ' selection=[(ExemptedCause.E1.value, 'E1'), (ExemptedCause.E2.value, 'E2'), (ExemptedCause.E3.value, 'E3'), (ExemptedCause.E4.value, 'E4'), (ExemptedCause.E5.value, 'E5'), (ExemptedCause.E6.value, 'E6')]
  • is_exempted Boolean
  • is_subject_to Boolean
    args: 'Is Subject to'
  • not_exempted_type Selection
    help='\n S1: Sin inversión del sujeto pasivo.\n S2: Con inversión del sujeto pasivo.\n ' selection=[(NotExemptedType.S1.value, 'S1'), (NotExemptedType.S2.value, 'S2')]
  • not_subject_to_cause Selection
    help='\n OT:\n - No sujeto por el artículo 7 de la Norma Foral de IVA Otros supuestos de no\n sujeción.\n RL:\n - No sujeto por reglas de localización.\n ' selection=[(NotSubjectToCause.OT.value, 'OT'), (NotSubjectToCause.RL.value, 'RL')] string='Not Subject to Cause'
  • re_amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Surcharge Amount (%)'
  • re_amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Surcharge Amount Total'
  • surcharge_or_simplified_regime Selection
    default=SurchargeOrSimplifiedRegimeType.N.value selection=[(SurchargeOrSimplifiedRegimeType.N.value, 'N'), (SurchargeOrSimplifiedRegimeType.S.value, 'S')] string='Surcharge or Simplified Regime'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • type Selection
    selection=[(TicketBaiTaxType.service.value, 'Service'), (TicketBaiTaxType.provision_of_goods.value, 'Provision of goods')]
Public methods (0)

No public methods.

New fields (5)
  • state Selection
    required=True selection=[(TicketBaiResponseState.RECEIVED.value, 'Received'), (TicketBaiResponseState.REJECTED.value, 'Rejected'), (TicketBaiResponseState.REQUEST_ERROR.value, 'Request error'), (TicketBaiResponseState.BUILD_ERROR.value, 'Build error')] string='Status'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • tbai_response_message_ids One2many → tbai.response.message
    comodel_name='tbai.response.message' inverse_name='tbai_response_id'
  • xml Binary
    attachment=True string='XML Response'
  • xml_fname Char
    args: 'File Name'
Public methods (2)
  • prepare_tbai_api_error_values(self, msg)
    @api.model
  • prepare_tbai_response_values(self, response)
    @api.model

New fields (3)
  • code Char
    required=True
  • description Char
    required=True translate=True
  • tbai_response_id Many2one → tbai.response
    comodel_name='tbai.response' ondelete='cascade' required=True
Public methods (2)
  • create(self, vals)
    @api.model
  • name_get(self)
    @api.depends('code', 'description')

New fields (11)
  • name Char
    required=True string='Tax Agency name'
  • qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='QR Base URL'
  • rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoices'
  • sign_file_hash Char
    required=True string='Sign File HASH'
  • sign_file_url Char
    required=True string='Sign File URL'
  • tax_agency_version_ids One2many → tbai.tax.agency.version
    comodel_name='tbai.tax.agency.version' inverse_name='tbai_tax_agency_id'
  • test_qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='Test QR Base URL'
  • test_rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoices'
  • version Char
    compute='_compute_ticketbai_version' store=True string='TicketBAI version'
Public methods (1)
  • get_current_version(self)

New fields (10)
  • date_from Date
  • date_to Date
  • qr_base_url Char
    required=True string='QR Base URL'
  • rest_url_cancellation Char
    string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    string='REST API URL for Invoices'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' ondelete='restrict' required=True
  • test_qr_base_url Char
    string='Test - QR Base URL'
  • test_rest_url_cancellation Char
    string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    string='Test - REST API URL for Invoices'
  • version Char
    required=True string='TicketBAI version'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/l10n-spain
GIT
GIThttps://github.com/OCA/l10n-spain.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/l10n-spain/tree/14.0/l10n_es_ticketbai_api
VERSION
VERSION 2.4.4
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Binovo
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Binovo
COMMITTERS
COMMITTERSPedro M. Baeza, Enric Tobella, OCA Transbot, oca-travis, Weblate, OCA-git-bot, Oihane Crucelaegui, oca-ci, Enrique Martín, Aritz Olea, luciaavanzosc
WEBSITE
WEBSITEhttps://github.com/OCA/l10n-spain
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:40:49
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - base_setup
    - web
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES cryptography<39
pyOpenSSL
qrcode
xmlsig
xmltodict
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
res_config_settings_view_form_inherit_l10n_es_ticketbai_api res.config.settings.view.form.inherit.base.setup.inherit.ticketbai_api res.config.settings xpath Inherits base_setup.res_config_settings_view_form
tbai_certificate_form_view tbai.certificate.view.form tbai.certificate form New
tbai_certificate_search_view tbai.certificate.view.search tbai.certificate search New
tbai_certificate_tree_view tbai.certificate.view.tree tbai.certificate tree New
tbai_installation_form_view tbai.installation.view.form tbai.installation form New
tbai_installation_search_view tbai.installation.view.search tbai.installation search New
tbai_installation_tree_view tbai.installation.view.tree tbai.installation tree New
view_company_form_inherit res.company.form.inherit res.company xpath Inherits base.view_company_form
Models touched (14)

New fields (14)
  • tbai_certificate_id Many2one → tbai.certificate
    comodel_name='tbai.certificate' copy=False domain="[('company_id', '=', id)]" string='Certificate'
  • tbai_developer_id Many2one → res.partner
    comodel_name='res.partner' readonly=True related='tbai_installation_id.developer_id' string='Developer'
  • tbai_device_serial_number Char
    copy=False default='' args: 'Device Serial Number'
  • tbai_enabled Boolean
    copy=False args: 'Enable TicketBAI'
  • tbai_installation_id Many2one → tbai.installation
    comodel_name='tbai.installation' copy=False
  • tbai_last_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False string='Last TicketBAI Invoice sent'
  • tbai_license_key Char
    readonly=True related='tbai_installation_id.license_key' args: 'License Key'
  • tbai_pro_available Boolean
    copy=False args: 'Are Production URLs Available'
  • tbai_software_name Char
    help='Registered name at the Tax Agency.' readonly=True related='tbai_installation_id.name' string='Software Name'
  • tbai_software_version Char
    copy=False help='Version of the software.' related='tbai_installation_id.version' string='Software Version'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' copy=False string='TBAI Tax Agency'
  • tbai_test_available Boolean
    copy=False args: 'Are Tests URLs Available'
  • tbai_test_enabled Boolean
    copy=False args: 'Enable testing'
  • tbai_vat_regime_simplified Boolean
    copy=False args: 'Regime Simplified'
Public methods (7)
  • is_operation_in_surcharge_equivalence_or_simplified_regime(self)
  • onchange_tbai_enabled(self)
    @api.onchange('tbai_enabled')
  • onchange_tbai_tax_agency(self)
    @api.onchange('tbai_tax_agency_id')
  • tbai_build_software(self)
  • tbai_certificate_get_p12(self)
  • tbai_certificate_get_p12_buffer(self)
  • tbai_certificate_get_p12_password(self)

New fields (2)
  • tbai_device_serial_number Char
    readonly=False related='company_id.tbai_device_serial_number' string='Device Serial Number'
  • tbai_enabled Boolean
    readonly=True related='company_id.tbai_enabled'
Public methods (0)

No public methods.

New fields (3)
  • tbai_enabled Boolean
    compute='_compute_tbai_enabled'
  • tbai_partner_identification_number Char
    default='' help='Used when the identification type code is not VAT identification number.' args: 'TicketBAI Partner Identification Number'
  • tbai_partner_idtype Selection
    default=TicketBaiCustomerIdType.T02.value selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='TicketBAI Identification Type Code'
Public methods (5)
  • tbai_get_partner_country_code(self)
  • tbai_get_partner_vat_number(self)
  • tbai_get_value_apellidos_nombre_razon_social(self)
    V 1.2 <element name="ApellidosNombreRazonSocial" type="T:TextMax120Type"/> <maxLength value="120"/> :return: Name and surname, or business name
  • tbai_get_value_direccion(self)
    V 1.2 <element name="Direccion" type="T:TextMax250Type" minOccurs="0"/> <maxLength value="250"/>
  • tbai_get_value_nif(self)
    V 1.2 <element name="NIF" type="T:NIFType"/> <length value="9" /> <pattern value="(([a-z|A-Z]{1}\d{7}[a-z|A-Z]{1})|(\d{8}[a-z|A-Z]{1})| ([a-z|A-Z]{1}\d{8}))" /> :return: VAT Number for Customers from Spain or the Company associated partner.

New fields (4)
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • datas Binary
    attachment=True required=True args: 'P12 Certificate'
  • name Char
    required=True
  • password Char
    default=''
Public methods (2)
  • get_p12(self)
    :return: cryptography.pkcs12
  • get_p12_buffer(self)
    :return: p12 Buffer

New fields (5)
  • developer_id Many2one → res.partner
    comodel_name='res.partner' copy=False required=True string='Developer'
  • license_key Char
    copy=False required=True args: 'License Key'
  • name Char
    copy=False help='Registered name at the Tax Agency.' required=True string='Software Name'
  • vat Char
    related='developer_id.vat' args: 'TIN'
  • version Char
    copy=False help='Version of the software.' required=True string='Software Version'
Public methods (0)

No public methods.

New fields (36)
  • amount_total Char
    default=''
  • api_url Char
    compute='_compute_api_url' args: 'TicketBAI API URL'
  • company_id Many2one → res.company
    comodel_name='res.company' required=True
  • datas Binary
    attachment=True copy=False
  • datas_fname Char
    copy=False args: 'File Name'
  • description Char
    default='/'
  • expedition_date Char
    required=True
  • expedition_hour Char
    default=''
  • file_size Integer
    copy=False args: 'File Size'
  • is_invoice_refund Boolean
    help='TicketBAI Invoice is a refund (Substitution or Differences).'
  • name Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • operation_date Char
    default=''
  • previous_tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False
  • qr Binary
    attachment=True compute='_compute_tbai_qr' copy=False store=True string='QR'
  • qr_url Char
    compute='_compute_tbai_qr' copy=False store=True args: 'URL'
  • refund_code Selection
    help='BOE-A-1992-28740. Ley 37/1992, de 28 de diciembre, del Impuesto sobre el Valor Añadido. Artículo 80. Modificación de la base imponible.' selection=[(RefundCode.R1.value, 'Art. 80.1, 80.2, 80.6 and rights founded error'), (RefundCode.R2.value, 'Art. 80.3'), (RefundCode.R3.value, 'Art. 80.4'), (RefundCode.R4.value, 'Art. 80 - other'), (RefundCode.R5.value, 'Simplified Invoice')] string='Invoice Refund Reason Code'
  • refund_type Selection
    help='Refund Invoice Type (S/Substitution or I/Differences).' selection=[(RefundType.substitution.value, 'S'), (RefundType.differences.value, 'I')]
  • schema Selection
    help='\n * TicketBai: Invoice\n * AnulaTicketBai: Invoice Cancellation\n ' required=True selection=[(TicketBaiSchema.TicketBai.value, 'TicketBai'), (TicketBaiSchema.AnulaTicketBai.value, 'AnulaTicketBai')]
  • signature_value Char
    copy=False default='' args: 'Signature Value'
  • simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • state Selection
    copy=False default=TicketBaiInvoiceState.draft.value index=True required=True selection=[(TicketBaiInvoiceState.draft.value, 'Draft'), (TicketBaiInvoiceState.pending.value, 'Pending'), (TicketBaiInvoiceState.sent.value, 'Sent'), (TicketBaiInvoiceState.cancel.value, 'Cancelled'), (TicketBaiInvoiceState.error.value, 'Error')] string='Status'
  • substituted_invoice_amount_total_untaxed Char
    default='' help='\n Original Invoice Total Amount without Taxes. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n - Total Tax Amount: 21 €\n * Amount Total Untaxed: 100 €\n '
  • substituted_invoice_total_tax_amount Char
    default='' help='\n Original Invoice Total Tax Amount. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n * Total Tax Amount: 21 €\n '
  • substitutes_simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • tax_retention_amount_total Char
    default='' args: 'Invoice Tax Retention Total Amount'
  • tbai_customer_ids One2many → tbai.invoice.customer
    comodel_name='tbai.invoice.customer' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Recipients'
  • tbai_identifier Char
    compute='_compute_tbai_identifier' copy=False store=True args: 'TBAI Identifier'
  • tbai_invoice_line_ids One2many → tbai.invoice.line
    comodel_name='tbai.invoice.line' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Details'
  • tbai_invoice_refund_ids One2many → tbai.invoice.refund
    comodel_name='tbai.invoice.refund' copy=True inverse_name='tbai_invoice_id' string='Refunded Invoices'
  • tbai_response_ids One2many → tbai.response
    comodel_name='tbai.response' inverse_name='tbai_invoice_id' string='Responses'
  • tbai_tax_ids One2many → tbai.invoice.tax
    comodel_name='tbai.invoice.tax' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Taxes'
  • vat_regime_key Char
    default='' args: 'VAT Regime Key'
  • vat_regime_key2 Char
    default='' args: 'Second VAT Regime Key'
  • vat_regime_key3 Char
    default='' args: 'Third VAT Regime Key'
Public methods (45)
  • build_cabecera(self)
    V 1.2 Get TicketBAI version from the Company Tax Agency. <element name="Cabecera" type="T:Cabecera"/> <complexType name="Cabecera"> <sequence> <element name="IDVersionTBAI" type="T:IDVersionTicketBaiType"/> <enumeration value="1.2"/> </sequence> </complexType> :return: Tax Agency
  • build_cabecera_factura(self)
  • build_cancellation(self)
  • build_claves(self)
    V 1.2 The specification document indicates that at least 1 regime key is required. <element name="IDClave" type="T:IDClaveType" maxOccurs="3"/> <sequence> <element name="ClaveRegimenIvaOpTrascendencia" type="T:IdOperacionesTrascendenciaTributariaType"/> </sequence> :return: dict
  • build_datos_factura(self)
  • build_destinatarios(self)
    Support only for one customer.
  • build_detalle_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> <sequence> <element name="CausaExencion" type="T:CausaExencionType" /> <restriction base="string"> <enumeration value="E1"> ... <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalle_no_exenta(self)
    V 1.2 1. Inversión del Sujeto Pasivo (ISP) taxes (tax is paid by the customer). 2. Other taxes <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> <sequence> <element name="TipoNoExenta" type="T:TipoOperacionSujetaNoExentaType"/> <restriction base="string"> <enumeration value="S1"> <enumeration value="S2"> <element name="DesgloseIVA" type="T:DesgloseIVAType"/> <element name="DetalleIVA" type="T:DetalleIVAType" maxOccurs="6" /> <sequence> <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> <element name="TipoImpositivo" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaImpuesto" type="T:ImporteSgn12.2Type" minOccurs="0" /> <element name="TipoRecargoEquivalencia" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaRecargoEquivalencia" type="T:ImporteSgn12.2Type" minOccurs="0"/> <element name="OperacionEnRecargoDeEquivalenciaORegimenSimplificado" type="T:SiNoType" minOccurs="0"/> :return: list<OrderedDict>
  • build_detalle_no_sujeta(self)
    V 1.2 <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> <sequence> <element name="Causa" type="T:CausaNoSujetaType"/> <element name="Importe" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalles_factura(self)
  • build_emisor(self)
  • build_encadenamiento_factura_anterior(self)
  • build_entrega(self)
    V 1.2 <element name="Entrega" type="T:Entrega" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> :return: dict
  • build_factura(self)
  • build_factura_rectificativa(self)
  • build_facturas_rectificadas_sustituidas(self)
  • build_huella_tbai(self)
  • build_id_detalle_factura(self)
  • build_id_factura(self)
  • build_importe_rectificacion_sustitutiva(self)
  • build_invoice(self)
  • build_no_exenta(self)
    V 1.2 <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> :return: dict
  • build_no_sujeta(self)
    V 1.2 <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> <sequence> <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> </sequence> :return: OrderedDict
  • build_prestacion_servicios(self)
    V 1.2 <element name="PrestacionServicios" type="T:PrestacionServicios" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_sujeta(self)
    V 1.2 <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <sequence> <element name="Exenta" type="T:ExentaType" minOccurs="0" /> <element name="NoExenta" type="T:NoExentaType" minOccurs="0" /> :return: OrderedDict
  • build_sujetos(self)
  • build_tbai_invoice(self)
  • build_tipo_desglose(self)
  • cancel(self)
  • error(self)
  • get_exempted_taxes(self)
    * Subject to: - Exempted :return: Recordset of tbai.invoice.tax
  • get_next_pending_invoice(self, company_id=False, limit=1)
    @api.model
  • get_not_exempted_taxes(self)
    * Subject to: - Not exempted :return: Recordset of tbai.invoice.tax
  • get_not_subject_to_taxes(self)
    * Not subject to :return: Recordset of tbai.invoice.tax
  • get_subject_to_taxes(self)
    * Subject to :return: Recordset of tbai.invoice.tax
  • get_taxes(self)
    Filter TicketBai Taxes when Customer is not from Spain. * DesgloseTipoOperacion - PrestacionServicios - Entrega :return: Recordset of tbai.invoice.tax
  • get_tbai_xml_signed_and_signature_value(self)
  • get_tbai_xml_unsigned(self)
  • get_ticketbai_api(self, **kwargs)
  • mark_as_pending(self)
  • mark_as_sent(self)
  • mark_chain_as_error(self, invoice_to_error)
    @api.model
  • send(self, **kwargs)
  • send_pending_invoices(self)
    @api.model

New fields (8)
  • address Char
    default=''
  • country_code Char
    required=True
  • identification_number Char
    default='' help='Required Identification Number for non spanish customers.'
  • idtype Selection
    default=TicketBaiCustomerIdType.T02.value help='Required for non spanish customers.' selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='Identification Type Code'
  • name Char
    help='Name and surname, or business name.' required=True
  • nif Char
    default='' help='Spanish Fiscal Identification Number' args: 'NIF'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • zip Char
    default='' args: 'ZIP Code'
Public methods (0)

No public methods.

New fields (6)
  • amount_total Char
    help='String of float with 12 digits and 2 decimal points.' required=True args: 'Amount Total'
  • description Char
    required=True args: 'Description'
  • discount_amount Char
    default='0.00' help='String of float with 12 digits and 2 decimal points.' args: 'Discount Amount'
  • price_unit Char
    help='String of float with 12 digits and 8 decimal points.' required=True args: 'Price Unit'
  • quantity Char
    help='String of float with 12 digits and 2 decimal points.' required=True args: 'Quantity'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (4)
  • expedition_date Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (13)
  • amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Amount (%)'
  • amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Amount Total'
  • base Char
    default='' help='String of float with 12 digits and 3 decimal points.' args: 'Base'
  • exempted_cause Selection
    help='\n E1: Exenta por el artículo 20 de la Norma Foral del IVA.\n E2: Exenta por el artículo 21 de la Norma Foral del IVA.\n E3: Exenta por el artículo 22 de la Norma Foral del IVA.\n E4: Exenta por el artículo 23 y 24 de la Norma Foral del IVA.\n E5: Exenta por el artículo 25 de la Norma Foral del IVA.\n E6: Exenta por otra causa.\n ' selection=[(ExemptedCause.E1.value, 'E1'), (ExemptedCause.E2.value, 'E2'), (ExemptedCause.E3.value, 'E3'), (ExemptedCause.E4.value, 'E4'), (ExemptedCause.E5.value, 'E5'), (ExemptedCause.E6.value, 'E6')] string='Exempted Cause'
  • is_exempted Boolean
    args: 'Is Exempted'
  • is_subject_to Boolean
    args: 'Is Subject to'
  • not_exempted_type Selection
    help='\n S1: Sin inversión del sujeto pasivo.\n S2: Con inversión del sujeto pasivo.\n ' selection=[(NotExemptedType.S1.value, 'S1'), (NotExemptedType.S2.value, 'S2')] string='Not Exempted Type'
  • not_subject_to_cause Selection
    help='\n OT:\n - No sujeto por el artículo 7 de la Norma Foral de IVA Otros supuestos de no\n sujeción.\n RL:\n - No sujeto por reglas de localización.\n ' selection=[(NotSubjectToCause.OT.value, 'OT'), (NotSubjectToCause.RL.value, 'RL')] string='Not Subject to Cause'
  • re_amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Surcharge Amount (%)'
  • re_amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Surcharge Amount Total'
  • surcharge_or_simplified_regime Selection
    default=SurchargeOrSimplifiedRegimeType.N.value selection=[(SurchargeOrSimplifiedRegimeType.N.value, 'N'), (SurchargeOrSimplifiedRegimeType.S.value, 'S')] string='Surcharge or Simplified Regime'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • type Selection
    selection=[(TicketBaiTaxType.service.value, 'Service'), (TicketBaiTaxType.provision_of_goods.value, 'Provision of goods')]
Public methods (0)

No public methods.

New fields (5)
  • state Selection
    required=True selection=[(TicketBaiResponseState.RECEIVED.value, 'Received'), (TicketBaiResponseState.REJECTED.value, 'Rejected'), (TicketBaiResponseState.REQUEST_ERROR.value, 'Request error'), (TicketBaiResponseState.BUILD_ERROR.value, 'Build error')] string='Status'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • tbai_response_message_ids One2many → tbai.response.message
    comodel_name='tbai.response.message' inverse_name='tbai_response_id'
  • xml Binary
    attachment=True string='XML Response'
  • xml_fname Char
    args: 'File Name'
Public methods (2)
  • prepare_tbai_api_error_values(self, msg)
    @api.model
  • prepare_tbai_response_values(self, response)
    @api.model

New fields (3)
  • code Char
    required=True
  • description Char
    required=True translate=True
  • tbai_response_id Many2one → tbai.response
    comodel_name='tbai.response' ondelete='cascade' required=True
Public methods (2)
  • create(self, vals)
    @api.model
  • name_get(self)
    @api.depends('code', 'description')

New fields (11)
  • name Char
    required=True string='Tax Agency name'
  • qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='QR Base URL'
  • rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoices'
  • sign_file_hash Char
    required=True string='Sign File HASH'
  • sign_file_url Char
    required=True string='Sign File URL'
  • tax_agency_version_ids One2many → tbai.tax.agency.version
    comodel_name='tbai.tax.agency.version' inverse_name='tbai_tax_agency_id'
  • test_qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='Test QR Base URL'
  • test_rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoices'
  • version Char
    compute='_compute_ticketbai_version' store=True string='TicketBAI version'
Public methods (1)
  • get_current_version(self)

New fields (10)
  • date_from Date
    string='Date from'
  • date_to Date
    string='Date to'
  • qr_base_url Char
    required=True string='QR Base URL'
  • rest_url_cancellation Char
    string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    string='REST API URL for Invoices'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' ondelete='restrict' required=True
  • test_qr_base_url Char
    string='Test - QR Base URL'
  • test_rest_url_cancellation Char
    string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    string='Test - REST API URL for Invoices'
  • version Char
    required=True string='TicketBAI version'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/l10n-spain
GIT
GIThttps://github.com/OCA/l10n-spain.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/l10n-spain/tree/13.0/l10n_es_ticketbai_api
VERSION
VERSION 1.5.8
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Binovo
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Binovo
COMMITTERS
COMMITTERSPedro M. Baeza, OCA Transbot, oca-travis, Weblate, OCA-git-bot, AdrianC, oca-ci, Aritz Olea
WEBSITE
WEBSITEhttps://github.com/OCA/l10n-spain
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:34:09
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - base_setup
    - web
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES OpenSSL
cryptography<39
qrcode
requests_pkcs12
xmlsig
xmltodict
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
res_config_settings_view_form_inherit_l10n_es_ticketbai_api res.config.settings.view.form.inherit.base.setup.inherit.ticketbai_api res.config.settings xpath Inherits base_setup.res_config_settings_view_form
tbai_certificate_form_view tbai.certificate.view.form tbai.certificate form New
tbai_certificate_search_view tbai.certificate.view.search tbai.certificate search New
tbai_certificate_tree_view tbai.certificate.view.tree tbai.certificate tree New
tbai_installation_form_view tbai.installation.view.form tbai.installation form New
tbai_installation_search_view tbai.installation.view.search tbai.installation search New
tbai_installation_tree_view tbai.installation.view.tree tbai.installation tree New
view_company_form_inherit res.company.form.inherit res.company xpath Inherits base.view_company_form
Models touched (14)

New fields (14)
  • tbai_certificate_id Many2one → tbai.certificate
    comodel_name='tbai.certificate' copy=False domain="[('company_id', '=', id)]" string='Certificate'
  • tbai_developer_id Many2one → res.partner
    comodel_name='res.partner' readonly=True related='tbai_installation_id.developer_id' string='Developer'
  • tbai_device_serial_number Char
    copy=False default='' args: 'Device Serial Number'
  • tbai_enabled Boolean
    copy=False args: 'Enable TicketBAI'
  • tbai_installation_id Many2one → tbai.installation
    comodel_name='tbai.installation' copy=False
  • tbai_last_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False string='Last TicketBAI Invoice sent'
  • tbai_license_key Char
    readonly=True related='tbai_installation_id.license_key' args: 'License Key'
  • tbai_pro_available Boolean
    copy=False args: 'Are Production URLs Available'
  • tbai_software_name Char
    help='Registered name at the Tax Agency.' readonly=True related='tbai_installation_id.name' string='Software Name'
  • tbai_software_version Char
    copy=False help='Version of the software.' related='tbai_installation_id.version' string='Software Version'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' copy=False string='TicketBAI Tax Agency'
  • tbai_test_available Boolean
    copy=False args: 'Are Tests URLs Available'
  • tbai_test_enabled Boolean
    copy=False args: 'Enable testing'
  • tbai_vat_regime_simplified Boolean
    copy=False args: 'Regime Simplified'
Public methods (6)
  • onchange_tbai_enabled(self)
    @api.onchange('tbai_enabled')
  • onchange_tbai_tax_agency(self)
    @api.onchange('tbai_tax_agency_id')
  • tbai_build_software(self)
  • tbai_certificate_get_p12(self)
  • tbai_certificate_get_p12_buffer(self)
  • tbai_certificate_get_p12_password(self)

New fields (2)
  • tbai_device_serial_number Char
    readonly=False related='company_id.tbai_device_serial_number' string='Device Serial Number'
  • tbai_enabled Boolean
    readonly=True related='company_id.tbai_enabled'
Public methods (0)

No public methods.

New fields (3)
  • tbai_enabled Boolean
    compute='_compute_tbai_enabled'
  • tbai_partner_identification_number Char
    default='' help='Used when the identification type code is not VAT identification number.' args: 'TicketBAI Partner Identification Number'
  • tbai_partner_idtype Selection
    default=TicketBaiCustomerIdType.T02.value selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='TicketBAI Identification Type Code'
Public methods (5)
  • tbai_get_partner_country_code(self)
  • tbai_get_partner_vat_number(self)
  • tbai_get_value_apellidos_nombre_razon_social(self)
    V 1.2 <element name="ApellidosNombreRazonSocial" type="T:TextMax120Type"/> <maxLength value="120"/> :return: Name and surname, or business name
  • tbai_get_value_direccion(self)
    V 1.2 <element name="Direccion" type="T:TextMax250Type" minOccurs="0"/> <maxLength value="250"/>
  • tbai_get_value_nif(self)
    V 1.2 <element name="NIF" type="T:NIFType"/> <length value="9" /> <pattern value="(([a-z|A-Z]{1}\d{7}[a-z|A-Z]{1})|(\d{8}[a-z|A-Z]{1})| ([a-z|A-Z]{1}\d{8}))" /> :return: VAT Number for Customers from Spain or the Company associated partner.

New fields (4)
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • datas Binary
    attachment=True required=True args: 'P12 Certificate'
  • name Char
    required=True
  • password Char
    default=''
Public methods (2)
  • get_p12(self)
    :return: OpenSSL.crypto.PKCS12
  • get_p12_buffer(self)
    :return: p12 Buffer

New fields (5)
  • developer_id Many2one → res.partner
    comodel_name='res.partner' copy=False required=True string='Developer'
  • license_key Char
    copy=False required=True args: 'License Key'
  • name Char
    copy=False help='Registered name at the Tax Agency.' required=True string='Software Name'
  • vat Char
    related='developer_id.vat' args: 'TIN'
  • version Char
    copy=False help='Version of the software.' required=True string='Software Version'
Public methods (0)

No public methods.

New fields (36)
  • amount_total Char
    default=''
  • api_url Char
    compute='_compute_api_url' args: 'TicketBAI API URL'
  • company_id Many2one → res.company
    comodel_name='res.company' required=True
  • datas Binary
    attachment=True copy=False
  • datas_fname Char
    copy=False args: 'File Name'
  • description Char
    default='/'
  • expedition_date Char
    required=True
  • expedition_hour Char
    default=''
  • file_size Integer
    copy=False args: 'File Size'
  • is_invoice_refund Boolean
    help='TicketBAI Invoice is a refund (Substitution or Differences).'
  • name Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • operation_date Char
    default=''
  • previous_tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False
  • qr Binary
    attachment=True compute='_compute_tbai_qr' copy=False store=True string='QR'
  • qr_url Char
    compute='_compute_tbai_qr' copy=False store=True args: 'URL'
  • refund_code Selection
    help='BOE-A-1992-28740. Ley 37/1992, de 28 de diciembre, del Impuesto sobre el Valor Añadido. Artículo 80. Modificación de la base imponible.' selection=[(RefundCode.R1.value, 'Art. 80.1, 80.2, 80.6 and rights founded error'), (RefundCode.R2.value, 'Art. 80.3'), (RefundCode.R3.value, 'Art. 80.4'), (RefundCode.R4.value, 'Art. 80 - other')] string='Invoice Refund Reason Code'
  • refund_type Selection
    help='Refund Invoice Type (S/Substitution or I/Differences).' selection=[(RefundType.substitution.value, 'S'), (RefundType.differences.value, 'I')]
  • schema Selection
    help='\n * TicketBai: Invoice\n * AnulaTicketBai: Invoice Cancellation\n ' required=True selection=[(TicketBaiSchema.TicketBai.value, 'TicketBai'), (TicketBaiSchema.AnulaTicketBai.value, 'AnulaTicketBai')]
  • signature_value Char
    copy=False default='' args: 'Signature Value'
  • simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • state Selection
    copy=False default=TicketBaiInvoiceState.draft.value index=True required=True selection=[(TicketBaiInvoiceState.draft.value, 'Draft'), (TicketBaiInvoiceState.pending.value, 'Pending'), (TicketBaiInvoiceState.sent.value, 'Sent'), (TicketBaiInvoiceState.cancel.value, 'Cancelled'), (TicketBaiInvoiceState.error.value, 'Error')] string='Status'
  • substituted_invoice_amount_total_untaxed Char
    default='' help='\n Original Invoice Total Amount without Taxes. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n - Total Tax Amount: 21 €\n * Amount Total Untaxed: 100 €\n '
  • substituted_invoice_total_tax_amount Char
    default='' help='\n Original Invoice Total Tax Amount. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n * Total Tax Amount: 21 €\n '
  • substitutes_simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • tax_retention_amount_total Char
    default='' args: 'Invoice Tax Retention Total Amount'
  • tbai_customer_ids One2many → tbai.invoice.customer
    comodel_name='tbai.invoice.customer' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Recipients'
  • tbai_identifier Char
    compute='_compute_tbai_identifier' copy=False store=True args: 'TBAI Identifier'
  • tbai_invoice_line_ids One2many → tbai.invoice.line
    comodel_name='tbai.invoice.line' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Details'
  • tbai_invoice_refund_ids One2many → tbai.invoice.refund
    comodel_name='tbai.invoice.refund' copy=True inverse_name='tbai_invoice_id' string='Refunded Invoices'
  • tbai_response_ids One2many → tbai.response
    comodel_name='tbai.response' inverse_name='tbai_invoice_id' string='Responses'
  • tbai_tax_ids One2many → tbai.invoice.tax
    comodel_name='tbai.invoice.tax' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Taxes'
  • vat_regime_key Char
    default='' args: 'VAT Regime Key'
  • vat_regime_key2 Char
    default='' args: 'Second VAT Regime Key'
  • vat_regime_key3 Char
    default='' args: 'Third VAT Regime Key'
Public methods (45)
  • build_cabecera(self)
    V 1.2 Get TicketBAI version from the Company Tax Agency. <element name="Cabecera" type="T:Cabecera"/> <complexType name="Cabecera"> <sequence> <element name="IDVersionTBAI" type="T:IDVersionTicketBaiType"/> <enumeration value="1.2"/> </sequence> </complexType> :return: Tax Agency
  • build_cabecera_factura(self)
  • build_cancellation(self)
  • build_claves(self)
    V 1.2 The specification document indicates that at least 1 regime key is required. <element name="IDClave" type="T:IDClaveType" maxOccurs="3"/> <sequence> <element name="ClaveRegimenIvaOpTrascendencia" type="T:IdOperacionesTrascendenciaTributariaType"/> </sequence> :return: dict
  • build_datos_factura(self)
  • build_destinatarios(self)
    Support only for one customer.
  • build_detalle_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> <sequence> <element name="CausaExencion" type="T:CausaExencionType" /> <restriction base="string"> <enumeration value="E1"> ... <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalle_no_exenta(self)
    V 1.2 1. Inversión del Sujeto Pasivo (ISP) taxes (tax is paid by the customer). 2. Other taxes <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> <sequence> <element name="TipoNoExenta" type="T:TipoOperacionSujetaNoExentaType"/> <restriction base="string"> <enumeration value="S1"> <enumeration value="S2"> <element name="DesgloseIVA" type="T:DesgloseIVAType"/> <element name="DetalleIVA" type="T:DetalleIVAType" maxOccurs="6" /> <sequence> <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> <element name="TipoImpositivo" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaImpuesto" type="T:ImporteSgn12.2Type" minOccurs="0" /> <element name="TipoRecargoEquivalencia" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaRecargoEquivalencia" type="T:ImporteSgn12.2Type" minOccurs="0"/> <element name="OperacionEnRecargoDeEquivalenciaORegimenSimplificado" type="T:SiNoType" minOccurs="0"/> :return: list<OrderedDict>
  • build_detalle_no_sujeta(self)
    V 1.2 <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> <sequence> <element name="Causa" type="T:CausaNoSujetaType"/> <element name="Importe" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalles_factura(self)
  • build_emisor(self)
  • build_encadenamiento_factura_anterior(self)
  • build_entrega(self)
    V 1.2 <element name="Entrega" type="T:Entrega" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> :return: dict
  • build_factura(self)
  • build_factura_rectificativa(self)
  • build_facturas_rectificadas_sustituidas(self)
  • build_huella_tbai(self)
  • build_id_detalle_factura(self)
  • build_id_factura(self)
  • build_importe_rectificacion_sustitutiva(self)
  • build_invoice(self)
  • build_no_exenta(self)
    V 1.2 <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> :return: dict
  • build_no_sujeta(self)
    V 1.2 <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> <sequence> <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> </sequence> :return: OrderedDict
  • build_prestacion_servicios(self)
    V 1.2 <element name="PrestacionServicios" type="T:PrestacionServicios" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_sujeta(self)
    V 1.2 <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <sequence> <element name="Exenta" type="T:ExentaType" minOccurs="0" /> <element name="NoExenta" type="T:NoExentaType" minOccurs="0" /> :return: OrderedDict
  • build_sujetos(self)
  • build_tbai_invoice(self)
  • build_tipo_desglose(self)
  • cancel(self)
  • error(self)
  • get_exempted_taxes(self)
    * Subject to: - Exempted :return: Recordset of tbai.invoice.tax
  • get_next_pending_invoice(self, company_id=False, limit=1)
    @api.model
  • get_not_exempted_taxes(self)
    * Subject to: - Not exempted :return: Recordset of tbai.invoice.tax
  • get_not_subject_to_taxes(self)
    * Not subject to :return: Recordset of tbai.invoice.tax
  • get_subject_to_taxes(self)
    * Subject to :return: Recordset of tbai.invoice.tax
  • get_taxes(self)
    Filter TicketBai Taxes when Customer is not from Spain. * DesgloseTipoOperacion - PrestacionServicios - Entrega :return: Recordset of tbai.invoice.tax
  • get_tbai_xml_signed_and_signature_value(self)
  • get_tbai_xml_unsigned(self)
  • get_ticketbai_api(self, **kwargs)
  • mark_as_pending(self)
  • mark_as_sent(self)
  • mark_chain_as_error(self, invoice_to_error)
    @api.model
  • send(self, **kwargs)
  • send_pending_invoices(self)
    @api.model

New fields (8)
  • address Char
    default=''
  • country_code Char
    required=True
  • identification_number Char
    default='' help='Required Identification Number for non spanish customers.'
  • idtype Selection
    default=TicketBaiCustomerIdType.T02.value help='Required for non spanish customers.' selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='Identification Type Code'
  • name Char
    help='Name and surname, or business name.' required=True
  • nif Char
    default='' help='Spanish Fiscal Identification Number' args: 'NIF'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • zip Char
    default='' args: 'ZIP Code'
Public methods (0)

No public methods.

New fields (6)
  • amount_total Char
    help='String of float with 12 digits and 2 decimal points.' required=True args: 'Amount Total'
  • description Char
    required=True args: 'Description'
  • discount_amount Char
    default='0.00' help='String of float with 12 digits and 2 decimal points.' args: 'Discount Amount'
  • price_unit Char
    help='String of float with 12 digits and 8 decimal points.' required=True args: 'Price Unit'
  • quantity Char
    help='String of float with 12 digits and 2 decimal points.' required=True args: 'Quantity'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (4)
  • expedition_date Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (13)
  • amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Amount (%)'
  • amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Amount Total'
  • base Char
    default='' help='String of float with 12 digits and 3 decimal points.' args: 'Base'
  • exempted_cause Selection
    help='\n E1: Exenta por el artículo 20 de la Norma Foral del IVA.\n E2: Exenta por el artículo 21 de la Norma Foral del IVA.\n E3: Exenta por el artículo 22 de la Norma Foral del IVA.\n E4: Exenta por el artículo 23 y 24 de la Norma Foral del IVA.\n E5: Exenta por el artículo 25 de la Norma Foral del IVA.\n E6: Exenta por otra causa.\n ' selection=[(ExemptedCause.E1.value, 'E1'), (ExemptedCause.E2.value, 'E2'), (ExemptedCause.E3.value, 'E3'), (ExemptedCause.E4.value, 'E4'), (ExemptedCause.E5.value, 'E5'), (ExemptedCause.E6.value, 'E6')] string='Exempted Cause'
  • is_exempted Boolean
    args: 'Is Exempted'
  • is_subject_to Boolean
    args: 'Is Subject to'
  • not_exempted_type Selection
    help='\n S1: Sin inversión del sujeto pasivo.\n S2: Con inversión del sujeto pasivo.\n ' selection=[(NotExemptedType.S1.value, 'S1'), (NotExemptedType.S2.value, 'S2')] string='Not Exempted Type'
  • not_subject_to_cause Selection
    help='\n OT:\n - No sujeto por el artículo 7 de la Norma Foral de IVA Otros supuestos de no\n sujeción.\n RL:\n - No sujeto por reglas de localización.\n ' selection=[(NotSubjectToCause.OT.value, 'OT'), (NotSubjectToCause.RL.value, 'RL')] string='Not Subject to Cause'
  • re_amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Surcharge Amount (%)'
  • re_amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Surcharge Amount Total'
  • surcharge_or_simplified_regime Selection
    default=SurchargeOrSimplifiedRegimeType.N.value selection=[(SurchargeOrSimplifiedRegimeType.N.value, 'N'), (SurchargeOrSimplifiedRegimeType.S.value, 'S')] string='Surcharge or Simplified Regime'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • type Selection
    selection=[(TicketBaiTaxType.service.value, 'Service'), (TicketBaiTaxType.provision_of_goods.value, 'Provision of goods')]
Public methods (0)

No public methods.

New fields (5)
  • state Selection
    required=True selection=[(TicketBaiResponseState.RECEIVED.value, 'Received'), (TicketBaiResponseState.REJECTED.value, 'Rejected'), (TicketBaiResponseState.REQUEST_ERROR.value, 'Request error'), (TicketBaiResponseState.BUILD_ERROR.value, 'Build error')] string='Status'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • tbai_response_message_ids One2many → tbai.response.message
    comodel_name='tbai.response.message' inverse_name='tbai_response_id'
  • xml Binary
    attachment=True string='XML Response'
  • xml_fname Char
    args: 'File Name'
Public methods (2)
  • prepare_tbai_api_error_values(self, msg)
    @api.model
  • prepare_tbai_response_values(self, response)
    @api.model

New fields (3)
  • code Char
    required=True
  • description Char
    required=True translate=True
  • tbai_response_id Many2one → tbai.response
    comodel_name='tbai.response' ondelete='cascade' required=True
Public methods (2)
  • create(self, vals)
    @api.model
  • name_get(self)
    @api.depends('code', 'description')

New fields (11)
  • name Char
    required=True string='Tax Agency name'
  • qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='QR Base URL'
  • rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoices'
  • sign_file_hash Char
    required=True string='Sign File HASH'
  • sign_file_url Char
    required=True string='Sign File URL'
  • tax_agency_version_ids One2many → tbai.tax.agency.version
    comodel_name='tbai.tax.agency.version' inverse_name='tbai_tax_agency_id'
  • test_qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='Test QR Base URL'
  • test_rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoices'
  • version Char
    compute='_compute_ticketbai_version' store=True string='TicketBAI version'
Public methods (1)
  • get_current_version(self)

New fields (10)
  • date_from Date
    string='Date from'
  • date_to Date
    string='Date to'
  • qr_base_url Char
    required=True string='QR Base URL'
  • rest_url_cancellation Char
    string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    string='REST API URL for Invoices'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' ondelete='restrict' required=True
  • test_qr_base_url Char
    string='Test - QR Base URL'
  • test_rest_url_cancellation Char
    string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    string='Test - REST API URL for Invoices'
  • version Char
    required=True string='TicketBAI version'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/l10n-spain
GIT
GIThttps://github.com/OCA/l10n-spain.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/l10n-spain/tree/12.0/l10n_es_ticketbai_api
VERSION
VERSION 2.3.8
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Binovo
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Binovo
COMMITTERS
COMMITTERSOCA Transbot, oca-travis, Weblate, OCA-git-bot, Oihane Crucelaegui, oca-ci, Aritz Olea, xAdrianC, Tu Nombre, ao-landoo
WEBSITE
WEBSITEhttps://github.com/OCA/l10n-spain
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:29:13
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - base_setup
    - web
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES OpenSSL
cryptography
qrcode
requests_pkcs12
xmlsig
xmltodict
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
res_config_settings_view_form_inherit_l10n_es_ticketbai_api res.config.settings.view.form.inherit.base.setup.inherit.ticketbai_api res.config.settings xpath Inherits base_setup.res_config_settings_view_form
tbai_certificate_form_view tbai.certificate.view.form tbai.certificate form New
tbai_certificate_search_view tbai.certificate.view.search tbai.certificate search New
tbai_certificate_tree_view tbai.certificate.view.tree tbai.certificate tree New
tbai_installation_form_view tbai.installation.view.form tbai.installation form New
tbai_installation_search_view tbai.installation.view.search tbai.installation search New
tbai_installation_tree_view tbai.installation.view.tree tbai.installation tree New
view_company_form_inherit res.company.form.inherit res.company xpath Inherits base.view_company_form
Models touched (14)

New fields (13)
  • tbai_certificate_id Many2one → tbai.certificate
    comodel_name='tbai.certificate' copy=False domain="[('company_id', '=', id)]" string='Certificate'
  • tbai_developer_id Many2one → res.partner
    comodel_name='res.partner' readonly=True related='tbai_installation_id.developer_id' string='Developer'
  • tbai_device_serial_number Char
    copy=False default='' args: 'Device Serial Number'
  • tbai_enabled Boolean
    copy=False args: 'Enable TicketBAI'
  • tbai_installation_id Many2one → tbai.installation
    comodel_name='tbai.installation' copy=False
  • tbai_last_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False string='Last TicketBAI Invoice sent'
  • tbai_license_key Char
    readonly=True related='tbai_installation_id.license_key' args: 'License Key'
  • tbai_pro_available Boolean
    copy=False args: 'Are Production URLs Available'
  • tbai_software_name Char
    help='Registered name at the Tax Agency.' readonly=True related='tbai_installation_id.name' string='Software Name'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' copy=False string='TicketBAI Tax Agency'
  • tbai_test_available Boolean
    copy=False args: 'Are Tests URLs Available'
  • tbai_test_enabled Boolean
    copy=False args: 'Enable testing'
  • tbai_vat_regime_simplified Boolean
    copy=False args: 'Regime Simplified'
Public methods (6)
  • onchange_tbai_enabled(self)
    @api.onchange('tbai_enabled')
  • onchange_tbai_tax_agency(self)
    @api.onchange('tbai_tax_agency_id')
  • tbai_build_software(self)
  • tbai_certificate_get_p12(self)
  • tbai_certificate_get_p12_buffer(self)
  • tbai_certificate_get_p12_password(self)

New fields (2)
  • tbai_device_serial_number Char
    company_dependent=True readonly=False related='company_id.tbai_device_serial_number' string='Device Serial Number'
  • tbai_enabled Boolean
    company_dependent=True readonly=True related='company_id.tbai_enabled'
Public methods (0)

No public methods.

New fields (3)
  • tbai_enabled Boolean
    readonly=True related='company_id.tbai_enabled'
  • tbai_partner_identification_number Char
    default='' help='Used when the identification type code is not VAT identification number.' args: 'TicketBAI Partner Identification Number'
  • tbai_partner_idtype Selection
    default=TicketBaiCustomerIdType.T02.value selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='TicketBAI Identification Type Code'
Public methods (5)
  • tbai_get_partner_country_code(self)
  • tbai_get_partner_vat_number(self)
  • tbai_get_value_apellidos_nombre_razon_social(self)
    V 1.2 <element name="ApellidosNombreRazonSocial" type="T:TextMax120Type"/> <maxLength value="120"/> :return: Name and surname, or business name
  • tbai_get_value_direccion(self)
    V 1.2 <element name="Direccion" type="T:TextMax250Type" minOccurs="0"/> <maxLength value="250"/>
  • tbai_get_value_nif(self)
    V 1.2 <element name="NIF" type="T:NIFType"/> <length value="9" /> <pattern value="(([a-z|A-Z]{1}\d{7}[a-z|A-Z]{1})|(\d{8}[a-z|A-Z]{1})| ([a-z|A-Z]{1}\d{8}))" /> :return: VAT Number for Customers from Spain or the Company associated partner.

New fields (4)
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • datas Binary
    attachment=True required=True args: 'P12 Certificate'
  • name Char
    required=True
  • password Char
    default=''
Public methods (2)
  • get_p12(self)
    :return: OpenSSL.crypto.PKCS12
  • get_p12_buffer(self)
    :return: p12 Buffer

New fields (4)
  • developer_id Many2one → res.partner
    comodel_name='res.partner' copy=False required=True string='Developer'
  • license_key Char
    copy=False required=True args: 'License Key'
  • name Char
    copy=False help='Registered name at the Tax Agency.' required=True string='Software Name'
  • vat Char
    related='developer_id.vat' args: 'TIN'
Public methods (0)

No public methods.

New fields (36)
  • amount_total Char
    default=''
  • api_url Char
    compute='_compute_api_url' args: 'TicketBAI API URL'
  • company_id Many2one → res.company
    comodel_name='res.company' required=True
  • datas Binary
    attachment=True copy=False
  • datas_fname Char
    copy=False args: 'File Name'
  • description Char
    default='/'
  • expedition_date Char
    required=True
  • expedition_hour Char
    default=''
  • file_size Integer
    copy=False args: 'File Size'
  • is_invoice_refund Boolean
    help='TicketBAI Invoice is a refund (Substitution or Differences).'
  • name Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • operation_date Char
    default=''
  • previous_tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False
  • qr Binary
    attachment=True compute='_compute_tbai_qr' copy=False store=True string='QR'
  • qr_url Char
    compute='_compute_tbai_qr' copy=False store=True args: 'URL'
  • refund_code Selection
    help='BOE-A-1992-28740. Ley 37/1992, de 28 de diciembre, del Impuesto sobre el Valor Añadido. Artículo 80. Modificación de la base imponible.' selection=[(RefundCode.R1.value, 'Art. 80.1, 80.2, 80.6 and rights founded error'), (RefundCode.R2.value, 'Art. 80.3'), (RefundCode.R3.value, 'Art. 80.4'), (RefundCode.R4.value, 'Art. 80 - other'), (RefundCode.R5.value, 'Simplified Invoice')] string='Invoice Refund Reason Code'
  • refund_type Selection
    help='Refund Invoice Type (S/Substitution or I/Differences).' selection=[(RefundType.substitution.value, 'S'), (RefundType.differences.value, 'I')]
  • schema Selection
    help='\n * TicketBai: Invoice\n * AnulaTicketBai: Invoice Cancellation\n ' required=True selection=[(TicketBaiSchema.TicketBai.value, 'TicketBai'), (TicketBaiSchema.AnulaTicketBai.value, 'AnulaTicketBai')]
  • signature_value Char
    copy=False default='' args: 'Signature Value'
  • simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • state Selection
    copy=False default=TicketBaiInvoiceState.draft.value index=True required=True selection=[(TicketBaiInvoiceState.draft.value, 'Draft'), (TicketBaiInvoiceState.pending.value, 'Pending'), (TicketBaiInvoiceState.sent.value, 'Sent'), (TicketBaiInvoiceState.cancel.value, 'Cancelled'), (TicketBaiInvoiceState.error.value, 'Error')] string='Status'
  • substituted_invoice_amount_total_untaxed Char
    default='' help='\n Original Invoice Total Amount without Taxes. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n - Total Tax Amount: 21 €\n * Amount Total Untaxed: 100 €\n '
  • substituted_invoice_total_tax_amount Char
    default='' help='\n Original Invoice Total Tax Amount. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n * Total Tax Amount: 21 €\n '
  • substitutes_simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • tax_retention_amount_total Char
    default='' args: 'Invoice Tax Retention Total Amount'
  • tbai_customer_ids One2many → tbai.invoice.customer
    comodel_name='tbai.invoice.customer' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Recipients'
  • tbai_identifier Char
    compute='_compute_tbai_identifier' copy=False store=True args: 'TBAI Identifier'
  • tbai_invoice_line_ids One2many → tbai.invoice.line
    comodel_name='tbai.invoice.line' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Details'
  • tbai_invoice_refund_ids One2many → tbai.invoice.refund
    comodel_name='tbai.invoice.refund' copy=True inverse_name='tbai_invoice_id' string='Refunded Invoices'
  • tbai_response_ids One2many → tbai.response
    comodel_name='tbai.response' inverse_name='tbai_invoice_id' string='Responses'
  • tbai_tax_ids One2many → tbai.invoice.tax
    comodel_name='tbai.invoice.tax' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Taxes'
  • vat_regime_key Char
    default='' args: 'VAT Regime Key'
  • vat_regime_key2 Char
    default='' args: 'Second VAT Regime Key'
  • vat_regime_key3 Char
    default='' args: 'Third VAT Regime Key'
Public methods (45)
  • build_cabecera(self)
    V 1.2 Get TicketBAI version from the Company Tax Agency. <element name="Cabecera" type="T:Cabecera"/> <complexType name="Cabecera"> <sequence> <element name="IDVersionTBAI" type="T:IDVersionTicketBaiType"/> <enumeration value="1.2"/> </sequence> </complexType> :return: Tax Agency
  • build_cabecera_factura(self)
  • build_cancellation(self)
  • build_claves(self)
    V 1.2 The specification document indicates that at least 1 regime key is required. <element name="IDClave" type="T:IDClaveType" maxOccurs="3"/> <sequence> <element name="ClaveRegimenIvaOpTrascendencia" type="T:IdOperacionesTrascendenciaTributariaType"/> </sequence> :return: dict
  • build_datos_factura(self)
  • build_destinatarios(self)
    Support only for one customer.
  • build_detalle_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> <sequence> <element name="CausaExencion" type="T:CausaExencionType" /> <restriction base="string"> <enumeration value="E1"> ... <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalle_no_exenta(self)
    V 1.2 1. Inversión del Sujeto Pasivo (ISP) taxes (tax is paid by the customer). 2. Other taxes <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> <sequence> <element name="TipoNoExenta" type="T:TipoOperacionSujetaNoExentaType"/> <restriction base="string"> <enumeration value="S1"> <enumeration value="S2"> <element name="DesgloseIVA" type="T:DesgloseIVAType"/> <element name="DetalleIVA" type="T:DetalleIVAType" maxOccurs="6" /> <sequence> <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> <element name="TipoImpositivo" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaImpuesto" type="T:ImporteSgn12.2Type" minOccurs="0" /> <element name="TipoRecargoEquivalencia" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaRecargoEquivalencia" type="T:ImporteSgn12.2Type" minOccurs="0"/> <element name="OperacionEnRecargoDeEquivalenciaORegimenSimplificado" type="T:SiNoType" minOccurs="0"/> :return: list<OrderedDict>
  • build_detalle_no_sujeta(self)
    V 1.2 <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> <sequence> <element name="Causa" type="T:CausaNoSujetaType"/> <element name="Importe" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalles_factura(self)
  • build_emisor(self)
  • build_encadenamiento_factura_anterior(self)
  • build_entrega(self)
    V 1.2 <element name="Entrega" type="T:Entrega" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> :return: dict
  • build_factura(self)
  • build_factura_rectificativa(self)
  • build_facturas_rectificadas_sustituidas(self)
  • build_huella_tbai(self)
  • build_id_detalle_factura(self)
  • build_id_factura(self)
  • build_importe_rectificacion_sustitutiva(self)
  • build_invoice(self)
  • build_no_exenta(self)
    V 1.2 <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> :return: dict
  • build_no_sujeta(self)
    V 1.2 <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> <sequence> <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> </sequence> :return: OrderedDict
  • build_prestacion_servicios(self)
    V 1.2 <element name="PrestacionServicios" type="T:PrestacionServicios" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_sujeta(self)
    V 1.2 <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <sequence> <element name="Exenta" type="T:ExentaType" minOccurs="0" /> <element name="NoExenta" type="T:NoExentaType" minOccurs="0" /> :return: OrderedDict
  • build_sujetos(self)
  • build_tbai_invoice(self)
  • build_tipo_desglose(self)
  • cancel(self)
    @api.multi
  • error(self)
    @api.multi
  • get_exempted_taxes(self)
    * Subject to: - Exempted :return: Recordset of tbai.invoice.tax
  • get_next_pending_invoice(self, company_id=False, limit=1)
    @api.model
  • get_not_exempted_taxes(self)
    * Subject to: - Not exempted :return: Recordset of tbai.invoice.tax
  • get_not_subject_to_taxes(self)
    * Not subject to :return: Recordset of tbai.invoice.tax
  • get_subject_to_taxes(self)
    * Subject to :return: Recordset of tbai.invoice.tax
  • get_taxes(self)
    Filter TicketBai Taxes when Customer is not from Spain. * DesgloseTipoOperacion - PrestacionServicios - Entrega :return: Recordset of tbai.invoice.tax
  • get_tbai_xml_signed_and_signature_value(self)
  • get_tbai_xml_unsigned(self)
  • get_ticketbai_api(self, **kwargs)
    @api.multi
  • mark_as_pending(self)
    @api.multi
  • mark_as_sent(self)
    @api.multi
  • mark_chain_as_error(self, invoice_to_error)
    @api.model
  • send(self, **kwargs)
    @api.multi
  • send_pending_invoices(self)
    @api.model

New fields (8)
  • address Char
    default=''
  • country_code Char
    required=True
  • identification_number Char
    default='' help='Required Identification Number for non spanish customers.'
  • idtype Selection
    default=TicketBaiCustomerIdType.T02.value help='Required for non spanish customers.' selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='Identification Type Code'
  • name Char
    help='Name and surname, or business name.' required=True
  • nif Char
    default='' help='Spanish Fiscal Identification Number' args: 'NIF'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • zip Char
    default='' args: 'ZIP Code'
Public methods (0)

No public methods.

New fields (6)
  • amount_total Char
    help='String of float with 12 digits and 2 decimal points.' required=True args: 'Amount Total'
  • description Char
    required=True args: 'Description'
  • discount_amount Char
    default='0.00' help='String of float with 12 digits and 2 decimal points.' args: 'Discount Amount'
  • price_unit Char
    help='String of float with 12 digits and 8 decimal points.' required=True args: 'Price Unit'
  • quantity Char
    help='String of float with 12 digits and 2 decimal points.' required=True args: 'Quantity'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (4)
  • expedition_date Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (13)
  • amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Amount (%)'
  • amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Amount Total'
  • base Char
    default='' help='String of float with 12 digits and 3 decimal points.' args: 'Base'
  • exempted_cause Selection
    help='\n E1: Exenta por el artículo 20 de la Norma Foral del IVA.\n E2: Exenta por el artículo 21 de la Norma Foral del IVA.\n E3: Exenta por el artículo 22 de la Norma Foral del IVA.\n E4: Exenta por el artículo 23 y 24 de la Norma Foral del IVA.\n E5: Exenta por el artículo 25 de la Norma Foral del IVA.\n E6: Exenta por otra causa.\n ' selection=[(ExemptedCause.E1.value, 'E1'), (ExemptedCause.E2.value, 'E2'), (ExemptedCause.E3.value, 'E3'), (ExemptedCause.E4.value, 'E4'), (ExemptedCause.E5.value, 'E5'), (ExemptedCause.E6.value, 'E6')] string='Exempted Cause'
  • is_exempted Boolean
    args: 'Is Exempted'
  • is_subject_to Boolean
    args: 'Is Subject to'
  • not_exempted_type Selection
    help='\n S1: Sin inversión del sujeto pasivo.\n S2: Con inversión del sujeto pasivo.\n ' selection=[(NotExemptedType.S1.value, 'S1'), (NotExemptedType.S2.value, 'S2')] string='Not Exempted Type'
  • not_subject_to_cause Selection
    help='\n OT:\n - No sujeto por el artículo 7 de la Norma Foral de IVA Otros supuestos de no\n sujeción.\n RL:\n - No sujeto por reglas de localización.\n ' selection=[(NotSubjectToCause.OT.value, 'OT'), (NotSubjectToCause.RL.value, 'RL')] string='Not Subject to Cause'
  • re_amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Surcharge Amount (%)'
  • re_amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Surcharge Amount Total'
  • surcharge_or_simplified_regime Selection
    default=SurchargeOrSimplifiedRegimeType.N.value selection=[(SurchargeOrSimplifiedRegimeType.N.value, 'N'), (SurchargeOrSimplifiedRegimeType.S.value, 'S')] string='Surcharge or Simplified Regime'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • type Selection
    selection=[(TicketBaiTaxType.service.value, 'Service'), (TicketBaiTaxType.provision_of_goods.value, 'Provision of goods')]
Public methods (0)

No public methods.

New fields (5)
  • state Selection
    required=True selection=[(TicketBaiResponseState.RECEIVED.value, 'Received'), (TicketBaiResponseState.REJECTED.value, 'Rejected'), (TicketBaiResponseState.REQUEST_ERROR.value, 'Request error'), (TicketBaiResponseState.BUILD_ERROR.value, 'Build error')] string='Status'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • tbai_response_message_ids One2many → tbai.response.message
    comodel_name='tbai.response.message' inverse_name='tbai_response_id'
  • xml Binary
    attachment=True string='XML Response'
  • xml_fname Char
    args: 'File Name'
Public methods (2)
  • prepare_tbai_api_error_values(self, msg, **kwargs)
    @api.model
  • prepare_tbai_response_values(self, response, **kwargs)
    @api.model

New fields (3)
  • code Char
    required=True
  • description Char
    required=True translate=True
  • tbai_response_id Many2one → tbai.response
    comodel_name='tbai.response' ondelete='cascade' required=True
Public methods (2)
  • create(self, vals)
    @api.model
  • name_get(self)
    @api.multi@api.depends('code', 'description')

New fields (11)
  • name Char
    required=True string='Tax Agency name'
  • qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='QR Base URL'
  • rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoices'
  • sign_file_hash Char
    required=True string='Sign File HASH'
  • sign_file_url Char
    required=True string='Sign File URL'
  • tax_agency_version_ids One2many → tbai.tax.agency.version
    comodel_name='tbai.tax.agency.version' inverse_name='tbai_tax_agency_id'
  • test_qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='Test QR Base URL'
  • test_rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoices'
  • version Char
    compute='_compute_ticketbai_version' store=True string='TicketBAI version'
Public methods (1)
  • get_current_version(self)
    @api.multi

New fields (10)
  • date_from Date
    string='Date from'
  • date_to Date
    string='Date to'
  • qr_base_url Char
    required=True string='QR Base URL'
  • rest_url_cancellation Char
    string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    string='REST API URL for Invoices'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' ondelete='restrict' required=True
  • test_qr_base_url Char
    string='Test - QR Base URL'
  • test_rest_url_cancellation Char
    string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    string='Test - REST API URL for Invoices'
  • version Char
    required=True string='TicketBAI version'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/l10n-spain
GIT
GIThttps://github.com/OCA/l10n-spain.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/l10n-spain/tree/11.0/l10n_es_ticketbai_api
VERSION
VERSION 0.7.5
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Binovo
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Binovo
COMMITTERS
COMMITTERSPedro M. Baeza, OCA Transbot, oca-travis, OCA-git-bot, Victor Laskurain, Enrique Martín, arodriguez, Aritz Olea, Guillermo Murcia
WEBSITE
WEBSITEhttps://github.com/OCA/l10n-spain
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:23:55
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - base_setup
    - web
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES OpenSSL
cryptography
qrcode
requests_pkcs12
xmlsig
xmltodict
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
res_config_settings_view_form_inherit_l10n_es_ticketbai_api res.config.settings.view.form.inherit.base.setup.inherit.ticketbai_api res.config.settings xpath Inherits base_setup.res_config_settings_view_form
tbai_certificate_form_view tbai.certificate.view.form tbai.certificate form New
tbai_certificate_search_view tbai.certificate.view.search tbai.certificate search New
tbai_certificate_tree_view tbai.certificate.view.tree tbai.certificate tree New
tbai_installation_form_view tbai.installation.view.form tbai.installation form New
tbai_installation_search_view tbai.installation.view.search tbai.installation search New
tbai_installation_tree_view tbai.installation.view.tree tbai.installation tree New
view_company_form_inherit res.company.form.inherit res.company xpath Inherits base.view_company_form
Models touched (14)

New fields (14)
  • tbai_certificate_id Many2one → tbai.certificate
    comodel_name='tbai.certificate' copy=False domain="[('company_id', '=', id)]" string='Certificate'
  • tbai_developer_id Many2one → res.partner
    comodel_name='res.partner' readonly=True related='tbai_installation_id.developer_id' string='Developer'
  • tbai_device_serial_number Char
    copy=False default='' args: 'Device Serial Number'
  • tbai_enabled Boolean
    copy=False args: 'Enable TicketBAI'
  • tbai_installation_id Many2one → tbai.installation
    comodel_name='tbai.installation' copy=False
  • tbai_last_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False string='Last TicketBAI Invoice sent'
  • tbai_license_key Char
    readonly=True related='tbai_installation_id.license_key' args: 'License Key'
  • tbai_pro_available Boolean
    copy=False args: 'Are Production URLs Available'
  • tbai_software_name Char
    help='Registered name at the Tax Agency.' readonly=True related='tbai_installation_id.name' string='Software Name'
  • tbai_software_version Char
    copy=False help='Version of the software.' related='tbai_installation_id.version' string='Software Version'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' copy=False string='Tax Agency'
  • tbai_test_available Boolean
    copy=False args: 'Are Tests URLs Available'
  • tbai_test_enabled Boolean
    copy=False args: 'Enable testing'
  • tbai_vat_regime_simplified Boolean
    copy=False args: 'Regime Simplified'
Public methods (6)
  • onchange_tbai_enabled(self)
    @api.onchange('tbai_enabled')
  • onchange_tbai_tax_agency(self)
    @api.onchange('tbai_tax_agency_id')
  • tbai_build_software(self)
  • tbai_certificate_get_p12(self)
  • tbai_certificate_get_p12_buffer(self)
  • tbai_certificate_get_p12_password(self)

New fields (2)
  • tbai_device_serial_number Char
    company_dependent=True readonly=False related='company_id.tbai_device_serial_number' string='Device Serial Number'
  • tbai_enabled Boolean
    company_dependent=True readonly=True related='company_id.tbai_enabled'
Public methods (0)

No public methods.

New fields (3)
  • tbai_enabled Boolean
    readonly=True related='company_id.tbai_enabled'
  • tbai_partner_identification_number Char
    default='' help='Used when the identification type code is not VAT identification number.' args: 'TicketBAI Partner Identification Number'
  • tbai_partner_idtype Selection
    default=TicketBaiCustomerIdType.T02.value selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='TicketBAI Identification Type Code'
Public methods (5)
  • tbai_get_partner_country_code(self)
  • tbai_get_partner_vat_number(self)
  • tbai_get_value_apellidos_nombre_razon_social(self)
    V 1.2 <element name="ApellidosNombreRazonSocial" type="T:TextMax120Type"/> <maxLength value="120"/> :return: Name and surname, or business name
  • tbai_get_value_direccion(self)
    V 1.2 <element name="Direccion" type="T:TextMax250Type" minOccurs="0"/> <maxLength value="250"/>
  • tbai_get_value_nif(self)
    V 1.2 <element name="NIF" type="T:NIFType"/> <length value="9" /> <pattern value="(([a-z|A-Z]{1}\d{7}[a-z|A-Z]{1})|(\d{8}[a-z|A-Z]{1})| ([a-z|A-Z]{1}\d{8}))" /> :return: VAT Number for Customers from Spain or the Company associated partner.

New fields (4)
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • datas Binary
    attachment=True required=True args: 'P12 Certificate'
  • name Char
    required=True
  • password Char
    default=''
Public methods (2)
  • get_p12(self)
    :return: OpenSSL.crypto.PKCS12
  • get_p12_buffer(self)
    :return: p12 Buffer

New fields (5)
  • developer_id Many2one → res.partner
    comodel_name='res.partner' copy=False required=True string='Developer'
  • license_key Char
    copy=False required=True args: 'License Key'
  • name Char
    copy=False help='Registered name at the Tax Agency.' required=True string='Software Name'
  • vat Char
    related='developer_id.vat' args: 'TIN'
  • version Char
    copy=False help='Version of the software.' required=True string='Software Version'
Public methods (0)

No public methods.

New fields (36)
  • amount_total Char
    default=''
  • api_url Char
    compute='_compute_api_url' args: 'TicketBAI API URL'
  • company_id Many2one → res.company
    comodel_name='res.company' required=True
  • datas Binary
    attachment=True copy=False
  • datas_fname Char
    copy=False args: 'File Name'
  • description Char
    default='/'
  • expedition_date Char
    required=True
  • expedition_hour Char
    default=''
  • file_size Integer
    copy=False args: 'File Size'
  • is_invoice_refund Boolean
    help='TicketBAI Invoice is a refund (Substitution or Differences).'
  • name Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • operation_date Char
    default=''
  • previous_tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' copy=False
  • qr Binary
    attachment=True compute='_compute_tbai_qr' copy=False store=True string='QR'
  • qr_url Char
    compute='_compute_tbai_qr' copy=False store=True args: 'URL'
  • refund_code Selection
    help='BOE-A-1992-28740. Ley 37/1992, de 28 de diciembre, del Impuesto sobre el Valor Añadido. Artículo 80. Modificación de la base imponible.' selection=[(RefundCode.R1.value, 'Art. 80.1, 80.2, 80.6 and rights founded error'), (RefundCode.R2.value, 'Art. 80.3'), (RefundCode.R3.value, 'Art. 80.4'), (RefundCode.R4.value, 'Art. 80 - other')] string='Invoice Refund Reason Code'
  • refund_type Selection
    help='Refund Invoice Type (S/Substitution or I/Differences).' selection=[(RefundType.substitution.value, 'S'), (RefundType.differences.value, 'I')]
  • schema Selection
    help='\n * TicketBai: Invoice\n * AnulaTicketBai: Invoice Cancellation\n ' required=True selection=[(TicketBaiSchema.TicketBai.value, 'TicketBai'), (TicketBaiSchema.AnulaTicketBai.value, 'AnulaTicketBai')]
  • signature_value Char
    copy=False default='' args: 'Signature Value'
  • simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • state Selection
    copy=False default=TicketBaiInvoiceState.draft.value index=True required=True selection=[(TicketBaiInvoiceState.draft.value, 'Draft'), (TicketBaiInvoiceState.pending.value, 'Pending'), (TicketBaiInvoiceState.sent.value, 'Sent'), (TicketBaiInvoiceState.cancel.value, 'Cancelled'), (TicketBaiInvoiceState.error.value, 'Error')]
  • substituted_invoice_amount_total_untaxed Char
    default='' help='\n Original Invoice Total Amount without Taxes. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n - Total Tax Amount: 21 €\n * Amount Total Untaxed: 100 €\n '
  • substituted_invoice_total_tax_amount Char
    default='' help='\n Original Invoice Total Tax Amount. E.g.:\n - Amount Total: 121.0 €\n - Tax Amount: 21 %\n * Total Tax Amount: 21 €\n '
  • substitutes_simplified_invoice Selection
    help='S/Yes or N/No' selection=[(SiNoType.S.value, 'S'), (SiNoType.N.value, 'N')]
  • tax_retention_amount_total Char
    default='' args: 'Invoice Tax Retention Total Amount'
  • tbai_customer_ids One2many → tbai.invoice.customer
    comodel_name='tbai.invoice.customer' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Recipients'
  • tbai_identifier Char
    compute='_compute_tbai_identifier' copy=False store=True args: 'TBAI Identifier'
  • tbai_invoice_line_ids One2many → tbai.invoice.line
    comodel_name='tbai.invoice.line' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Details'
  • tbai_invoice_refund_ids One2many → tbai.invoice.refund
    comodel_name='tbai.invoice.refund' copy=True inverse_name='tbai_invoice_id' string='Refunded Invoices'
  • tbai_response_ids One2many → tbai.response
    comodel_name='tbai.response' inverse_name='tbai_invoice_id' string='Responses'
  • tbai_tax_ids One2many → tbai.invoice.tax
    comodel_name='tbai.invoice.tax' copy=True inverse_name='tbai_invoice_id' string='TicketBAI Invoice Taxes'
  • vat_regime_key Char
    default='' args: 'VAT Regime Key'
  • vat_regime_key2 Char
    default='' args: 'Second VAT Regime Key'
  • vat_regime_key3 Char
    default='' args: 'Third VAT Regime Key'
Public methods (46)
  • build_cabecera(self)
    V 1.2 Get TicketBAI version from the Company Tax Agency. <element name="Cabecera" type="T:Cabecera"/> <complexType name="Cabecera"> <sequence> <element name="IDVersionTBAI" type="T:IDVersionTicketBaiType"/> <enumeration value="1.2"/> </sequence> </complexType> :return: Tax Agency
  • build_cabecera_factura(self)
  • build_cancellation(self)
  • build_claves(self)
    V 1.2 The specification document indicates that at least 1 regime key is required. <element name="IDClave" type="T:IDClaveType" maxOccurs="3"/> <sequence> <element name="ClaveRegimenIvaOpTrascendencia" type="T:IdOperacionesTrascendenciaTributariaType"/> </sequence> :return: dict
  • build_datos_factura(self)
  • build_destinatarios(self)
    Support only for one customer.
  • build_detalle_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> <sequence> <element name="CausaExencion" type="T:CausaExencionType" /> <restriction base="string"> <enumeration value="E1"> ... <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalle_no_exenta(self)
    V 1.2 1. Inversión del Sujeto Pasivo (ISP) taxes (tax is paid by the customer). 2. Other taxes <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> <sequence> <element name="TipoNoExenta" type="T:TipoOperacionSujetaNoExentaType"/> <restriction base="string"> <enumeration value="S1"> <enumeration value="S2"> <element name="DesgloseIVA" type="T:DesgloseIVAType"/> <element name="DetalleIVA" type="T:DetalleIVAType" maxOccurs="6" /> <sequence> <element name="BaseImponible" type="T:ImporteSgn12.2Type"/> <element name="TipoImpositivo" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaImpuesto" type="T:ImporteSgn12.2Type" minOccurs="0" /> <element name="TipoRecargoEquivalencia" type="T:Tipo3.2Type" minOccurs="0"/> <element name="CuotaRecargoEquivalencia" type="T:ImporteSgn12.2Type" minOccurs="0"/> <element name="OperacionEnRecargoDeEquivalenciaORegimenSimplificado" type="T:SiNoType" minOccurs="0"/> :return: list<OrderedDict>
  • build_detalle_no_sujeta(self)
    V 1.2 <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> <sequence> <element name="Causa" type="T:CausaNoSujetaType"/> <element name="Importe" type="T:ImporteSgn12.2Type"/> </sequence> :return: list<OrderedDict>
  • build_detalles_factura(self)
  • build_emisor(self)
  • build_encadenamiento_factura_anterior(self)
  • build_entrega(self)
    V 1.2 <element name="Entrega" type="T:Entrega" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_exenta(self)
    V 1.2 <element name="DetalleExenta" type="T:DetalleExentaType" minOccurs="1" maxOccurs="7" /> :return: dict
  • build_factura(self)
  • build_factura_rectificativa(self)
  • build_facturas_rectificadas_sustituidas(self)
  • build_huella_tbai(self)
  • build_id_detalle_factura(self)
  • build_id_factura(self)
  • build_importe_rectificacion_sustitutiva(self)
  • build_invoice(self)
  • build_no_exenta(self)
    V 1.2 <element name="DetalleNoExenta" type="T:DetalleNoExentaType" minOccurs="1" maxOccurs="2" /> :return: dict
  • build_no_sujeta(self)
    V 1.2 <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> <sequence> <element name="DetalleNoSujeta" type="T:DetalleNoSujeta" minOccurs="1" maxOccurs="2" /> </sequence> :return: OrderedDict
  • build_prestacion_servicios(self)
    V 1.2 <element name="PrestacionServicios" type="T:PrestacionServicios" minOccurs="0"/> <sequence> <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <element name="NoSujeta" type="T:NoSujetaType" minOccurs="0" /> </sequence> :return: OrderedDict
  • build_sujeta(self)
    V 1.2 <element name="Sujeta" type="T:SujetaType" minOccurs="0" /> <sequence> <element name="Exenta" type="T:ExentaType" minOccurs="0" /> <element name="NoExenta" type="T:NoExentaType" minOccurs="0" /> :return: OrderedDict
  • build_sujetos(self)
  • build_tbai_invoice(self)
  • build_tipo_desglose(self)
  • cancel(self)
    @api.multi
  • error(self)
    @api.multi
  • get_exempted_taxes(self)
    * Subject to: - Exempted :return: Recordset of tbai.invoice.tax
  • get_next_pending_invoice(self, company_id=False, limit=1)
    @api.model
  • get_not_exempted_taxes(self)
    * Subject to: - Not exempted :return: Recordset of tbai.invoice.tax
  • get_not_subject_to_taxes(self)
    * Not subject to :return: Recordset of tbai.invoice.tax
  • get_subject_to_taxes(self)
    * Subject to :return: Recordset of tbai.invoice.tax
  • get_taxes(self)
    Filter TicketBai Taxes when Customer is not from Spain. * DesgloseTipoOperacion - PrestacionServicios - Entrega :return: Recordset of tbai.invoice.tax
  • get_tbai_xml_signed_and_signature_value(self)
  • get_tbai_xml_unsigned(self)
  • get_ticketbai_api(self, **kwargs)
    @api.multi
  • mark_as_pending(self)
    @api.multi
  • mark_as_sent(self)
    @api.multi
  • mark_chain_as_error(self, invoice_to_error)
    @api.model
  • send(self, **kwargs)
    @api.multi
  • send_pending_invoices(self)
    @api.model
  • send_pending_invoices_impl(self)
    @api.model

New fields (8)
  • address Char
    default=''
  • country_code Char
    required=True
  • identification_number Char
    default='' help='Required Identification Number for non spanish customers.'
  • idtype Selection
    default=TicketBaiCustomerIdType.T02.value help='Required for non spanish customers.' selection=[(TicketBaiCustomerIdType.T02.value, 'VAT identification number'), (TicketBaiCustomerIdType.T03.value, 'Passport'), (TicketBaiCustomerIdType.T04.value, 'Official identification document issued by the country or territory of residence'), (TicketBaiCustomerIdType.T05.value, 'Residence certificate'), (TicketBaiCustomerIdType.T06.value, 'Other document')] string='Identification Type Code'
  • name Char
    help='Name and surname, or business name.' required=True
  • nif Char
    default='' help='Spanish Fiscal Identification Number' args: 'NIF'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • zip Char
    default='' args: 'ZIP Code'
Public methods (0)

No public methods.

New fields (6)
  • amount_total Char
    help='String of float with 12 digits and 2 decimal points.' required=True args: 'Amount Total'
  • description Char
    required=True args: 'Description'
  • discount_amount Char
    default='0.00' help='String of float with 12 digits and 2 decimal points.' args: 'Discount Amount'
  • price_unit Char
    help='String of float with 12 digits and 8 decimal points.' required=True args: 'Price Unit'
  • quantity Char
    help='String of float with 12 digits and 2 decimal points.' required=True args: 'Quantity'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (4)
  • expedition_date Char
    required=True
  • number Char
    required=True
  • number_prefix Char
    default=''
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
Public methods (0)

No public methods.

New fields (13)
  • amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Amount (%)'
  • amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Amount Total'
  • base Char
    default='' help='String of float with 12 digits and 3 decimal points.' args: 'Base'
  • exempted_cause Selection
    help='\n E1: Exenta por el artículo 20 de la Norma Foral del IVA.\n E2: Exenta por el artículo 21 de la Norma Foral del IVA.\n E3: Exenta por el artículo 22 de la Norma Foral del IVA.\n E4: Exenta por el artículo 23 y 24 de la Norma Foral del IVA.\n E5: Exenta por el artículo 25 de la Norma Foral del IVA.\n E6: Exenta por otra causa.\n ' selection=[(ExemptedCause.E1.value, 'E1'), (ExemptedCause.E2.value, 'E2'), (ExemptedCause.E3.value, 'E3'), (ExemptedCause.E4.value, 'E4'), (ExemptedCause.E5.value, 'E5'), (ExemptedCause.E6.value, 'E6')] string='Exempted Cause'
  • is_exempted Boolean
    args: 'Is Exempted'
  • is_subject_to Boolean
    args: 'Is Subject to'
  • not_exempted_type Selection
    help='\n S1: Sin inversión del sujeto pasivo.\n S2: Con inversión del sujeto pasivo.\n ' selection=[(NotExemptedType.S1.value, 'S1'), (NotExemptedType.S2.value, 'S2')] string='Not Exempted Type'
  • not_subject_to_cause Selection
    help='\n OT:\n - No sujeto por el artículo 7 de la Norma Foral de IVA Otros supuestos de no\n sujeción.\n RL:\n - No sujeto por reglas de localización.\n ' selection=[(NotSubjectToCause.OT.value, 'OT'), (NotSubjectToCause.RL.value, 'RL')] string='Not Subject to Cause'
  • re_amount Char
    default='' help='String of float with 3 digits and 2 decimal points.' args: 'Surcharge Amount (%)'
  • re_amount_total Char
    default='' help='String of float with 12 digits and 2 decimal points.' args: 'Surcharge Amount Total'
  • surcharge_or_simplified_regime Selection
    default=SurchargeOrSimplifiedRegimeType.N.value selection=[(SurchargeOrSimplifiedRegimeType.N.value, 'N'), (SurchargeOrSimplifiedRegimeType.S.value, 'S')] string='Surcharge or Simplified Regime'
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • type Selection
    selection=[(TicketBaiTaxType.service.value, 'Service'), (TicketBaiTaxType.provision_of_goods.value, 'Provision of goods')]
Public methods (0)

No public methods.

New fields (5)
  • state Selection
    required=True selection=[(TicketBaiResponseState.RECEIVED.value, 'Received'), (TicketBaiResponseState.REJECTED.value, 'Rejected'), (TicketBaiResponseState.REQUEST_ERROR.value, 'Request error'), (TicketBaiResponseState.BUILD_ERROR.value, 'Build error')]
  • tbai_invoice_id Many2one → tbai.invoice
    comodel_name='tbai.invoice' ondelete='cascade' required=True
  • tbai_response_message_ids One2many → tbai.response.message
    comodel_name='tbai.response.message' inverse_name='tbai_response_id'
  • xml Binary
    attachment=True string='XML Response'
  • xml_fname Char
    args: 'File Name'
Public methods (2)
  • prepare_tbai_api_error_values(self, msg, **kwargs)
    @api.model
  • prepare_tbai_response_values(self, response, **kwargs)
    @api.model

New fields (3)
  • code Char
    required=True
  • description Char
    required=True translate=True
  • tbai_response_id Many2one → tbai.response
    comodel_name='tbai.response' ondelete='cascade' required=True
Public methods (2)
  • create(self, vals)
    @api.model
  • name_get(self)
    @api.multi@api.depends('code', 'description')

New fields (11)
  • name Char
    required=True string='Tax Agency'
  • qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='QR Base URL'
  • rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='REST API URL for Invoices'
  • sign_file_hash Char
    required=True string='Sign File HASH'
  • sign_file_url Char
    required=True string='Sign File URL'
  • tax_agency_version_ids One2many → tbai.tax.agency.version
    comodel_name='tbai.tax.agency.version' inverse_name='tbai_tax_agency_id'
  • test_qr_base_url Char
    compute='_compute_ticketbai_version' store=True string='QR Base URL'
  • test_rest_url_cancellation Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    compute='_compute_ticketbai_version' store=True string='Test - REST API URL for Invoices'
  • version Char
    compute='_compute_ticketbai_version' store=True string='TicketBAI version'
Public methods (1)
  • get_current_version(self)
    @api.multi

New fields (10)
  • date_from Date
    string='Date from'
  • date_to Date
    string='Date to'
  • qr_base_url Char
    required=True string='QR Base URL'
  • rest_url_cancellation Char
    string='REST API URL for Invoice Cancellations'
  • rest_url_invoice Char
    string='REST API URL for Invoices'
  • tbai_tax_agency_id Many2one → tbai.tax.agency
    comodel_name='tbai.tax.agency' ondelete='restrict' required=True
  • test_qr_base_url Char
    string='Test - QR Base URL'
  • test_rest_url_cancellation Char
    string='Test - REST API URL for Invoice Cancellations'
  • test_rest_url_invoice Char
    string='Test - REST API URL for Invoices'
  • version Char
    required=True string='TicketBAI version'
Public methods (0)

No public methods.