Files
octopus/myproject/inventory/utils/document_generator.py
2025-11-04 11:00:05 +03:00

91 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Генератор номеров документов для различных операций в inventory.
"""
from inventory.models import DocumentCounter
def generate_transfer_document_number():
"""
Генерирует уникальный номер документа перемещения.
Формат: MOVE-XXXXXX (6 цифр)
Returns:
str: Сгенерированный номер документа (например, MOVE-000001)
"""
next_number = DocumentCounter.get_next_value('transfer')
return f"MOVE-{next_number:06d}"
def generate_incoming_document_number():
"""
Генерирует номер документа поступления вида 'IN-XXXX-XXXX'.
Алгоритм:
1. Ищет максимальный номер в БД с префиксом 'IN-'
2. Извлекает числовое значение из последней части (IN-XXXX-XXXX)
3. Увеличивает на 1 и форматирует в 'IN-XXXX-XXXX'
Преимущества:
- Работает без SEQUENCE (не требует миграций)
- Гарантирует уникальность через unique constraint в модели
- Простая логика, легко отладить
- Работает с любым тенантом (django-tenants совместимо)
Возвращает:
str: Номер вида 'IN-0000-0001', 'IN-0000-0002', итд
"""
from inventory.models import IncomingBatch
import logging
import os
# Настройка логирования
LOG_FILE = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'logs', 'incoming_sequence.log')
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
file_logger = logging.getLogger('incoming_sequence_file')
if not file_logger.handlers:
handler = logging.FileHandler(LOG_FILE, encoding='utf-8')
formatter = logging.Formatter(
'%(asctime)s | %(levelname)s | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
handler.setFormatter(formatter)
file_logger.addHandler(handler)
file_logger.setLevel(logging.DEBUG)
logger = logging.getLogger('inventory.incoming')
try:
# Найти все номера с префиксом IN-
existing_batches = IncomingBatch.objects.filter(
document_number__startswith='IN-'
).values_list('document_number', flat=True).order_by('document_number')
if not existing_batches:
# Если нет номеров - начинаем с 1
next_num = 1
file_logger.info(f"✓ No existing batches found, starting from 1")
else:
# Берем последний номер, извлекаем цифру и увеличиваем
last_number = existing_batches.last() # 'IN-0000-0005'
# Извлекаем последние 4 цифры
last_digits = int(last_number.split('-')[-1]) # 5
next_num = last_digits + 1
file_logger.info(f"✓ Last number was {last_number}, next: {next_num}")
# Форматируем в IN-XXXX-XXXX
combined_str = f"{next_num:08d}" # Гарантируем 8 цифр
first_part = combined_str[:4] # '0000' или '0001'
second_part = combined_str[4:] # '0001' или '0002'
result = f"IN-{first_part}-{second_part}"
file_logger.info(f"✓ Generated: {result}")
return result
except Exception as e:
file_logger.error(f"✗ Error generating number: {str(e)}")
raise