Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Spanish CAE Number #446

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 248 additions & 0 deletions stdnum/es/cae.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
# cae.py - functions for handling Spanish CAE number
# coding: utf-8
#
# Copyright (C) 2024 Quique Porta
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA

"""CAE (Código de Actividad y Establecimiento).

The CAE number is a 13-digit number and that allows you to identify an
activity and the establishment in which it is carried out.

The sixth and seventh characters identify the managing office in which
the territorial registration is carried out.

And the eighth and ninth characters identify the activity that takes place.

This is the official BOE (Boletín Oficial del Estado) about the CAE number:
https://www.boe.es/boe/dias/2006/12/28/pdfs/A46098-46100.pdf

This is the online checker from the Spanish Tax Agency (Agencia Tributaria):
https://www2.agenciatributaria.gob.es/L/inwinvoc/es.aeat.dit.adu.adce.cae.cw.AccW?fAccion=consulta

This is the explanation of the CAE number in the Spanish Tax Agency:
https://sede.agenciatributaria.gob.es/Sede/impuestos-especiales-medioambientales/censo-impuestos-especiales-medioambientales/registro-impuestos-especiales-fabricacion.html?faqId=3cc75c714b11c710VgnVCM100000dc381e0aRCRD


>>> validate('ES00008V1488Q')
'ES00008V1488Q'
>>> validate('00008V1488') # invalid check length
Traceback (most recent call last):
...
InvalidLength: ...
>>> is_valid('ES00008V1488Q')
True
>>> is_valid('00008V1488')
False
>>> compact('ES00008V1488Q')
'ES00008V1488Q'
"""

from stdnum.exceptions import *
from stdnum.util import clean


def compact(number):
"""Compact Spanish CAE Number"""
return clean(number).upper().strip()


def validate(number):
"""Check if the number provided is a valid CAE number. This checks the
length and formatting."""
number = compact(number)

if len(number) != 13:
raise InvalidLength()

if number[:2] != 'ES':
raise InvalidFormat()

if number[2:5] != '000':
raise InvalidFormat()

if number[5:7] not in OFFICES:
raise InvalidFormat()

if number[7:9] not in ACTIVITY_KEYS:
raise InvalidFormat()

if not number[9:12].isdigit():
raise InvalidFormat()

if not number[12].isalpha():
raise InvalidFormat()

return number


def is_valid(number):
"""Check if the number provided is a valid CAE number. This checks the
length and formatting."""
try:
return bool(validate(number))
except ValidationError:
return False


OFFICES = [
'01', # 'Álava'
'02', # 'Albacete'
'03', # 'Alicante'
'04', # 'Almería'
'05', # 'Ávila'
'06', # 'Badajoz'
'07', # 'Illes Balears'
'08', # 'Barcelona'
'09', # 'Burgos'
'10', # 'Cáceres'
'11', # 'Cádiz'
'12', # 'Castellón'
'13', # 'Ciudad Real'
'14', # 'Córdoba'
'15', # 'A Coruña'
'16', # 'Cuenca'
'17', # 'Girona'
'18', # 'Granada'
'19', # 'Guadalajara'
'20', # 'Guipúzcoa'
'21', # 'Huelva'
'22', # 'Huesca'
'23', # 'Jaén'
'24', # 'León'
'25', # 'Lleida'
'26', # 'La Rioja'
'27', # 'Lugo'
'28', # 'Madrid'
'29', # 'Málaga'
'30', # 'Murcia'
'31', # 'Navarra'
'32', # 'Ourense'
'33', # 'Oviedo'
'34', # 'Palencia'
'35', # 'Las Palmas'
'36', # 'Pontevedra'
'37', # 'Salamanca'
'38', # 'Santa Cruz de Tenerife'
'39', # 'Santander'
'40', # 'Segovia'
'41', # 'Sevilla'
'42', # 'Soria'
'43', # 'Tarragona'
'44', # 'Teruel'
'45', # 'Toledo'
'46', # 'Valencia'
'47', # 'Valladolid'
'48', # 'Bizcaia'
'49', # 'Zamora'
'50', # 'Zaragoza'
'51', # 'Cartagena'
'52', # 'Gijón'
'53', # 'Jerez de la Frontera'
'54', # 'Vigo'
'55', # 'Ceuta'
'56', # 'Melilla'
]

