diff --git a/api/api_methods.py b/api/api_methods.py index d51f7eb..ad98d46 100755 --- a/api/api_methods.py +++ b/api/api_methods.py @@ -521,9 +521,6 @@ class ApiOrder: ApiParamEnum(name='purchase_of_material', choices=Order.PURCHASE_OF_MATERIAL_CHOICES, required=False, default=Order.CHOICE_UNDEFINED, description="Закуп материала: {choices}"), - ApiParamEnum(name='type_of_executor', choices=Order.TYPE_OF_EXECUTOR_CHOICES, - required=False, default=Order.CHOICE_UNDEFINED, - description="Тип исполнителя: {choices}"), # дальше отдельные флаги ApiParamBoolean(name="is_with_warranty", required=False, default=True, diff --git a/api/models.py b/api/models.py index 160cf66..a375f17 100755 --- a/api/models.py +++ b/api/models.py @@ -1,7 +1,7 @@ from datetime import datetime from asgiref.sync import sync_to_async -from django.core.validators import RegexValidator +from django.core.validators import * from django.db import models from hashlib import sha512, sha256 @@ -232,36 +232,28 @@ class AccessToken(models.Model): class Order(models.Model): + owner = models.ForeignKey(Account, on_delete=models.CASCADE, related_name="owner", verbose_name="Владелец") + # основные поля: название и описание - name = models.CharField(max_length=200, verbose_name="Название заказа") - description = models.TextField(blank=True, verbose_name="Описание") - - # площадь в квадратных метрах - square = models.DecimalField(max_digits=7, decimal_places=2, blank=False, verbose_name="Площадь в м²") - - work_time = models.CharField(max_length=100, blank=True, verbose_name="Рабочее время") - - # дальше вид дома, тип ремонта, тип квартиры, требуется дизайн проект, закуп материала, тип исполнителя + name = models.CharField(max_length=200, verbose_name="Название объявления") + address_city = models.CharField(max_length=CITIES_FIELD_SIZE, choices=CITIES_CHOICES, + blank=False, verbose_name="Город") + address_text = models.CharField(max_length=70, blank=True, verbose_name="Улица, дом") CHOICE_UNDEFINED = '' - # тип ремонта - TYPE_OF_RENOVATION_OVERHAUL = 'overhaul' - TYPE_OF_RENOVATION_PARTIAL = 'partial' - TYPE_OF_RENOVATION_REDECOR = 'redecor' - TYPE_OF_RENOVATION_PREMIUM = 'premium' - TYPE_OF_RENOVATION_DESIGN = 'design' + # Раздел "Параметры объекта" - TYPE_OF_RENOVATION_CHOICES = [ - (CHOICE_UNDEFINED, 'Не определено'), - (TYPE_OF_RENOVATION_OVERHAUL, 'Капитальный'), - (TYPE_OF_RENOVATION_PARTIAL, 'Частичный'), - (TYPE_OF_RENOVATION_REDECOR, 'Косметический'), - (TYPE_OF_RENOVATION_PREMIUM, 'Премиальный'), - (TYPE_OF_RENOVATION_DESIGN, 'Дизайнерский'), + # тип квартиры + TYPE_OF_APARTMENT_PRIMARY = 'primary' + TYPE_OF_APARTMENT_SECONDARY = 'secondary' + + TYPE_OF_APARTMENT_CHOICES = [ + (TYPE_OF_APARTMENT_PRIMARY, 'Первичка'), + (TYPE_OF_APARTMENT_SECONDARY, 'Вторичка') ] - type_of_renovation = models.CharField(max_length=10, choices=TYPE_OF_RENOVATION_CHOICES, default=CHOICE_UNDEFINED, - blank=True, verbose_name="Тип ремонта") + type_of_apartment = models.CharField(max_length=10, choices=TYPE_OF_APARTMENT_CHOICES, blank=True, + default=CHOICE_UNDEFINED, verbose_name="Тип квартиры") # тип дома TYPE_OF_HOUSE_BLOCK = 'block' @@ -278,16 +270,72 @@ class Order(models.Model): type_of_house = models.CharField(max_length=10, choices=TYPE_OF_HOUSE_CHOICES, blank=True, default=CHOICE_UNDEFINED, verbose_name="Тип дома") - # тип квартиры - TYPE_OF_ROOM_PRIMARY = 'primary' - TYPE_OF_ROOM_SECONDARY = 'secondary' + TYPE_OF_ROOM_APARTMENT = "apartment" + TYPE_OF_ROOM_PRIVATE_HOUSE = "private_house" + TYPE_OF_ROOM_PENTHOUSE = "penthouse" + TYPE_OF_ROOM_COUNTRY_HOUSE = "country_house" + TYPE_OF_ROOM_APARTMENTS = "apartments" + TYPE_OF_ROOM_KITCHEN = "kitchen" + TYPE_OF_ROOM_BATHROOM = "bathroom" + TYPE_OF_ROOM_NURSERY = "nursery" TYPE_OF_ROOM_CHOICES = [ - (TYPE_OF_ROOM_PRIMARY, 'Первичка'), - (TYPE_OF_ROOM_SECONDARY, 'Вторичка') + (TYPE_OF_ROOM_APARTMENT, "квартира"), + (TYPE_OF_ROOM_PRIVATE_HOUSE, "частный дом"), + (TYPE_OF_ROOM_PENTHOUSE, "пентхаус"), + (TYPE_OF_ROOM_COUNTRY_HOUSE, "дачный дом"), + (TYPE_OF_ROOM_APARTMENTS, "апартаменты"), + (TYPE_OF_ROOM_KITCHEN, "кухня"), + (TYPE_OF_ROOM_BATHROOM, "ванная комната"), + (TYPE_OF_ROOM_NURSERY, "детская") ] - type_of_room = models.CharField(max_length=10, choices=TYPE_OF_ROOM_CHOICES, blank=True, default=CHOICE_UNDEFINED, - verbose_name="Тип квартиры") + type_of_room = models.CharField(max_length=16, choices=TYPE_OF_ROOM_CHOICES, blank=True, + default=CHOICE_UNDEFINED, verbose_name="Тип помещения") + + number_of_rooms = models.SmallIntegerField(verbose_name='Количество комнат, -1 = студия', validators=[ + MinValueValidator(-1), + MaxValueValidator(100) + ]) + + is_balcony = models.BooleanField(default=False, verbose_name="Балкон") + is_loggia = models.BooleanField(default=False, verbose_name="Лоджия") + + state_of_room = models.CharField(max_length=40, blank=True, default=CHOICE_UNDEFINED, + verbose_name="Состояние помещения") + + # площадь в квадратных метрах + square = models.DecimalField(max_digits=7, decimal_places=2, blank=False, verbose_name="Площадь в м²") + + # высота потолков + ceiling_height = models.DecimalField(max_digits=2, decimal_places=2, blank=False, + verbose_name="Высота потолков в м") + + # Раздел "Ремонт" + + # тип ремонта + TYPE_OF_RENOVATION_OVERHAUL = 'overhaul' + TYPE_OF_RENOVATION_REDECOR = 'redecor' + TYPE_OF_RENOVATION_PARTIAL = 'partial' + + TYPE_OF_RENOVATION_CHOICES = [ + (CHOICE_UNDEFINED, 'Не определено'), + (TYPE_OF_RENOVATION_OVERHAUL, 'Капитальный'), + (TYPE_OF_RENOVATION_REDECOR, 'Косметический'), + (TYPE_OF_RENOVATION_PARTIAL, 'Частичный'), + ] + type_of_renovation = models.CharField(max_length=10, choices=TYPE_OF_RENOVATION_CHOICES, default=CHOICE_UNDEFINED, + blank=True, verbose_name="Тип ремонта") + + is_redevelopment = models.BooleanField(default=False, verbose_name="Перепланировка") + is_leveling_floors = models.BooleanField(default=False, verbose_name="Выравнивать полы") + is_heated_floor = models.BooleanField(default=False, verbose_name="Теплый пол") + is_leveling_walls = models.BooleanField(default=False, verbose_name="Выравнивать стены") + + type_of_ceiling = models.CharField(max_length=40, blank=True, default=CHOICE_UNDEFINED, + verbose_name="Потолок") + + is_wiring_replace = models.BooleanField(default=False, verbose_name="Замена проводки") + is_require_design = models.BooleanField(default=False, verbose_name="Требуется дизайн проект") # закуп материала PURCHASE_OF_MATERIAL_EXECUTOR = 'executor' @@ -300,42 +348,29 @@ class Order(models.Model): purchase_of_material = models.CharField(max_length=10, choices=PURCHASE_OF_MATERIAL_CHOICES, blank=True, default=CHOICE_UNDEFINED, verbose_name="Закуп материала") - # тип исполнителя - TYPE_OF_EXECUTOR_INDIVIDUAL = 'individual' - TYPE_OF_EXECUTOR_COMPANY = 'company' - - TYPE_OF_EXECUTOR_CHOICES = [ - (TYPE_OF_EXECUTOR_INDIVIDUAL, 'Самозанятый/бригада'), - (TYPE_OF_EXECUTOR_COMPANY, 'Компания') - ] - type_of_executor = models.CharField(max_length=10, choices=TYPE_OF_EXECUTOR_CHOICES, - blank=True, default=CHOICE_UNDEFINED, verbose_name="Тип исполнителя") - # дальше отдельные параметры - is_with_warranty = models.BooleanField(default=True, verbose_name="С гарантией") is_with_contract = models.BooleanField(default=False, verbose_name="Работа по договору") - is_require_design = models.BooleanField(default=False, verbose_name="Требуется дизайн проект") + is_with_warranty = models.BooleanField(default=True, verbose_name="С гарантией") is_with_trade = models.BooleanField(default=False, verbose_name="Возможен торг") - is_with_cleaning = models.BooleanField(default=False, verbose_name="С уборкой") is_with_garbage_removal = models.BooleanField(default=False, verbose_name="С вывозом мусора") - # примерная цена - approximate_price = models.DecimalField(max_digits=12, decimal_places=2, blank=False, verbose_name="Цена") - date_start = models.DateField(null=True, blank=True, default=None, verbose_name="Дата начала") date_end = models.DateField(null=True, blank=True, default=None, verbose_name="Дата окончания") - address_city = models.CharField(max_length=CITIES_FIELD_SIZE, choices=CITIES_CHOICES, - blank=False, verbose_name="Город") - address_text = models.CharField(max_length=70, blank=True, verbose_name="Улица, дом") + # примерная цена + approximate_price = models.DecimalField(max_digits=12, decimal_places=2, blank=False, verbose_name="Цена") - owner = models.ForeignKey(Account, on_delete=models.CASCADE, related_name="owner", verbose_name="Владелец") + description = models.TextField(blank=True, verbose_name="Описание") + + # TODO сделать ссылку на видео email = models.EmailField(null=True, blank=True, verbose_name="Email") phone = models.CharField(null=True, blank=True, max_length=16, verbose_name="Телефон", validators=[ RegexValidator(regex="^\\+7[0-9]{10}$") ]) + # Внутренние поля + create_time = models.DateTimeField(default=datetime.now, editable=False, verbose_name="Время создания") moderated = models.BooleanField(default=True, verbose_name="Модерирован") @@ -359,7 +394,6 @@ class Order(models.Model): else: return q[0] - # def _upload_image_filename(instance, filename): # name, ext = os.path.splitext(filename) # fn = sha256((str(datetime.now()) + name).encode('utf-8')).hexdigest() + ext