Files
Project_WEB/cleaning/models.py
T
Dmitry 97591a71ea Add initial Django project structure with cleaning app
- Created .gitignore to exclude Python-generated files and virtual environments.
- Added .python-version to specify Python version 3.13.
- Implemented models for Client, Brigade, Service, Order, and CompletedWork.
- Created Django admin configurations for managing models.
- Added management command to seed the database with test data.
- Created initial migrations for the models.
- Developed views and templates for listing and detailing orders, clients, and brigades.
- Set up URL routing for the cleaning app.
- Configured Django settings and WSGI/ASGI entry points.
- Added basic test structure in tests.py.
- Included project metadata in pyproject.toml and uv.lock.
2026-05-16 16:09:37 +03:00

97 lines
3.3 KiB
Python

from django.db import models
class Client(models.Model):
TIME_CHOICES = [
('morning', 'Утро'),
('day', 'День'),
('evening', 'Вечер'),
('any', 'Не важно'),
]
full_name = models.CharField('ФИО', max_length=200)
address = models.CharField('Адрес', max_length=300)
phone = models.CharField('Телефон', max_length=20)
preferred_time = models.CharField(
'Предпочтительное время',
max_length=10,
choices=TIME_CHOICES,
default='any',
)
class Meta:
verbose_name = 'Клиент'
verbose_name_plural = 'Клиенты'
ordering = ['full_name']
def __str__(self):
return self.full_name
class Brigade(models.Model):
name = models.CharField('Название', max_length=100)
supervisor = models.CharField('Руководитель', max_length=200)
employee_count = models.PositiveIntegerField('Количество сотрудников')
specialization = models.CharField('Специализация', max_length=200)
class Meta:
verbose_name = 'Бригада'
verbose_name_plural = 'Бригады'
ordering = ['name']
def __str__(self):
return self.name
class Service(models.Model):
name = models.CharField('Наименование', max_length=200)
price_per_sqm = models.DecimalField('Цена за м2', max_digits=8, decimal_places=2)
duration_per_sqm = models.DecimalField('Продолжительность (мин/м2)', max_digits=6, decimal_places=2)
class Meta:
verbose_name = 'Услуга'
verbose_name_plural = 'Услуги'
ordering = ['name']
def __str__(self):
return self.name
class Order(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE, verbose_name='Клиент', related_name='orders')
brigade = models.ForeignKey(Brigade, on_delete=models.CASCADE, verbose_name='Бригада', related_name='orders')
date = models.DateField('Дата')
start_time = models.TimeField('Время начала')
end_time = models.TimeField('Время окончания')
services = models.ManyToManyField(Service, through='CompletedWork', verbose_name='Услуги')
class Meta:
verbose_name = 'Заказ'
verbose_name_plural = 'Заказы'
ordering = ['date']
def __str__(self):
return f'Заказ №{self.pk}{self.client} ({self.date})'
def total_cost(self):
total = 0
for work in self.completedwork_set.select_related('service').all(): # type: ignore
total += work.area * work.service.price_per_sqm
return total
class CompletedWork(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, verbose_name='Заказ')
service = models.ForeignKey(Service, on_delete=models.CASCADE, verbose_name='Услуга')
area = models.DecimalField('Фактическая площадь (м2)', max_digits=8, decimal_places=2)
class Meta:
verbose_name = 'Выполненная работа'
verbose_name_plural = 'Выполненные работы'
def __str__(self):
return f'{self.service}{self.area} м2'
def cost(self):
return self.area * self.service.price_per_sqm