from django.db import models class RouteStub(models.Model): """Заглушка для будущего модуля техпроцессов.""" name = models.CharField("Маршрут (напр. Лазер-Гибка-Сварка)", max_length=200, unique=True) def __str__(self): return self.name class ProductEntity(models.Model): """ Универсальный паспорт Детали или Сборки. Логика Вьюх: Это "Чертеж". Он не привязан к конкретному заказу (Сделке). planned_material - это то, что задумал конструктор. Оператор по факту может взять другое сырье. """ ENTITY_TYPE = [('product', 'Готовое изделие'), ('assembly', 'Сборочная единица'), ('part', 'Деталь')] name = models.CharField("Наименование", max_length=255) drawing_number = models.CharField("Обозначение/Чертеж", max_length=100, blank=True) entity_type = models.CharField("Тип", max_length=15, choices=ENTITY_TYPE, default='part') planned_material = models.ForeignKey('warehouse.Material', on_delete=models.PROTECT, null=True, blank=True, verbose_name="Заложенный материал") route = models.ForeignKey(RouteStub, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="Маршрут") weight_unit = models.FloatField("Вес 1 шт, кг", default=0.0) surface_area = models.FloatField("Площадь поверхности, м2", default=0.0) dxf_file = models.FileField("Исходник (DXF/IGES)", upload_to="drawings/dxf/%Y/%m/", blank=True, null=True) pdf_main = models.FileField("Доп. чертеж (PDF)", upload_to="drawings/pdf/%Y/%m/", blank=True, null=True) preview = models.ImageField("Превью", upload_to="previews/%Y/%m/", blank=True, null=True) class Meta: verbose_name = "КД (Изделие/Деталь)"; verbose_name_plural = "Конструкторская документация" def __str__(self): return f"{self.drawing_number} {self.name}".strip() class BOM(models.Model): """ Спецификация (Bill of Materials). Состав изделия. Логика Вьюх: При создании заказа на 5 "Лавок", система рекурсивно ищет все BOM, где Лавка = parent, чтобы создать потребность в материалах (child) умноженную на quantity. """ parent = models.ForeignKey(ProductEntity, related_name='components', on_delete=models.CASCADE, verbose_name="Куда входит (Сборка)") child = models.ForeignKey(ProductEntity, related_name='used_in', on_delete=models.CASCADE, verbose_name="Что входит (Деталь)") quantity = models.PositiveIntegerField("Кол-во в сборке", default=1) class Meta: unique_together = ('parent', 'child') verbose_name = "Спецификация (BOM)"; verbose_name_plural = "Спецификации (BOM)"