39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Utilidades para los catálogos configurables (sucursales, categorías)."""
|
|
|
|
import re
|
|
import unicodedata
|
|
|
|
|
|
def slugify(text):
|
|
"""'Playa de Rosarito' -> 'playa-de-rosarito' (sin acentos, [a-z0-9-])."""
|
|
text = unicodedata.normalize('NFKD', str(text or ''))
|
|
text = text.encode('ascii', 'ignore').decode('ascii')
|
|
text = re.sub(r'[^a-zA-Z0-9]+', '-', text).strip('-').lower()
|
|
return text
|
|
|
|
|
|
def unique_slug(model, base, exclude_id=None):
|
|
"""Slug único para `model` (sufija -2, -3... si ya existe).
|
|
|
|
Cuenta también los registros inactivos: el `code` es único a nivel base de
|
|
datos y las bajas son lógicas, así que un código usado por algo desactivado
|
|
sigue ocupado.
|
|
"""
|
|
model = model.with_context(active_test=False)
|
|
base = slugify(base) or 'item'
|
|
domain = [('code', '=', base)]
|
|
if exclude_id:
|
|
domain.append(('id', '!=', exclude_id))
|
|
if not model.search_count(domain):
|
|
return base
|
|
n = 2
|
|
while True:
|
|
cand = '%s-%d' % (base, n)
|
|
domain = [('code', '=', cand)]
|
|
if exclude_id:
|
|
domain.append(('id', '!=', exclude_id))
|
|
if not model.search_count(domain):
|
|
return cand
|
|
n += 1
|