Files
MES_Core/exempl/shiftflow/models.py
ackFromRedmi e88b861f68
All checks were successful
Deploy MES Core / deploy (push) Successful in 11s
Огромная замена логики
2026-04-06 08:06:37 +03:00

90 lines
5.0 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.

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
# --- СПРАВОЧНИКИ ---
class Company(models.Model):
name = models.CharField("Название компании", max_length=255, unique=True)
def __str__(self): return self.name
class Machine(models.Model):
name = models.CharField("Название станка", max_length=100)
def __str__(self): return self.name
class EmployeeProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
role = models.CharField("Должность", max_length=20, default='operator')
machines = models.ManyToManyField(Machine, blank=True)
def __str__(self): return self.user.username
# --- КОНТУР ЗАКАЗОВ (СДЕЛКИ И ПОТРЕБНОСТИ) ---
class Deal(models.Model):
"""Сделка. Контейнер заказа клиента."""
number = models.CharField("№ Сделки", max_length=100, unique=True)
company = models.ForeignKey(Company, on_delete=models.PROTECT, null=True, blank=True)
status = models.CharField("Статус", max_length=20, default='lead')
def __str__(self): return f"Сделка №{self.number}"
class DealItem(models.Model):
"""
Что заказал клиент (точка входа MRP).
Логика Вьюх:
Менеджер вносит сюда 5 шт "Лавок". На основе этого генерируются MaterialRequirement и ProductionTask.
"""
deal = models.ForeignKey(Deal, related_name='items', on_delete=models.CASCADE)
entity = models.ForeignKey('manufacturing.ProductEntity', on_delete=models.PROTECT, verbose_name="Изделие")
quantity = models.PositiveIntegerField("Заказано, шт")
class MaterialRequirement(models.Model):
"""
Потребность в закупке сырья для Сделки.
Логика Вьюх:
Генерируется автоматически после "взрыва" спецификации (BOM).
Снабженец видит это в своем АРМ и организует приход.
"""
STATUS = [('needed', 'К закупке'), ('ordered', 'В пути'), ('fulfilled', 'Обеспечено')]
deal = models.ForeignKey(Deal, on_delete=models.CASCADE)
material = models.ForeignKey('warehouse.Material', on_delete=models.PROTECT)
required_qty = models.FloatField("Нужно докупить (шт/м/кг)")
status = models.CharField(max_length=20, choices=STATUS, default='needed')
# --- ПРОИЗВОДСТВЕННЫЙ КОНТУР ---
class ProductionTask(models.Model):
"""
Сменное задание (План на производство детали).
Логика: Связывает Сделку и КД (ProductEntity).
"""
deal = models.ForeignKey(Deal, on_delete=models.CASCADE, verbose_name="Сделка")
entity = models.ForeignKey('manufacturing.ProductEntity', on_delete=models.CASCADE, verbose_name="Что делать")
quantity_ordered = models.PositiveIntegerField("План, шт")
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self): return f"{self.entity.name} (Заказ {self.deal.number})"
class CuttingSession(models.Model):
"""
Сессия переработки (Основа для списания/начисления).
Логика Вьюх:
Оператор создает сессию. Указывает, какой StockItem (Лист/Хлыст) он взял со своего участка.
В рамках сессии он закрывает пункты (ShiftItem).
При закрытии сессии Вьюха: 1) списывает used_stock_item, 2) начисляет новые StockItem с готовыми деталями, 3) начисляет ДО.
"""
operator = models.ForeignKey(User, on_delete=models.PROTECT)
machine = models.ForeignKey(Machine, on_delete=models.PROTECT)
used_stock_item = models.ForeignKey('warehouse.StockItem', on_delete=models.PROTECT, verbose_name="Взятый со склада материал")
date = models.DateField("Дата", default=timezone.localdate)
created_at = models.DateTimeField(auto_now_add=True)
is_closed = models.BooleanField("Сессия закрыта", default=False)
class ShiftItem(models.Model):
"""
Конкретный пункт отчета в рамках сессии.
(Замена старой модели Item).
"""
session = models.ForeignKey(CuttingSession, related_name='tasks', on_delete=models.CASCADE)
task = models.ForeignKey(ProductionTask, on_delete=models.PROTECT, verbose_name="Плановое задание")
quantity_fact = models.PositiveIntegerField("Изготовлено (Факт), шт", default=0)
# Флаг для контроля отклонений (если взяли Ст3 вместо Ст10)
material_substitution = models.BooleanField("Замена материала по факту", default=False)