ACTIVITY_KEYS = [
'A1', # "Fábricas de alcohol."
'B1', # "Fábricas de bebidas derivadas."
'B9', # "Elaboradores de productos intermedios distintos de los comprendidos en B-0."
'B0', # "Elaboradores de productos intermedios en régimen especial."
'BA', # "Fábricas de bebidas alcohólicas."
'C1', # "Fábricas de cerveza."
'DA', # "Destiladores artesanales."
'EC', # "Fábricas de extractos y concentrados alcohólicos."
'F1', # "Elaboradores de otras bebidas fermentadas."
'V1', # "Elaboradores de vinos."
'A7', # "Depósitos fiscales de alcohol."
'AT', # "Almacenes fiscales de alcohol."
'B7', # "Depósitos fiscales de bebidas derivadas."
'BT', # "Almacenes fiscales de bebidas alcohólicas."
'C7', # "Depósitos fiscales de cerveza."
'DB', # "Depósitos fiscales de bebidas alcohólicas."
'E7', # "Depósitos fiscales de extractos y concentrados alcohólicos exclusivamente."
'M7', # "Depósitos fiscales de productos intermedios."
'OA', # "Operadores registrados de alcohol."
'OB', # "Operadores registrados de bebidas alcohólicas."
'OE', # "Operadores registrados de extractos y concentrados alcohólicos."
'OV', # "Operadores registrados de vinos y de otras bebidas fermentadas."
'V7', # "Depósitos fiscales de vinos y de otras bebidas fermentadas."
'B6', # "Plantas embotelladoras de bebidas derivadas."
'A2', # "Centros de investigación."
'A6', # "Usuarios de alcohol totalmente desnaturalizado."
'A9', # "Industrias de especialidades farmacéuticas."
'A0', # "Centros de atención médica."
'AC', # "Usuarios con derecho a devolución."
'AV', # "Usuarios de alcohol parcialmente desnaturalizado con desnaturalizante general."
'AW', # "Usuarios de alcohol parcialmente desnaturalizado con desnaturalizante especial."
'AX', # "Fábricas de vinagre."
'H1', # "Refinerías de crudo de petróleo."
'H2', # "Fábricas de biocarburante, consistente en alcohol etílico."
'H4', # "Fábricas de biocarburante o biocombustible con sistente en biodiesel."
'H6', # "Fábricas de biocarburante o biocombustible con sistente en alcohol metílico."
'H9', # "Industrias extractoras de gas natural y otros productos gaseosos."
'H0', # "Las demás industrias que obtienen productos gravados."
'HD', # "Industrias o establecimientos que someten productos a un tratamiento definido o,
# previa solicitud, a una transformación química."
'HH', # "Industrias extractoras de crudo de petróleo."
'H7', # "Depósitos fiscales de hidrocarburos."
'H8', # "Depósitos fiscales exclusivamente de biocarburantes."
'HB', # "Obtención accesoria de productos sujetos alimpuesto."
'HF', # "Almacenes fiscales para el suministro directo a instalaciones fijas."
'HI', # "Depósitos fiscales exclusivamente para la distribución de querosenos y gasolinas de aviación."
'HJ', # "Depósitos fiscales exclusivamente de productos de la tarifa segunda."
'HK', # "Instalaciones de venta de gas natural con tipo general y tipo reducido."
'HL', # "Almacenes fiscales exclusivamente de productos de la tarifa segunda."
'HM', # "Almacenes fiscales para la gestión de aceites usados destinados a su utilización como combustibles."
'HN', # "Depósitos fiscales constituidos por una red de oleoductos."
'HT', # "Almacenes fiscales para el comercio al por mayor de hidrocarburos."
'HU', # "Almacenes fiscales constituidos por redes de transporte o distribución de gas natural."
'HV', # "Puntos de suministro marítimo de gasóleo."
'HX', # "Depósitos fiscales constituidos por una red de gasoductos."
'HZ', # "Detallistas de gasóleo."
'OH', # "Operadores registrados de hidrocarburos."
'HA', # "Titulares de aeronaves que utilizan instalaciones privadas."
'HC', # "Explotaciones industriales y proyectos piloto con derecho a devolución."
'HE', # "Los demás usuarios con derecho a exención."
'HP', # "Inyección en altos hornos."
'HQ', # "Construcción, modificación, pruebas y mantenimiento de aeronaves y embarcaciones."
'HR', # "Producción de electricidad en centrales eléctricas o producción de electricidad o
# cogeneración de electricidad y de calor en centrales combinadas."
'HS', # "Transporte por ferrocarril."
'HW', # "Consumidores de combustibles y carburantes a tipo reducido (artículos 106.4 y 108
# del Reglamento de los Impuestos Especiales)."
'T1', # "Fábricas de labores del tabaco."
'OT', # "Operadores registrados de labores del tabaco."
'T7', # "Depósitos fiscales de labores del tabaco."
'TT', # "Almacenes fiscales de labores del tabaco."
'L1', # "Fábricas de electricidad en régimen ordinario."
'L2', # "Generadores o conjunto de generadores de potencia total superior a 100 kilovatios."
'L0', # "Fábricas de electricidad en régimen especial."
'L3', # "Los demás sujetos pasivos."
'L7', # "Depósitos fiscales de electricidad."
'AF', # "Almacenes fiscales de bebidas alcohólicas y de labores del tabaco."
'DF', # "Depósitos fiscales de bebidas alcohólicas y de labores del tabaco."
'DM', # "Depósitos fiscales de bebidas alcohólicas y de labores del tabaco situados en
# puertos y aeropuertos y que funcionen exclusivamente como establecimientos minoristas."
'DP', # "Depósitos fiscales para el suministro de bebidas alcohólicas y de labores del
# tabaco para consumo o venta a bordo de buques y/o aeronaves."
'OR', # "Operadores registrados de bebidas alcohólicas y de labores del tabaco."
'PF', # "Industrias o usuarios en régimen de perfeccionamiento fiscal."
'RF', # "Representantes fiscales."
'VD', # "Empresas de ventas a distancia."
]
Loading
Loading