add contacts for establishments

This commit is contained in:
Dmitriy Kuzmenko 2019-09-01 12:35:09 +03:00
parent 805bda3267
commit fc4facbf83
13 changed files with 307 additions and 17 deletions

View File

@ -25,10 +25,33 @@ class MetaDataContentInline(GenericTabularInline):
extra = 0 extra = 0
class ContactPhoneInline(admin.TabularInline):
"""Contact phone inline admin."""
model = models.ContactPhone
extra = 0
class ContactEmailInline(admin.TabularInline):
"""Contact email inline admin."""
model = models.ContactEmail
extra = 0
@admin.register(models.Contact)
class ContactAdmin(admin.ModelAdmin):
"""Contact admin."""
inlines = [ContactPhoneInline, ContactEmailInline, ]
class ContactsInline(admin.TabularInline):
model = models.Contact
extra = 0
@admin.register(models.Establishment) @admin.register(models.Establishment)
class EstablishmentAdmin(admin.ModelAdmin): class EstablishmentAdmin(admin.ModelAdmin):
"""Establishment admin.""" """Establishment admin."""
inlines = [AwardInline, MetaDataContentInline] inlines = [AwardInline, MetaDataContentInline, ContactsInline, ]
@admin.register(models.EstablishmentSchedule) @admin.register(models.EstablishmentSchedule)

View File

@ -0,0 +1,77 @@
# Generated by Django 2.2.4 on 2019-09-01 08:31
from django.db import migrations, models
import django.db.models.deletion
import phonenumber_field.modelfields
import utils.models
class Migration(migrations.Migration):
dependencies = [
('location', '0009_auto_20190901_0831'),
('establishment', '0004_auto_20190828_1156'),
]
operations = [
migrations.CreateModel(
name='Contact',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('address', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='location.Address')),
],
options={
'verbose_name': 'contact',
'verbose_name_plural': 'contacts',
},
),
migrations.AlterField(
model_name='establishment',
name='description',
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Description'),
),
migrations.AlterField(
model_name='establishment',
name='name',
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Name'),
),
migrations.AlterField(
model_name='establishmentsubtype',
name='name',
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Description'),
),
migrations.AlterField(
model_name='establishmenttype',
name='name',
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Description'),
),
migrations.CreateModel(
name='ContactPhone',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('phone', phonenumber_field.modelfields.PhoneNumberField(max_length=128)),
('contact', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='phones', to='establishment.Contact')),
],
options={
'verbose_name': 'contact phone',
'verbose_name_plural': 'contact phones',
},
),
migrations.CreateModel(
name='ContactEmail',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.EmailField(max_length=254)),
('contact', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='emails', to='establishment.Contact')),
],
options={
'verbose_name': 'contact email',
'verbose_name_plural': 'contact emails',
},
),
migrations.AddField(
model_name='contact',
name='establishment',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contacts', to='establishment.Establishment'),
),
]

View File

@ -0,0 +1,14 @@
# Generated by Django 2.2.4 on 2019-09-01 08:46
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('establishment', '0005_auto_20190901_0831'),
('establishment', '0005_establishmentschedule'),
]
operations = [
]

View File

@ -1,12 +1,15 @@
"""Establishment models.""" """Establishment models."""
from functools import reduce from django.contrib.contenttypes import fields as generic
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from location.models import Address from location.models import Address
from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField, from utils.models import (
TraslatedFieldsMixin, BaseAttributes) ProjectBaseMixin, ImageMixin, TJSONField,
from django.contrib.contenttypes import fields as generic TraslatedFieldsMixin, BaseAttributes
)
# todo: establishment type&subtypes check # todo: establishment type&subtypes check
@ -14,7 +17,7 @@ class EstablishmentType(ProjectBaseMixin, TraslatedFieldsMixin):
"""Establishment type model.""" """Establishment type model."""
name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'), name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'),
help_text='{"en":"some text"}') help_text='{"en-GB":"some text"}')
use_subtypes = models.BooleanField(_('Use subtypes'), default=True) use_subtypes = models.BooleanField(_('Use subtypes'), default=True)
class Meta: class Meta:
@ -38,7 +41,7 @@ class EstablishmentSubType(ProjectBaseMixin, TraslatedFieldsMixin):
"""Establishment type model.""" """Establishment type model."""
name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'), name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'),
help_text='{"en":"some text"}') help_text='{"en-GB":"some text"}')
establishment_type = models.ForeignKey(EstablishmentType, establishment_type = models.ForeignKey(EstablishmentType,
on_delete=models.CASCADE, on_delete=models.CASCADE,
verbose_name=_('Type')) verbose_name=_('Type'))
@ -75,10 +78,10 @@ class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin):
"""Establishment model.""" """Establishment model."""
name = TJSONField(blank=True, null=True, default=None, name = TJSONField(blank=True, null=True, default=None,
verbose_name=_('Name'), help_text='{"en":"some text"}') verbose_name=_('Name'), help_text='{"en-GB":"some text"}')
description = TJSONField(blank=True, null=True, default=None, description = TJSONField(blank=True, null=True, default=None,
verbose_name=_('Description'), verbose_name=_('Description'),
help_text='{"en":"some text"}') help_text='{"en-GB":"some text"}')
public_mark = models.PositiveIntegerField(blank=True, null=True, public_mark = models.PositiveIntegerField(blank=True, null=True,
default=None, default=None,
verbose_name=_('Public mark'),) verbose_name=_('Public mark'),)
@ -160,3 +163,106 @@ class EstablishmentSchedule(BaseAttributes):
"""Meta class""" """Meta class"""
verbose_name = _('Establishment schedule') verbose_name = _('Establishment schedule')
verbose_name_plural = _('Establishment schedules') verbose_name_plural = _('Establishment schedules')
class Contact(models.Model):
"""Contact model."""
establishment = models.ForeignKey(
Establishment, related_name='contacts', on_delete=models.CASCADE)
address = models.ForeignKey('location.Address', on_delete=models.CASCADE)
class Meta:
verbose_name = _('contact')
verbose_name_plural = _('contacts')
class ContactPhone(models.Model):
"""Contact phone model."""
contact = models.ForeignKey(
Contact, related_name='phones', on_delete=models.CASCADE)
phone = PhoneNumberField()
class Meta:
verbose_name = _('contact phone')
verbose_name_plural = _('contact phones')
def __str__(self):
return f'{self.phone.as_e164}'
class ContactEmail(models.Model):
"""Contact email model."""
contact = models.ForeignKey(
Contact, related_name='emails', on_delete=models.CASCADE)
email = models.EmailField()
class Meta:
verbose_name = _('contact email')
verbose_name_plural = _('contact emails')
def __str__(self):
return f'{self.email}'
#
# class Wine(TraslatedFieldsMixin, models.Model):
# """Wine model."""
# establishment = models.ForeignKey(
# 'establishment.Establishment', verbose_name=_('establishment'),
# on_delete=models.CASCADE)
# bottles = models.IntegerField(_('bottles'))
# price_min = models.DecimalField(
# _('price min'), max_digits=14, decimal_places=2)
# price_max = models.DecimalField(
# _('price max'), max_digits=14, decimal_places=2)
# by_glass = models.BooleanField(_('by glass'))
# price_glass_min = models.DecimalField(
# _('price min'), max_digits=14, decimal_places=2)
# price_glass_max = models.DecimalField(
# _('price max'), max_digits=14, decimal_places=2)
#
#
# class Plate(TraslatedFieldsMixin, models.Model):
# """Plate model."""
#
# STARTER = 0
# MAIN = 1
# COURSE = 2
# DESSERT = 3
#
# PLATE_TYPE_CHOICES = (
# (STARTER, _('starter')),
# (MAIN, _('main')),
# (COURSE, _('course')),
# (DESSERT, _('dessert')),
# )
# name = models.CharField(_('name'), max_length=255)
# plate_type = models.PositiveSmallIntegerField(_('plate_type'), choices=PLATE_TYPE_CHOICES)
# description = TJSONField(
# blank=True, null=True, default=None, verbose_name=_('description'),
# help_text='{"en-GB":"some text"}')
# price = models.DecimalField(
# _('price'), max_digits=14, decimal_places=2)
# is_signature_plate = models.BooleanField(_('is signature plate'))
# currency = models.ForeignKey(
# 'main.Currency', verbose_name=_('currency'), on_delete=models.CASCADE)
#
# menu = models.ManyToManyField(to='Plate', verbose_name=_(''), through='establishment.Menu')
#
# class Meta:
# verbose_name = _('plate')
# verbose_name_plural = _('plates')
#
# def __str__(self):
# return f'plate_id:{self.id}'
#
#
# class Menu(TraslatedFieldsMixin, BaseAttributes):
# """Menu model."""
# establishment = models.ForeignKey(
# 'establishment.Establishment', verbose_name=_('establishment'),
# on_delete=models.CASCADE)
# plate = models.ForeignKey(Plate, verbose_name=_('menu'), on_delete=models.CASCADE)
#
# class Meta:
# verbose_name = _('menu')
# verbose_name_plural = _('menu')

View File

@ -6,6 +6,39 @@ from main.serializers import MetaDataContentSerializer, AwardSerializer
from timetable.models import Timetable from timetable.models import Timetable
class ContactPhonesSerializer(serializers.ModelSerializer):
"""Contact phone serializer"""
class Meta:
model = models.ContactPhone
fields = [
'phone'
]
class ContactEmailsSerializer(serializers.ModelSerializer):
"""Contact email serializer"""
class Meta:
model = models.ContactEmail
fields = [
'email'
]
class ContactSerializer(serializers.ModelSerializer):
"""Contact serializer."""
address = AddressSerializer(read_only=True)
phones = ContactPhonesSerializer(read_only=True, many=True,)
emails = ContactEmailsSerializer(read_only=True, many=True,)
class Meta:
model = models.Contact
fields = [
'address',
'phones',
'emails'
]
class EstablishmentTypeSerializer(serializers.ModelSerializer): class EstablishmentTypeSerializer(serializers.ModelSerializer):
"""Serializer for EstablishmentType model.""" """Serializer for EstablishmentType model."""
@ -59,6 +92,7 @@ class EstablishmentSerializer(serializers.ModelSerializer):
schedule = EstablishmentScheduleSerializer(source='schedule.schedule', schedule = EstablishmentScheduleSerializer(source='schedule.schedule',
many=True, many=True,
allow_null=True) allow_null=True)
contacts = ContactSerializer(read_only=True, many=True, )
class Meta: class Meta:
"""Meta class.""" """Meta class."""
@ -79,4 +113,7 @@ class EstablishmentSerializer(serializers.ModelSerializer):
'tags', 'tags',
'awards', 'awards',
'schedule', 'schedule',
'contacts'
) )

View File

@ -30,6 +30,6 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='country', model_name='country',
name='name', name='name',
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=None, help_text='{"en":"some text"}', null=True, verbose_name='Text'), field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Text'),
), ),
] ]

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.4 on 2019-09-01 08:31
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('location', '0008_auto_20190827_1302'),
]
operations = [
migrations.AlterField(
model_name='country',
name='name',
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Name'),
),
]

View File

@ -17,7 +17,7 @@ class Country(SVGImageMixin, ProjectBaseMixin):
"""Country model.""" """Country model."""
name = JSONField(null=True, blank=True, default=None, name = JSONField(null=True, blank=True, default=None,
verbose_name=_('Name'), help_text='{"en":"some text"}') verbose_name=_('Name'), help_text='{"en-GB":"some text"}')
code = models.CharField(max_length=255, unique=True, verbose_name=_('Code')) code = models.CharField(max_length=255, unique=True, verbose_name=_('Code'))
low_price = models.IntegerField(default=25, verbose_name=_('Low price')) low_price = models.IntegerField(default=25, verbose_name=_('Low price'))
high_price = models.IntegerField(default=50, verbose_name=_('High price')) high_price = models.IntegerField(default=50, verbose_name=_('High price'))

View File

@ -190,7 +190,7 @@ class Award(TraslatedFieldsMixin, models.Model):
award_type = models.ForeignKey('main.AwardType', on_delete=models.CASCADE) award_type = models.ForeignKey('main.AwardType', on_delete=models.CASCADE)
title = TJSONField( title = TJSONField(
_('title'), null=True, blank=True, _('title'), null=True, blank=True,
default=None, help_text='{"en":"some text"}') default=None, help_text='{"en-GB":"some text"}')
vintage_year = models.CharField(_('vintage year'), max_length=255, default='') vintage_year = models.CharField(_('vintage year'), max_length=255, default='')
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
@ -228,7 +228,7 @@ class MetaData(TraslatedFieldsMixin, models.Model):
"""MetaData model.""" """MetaData model."""
label = TJSONField( label = TJSONField(
_('label'), null=True, blank=True, _('label'), null=True, blank=True,
default=None, help_text='{"en":"some text"}') default=None, help_text='{"en-GB":"some text"}')
category = models.ForeignKey( category = models.ForeignKey(
MetaDataCategory, verbose_name=_('category'), on_delete=models.CASCADE) MetaDataCategory, verbose_name=_('category'), on_delete=models.CASCADE)
@ -250,3 +250,15 @@ class MetaDataContent(models.Model):
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id') content_object = generic.GenericForeignKey('content_type', 'object_id')
metadata = models.ForeignKey(MetaData, on_delete=models.CASCADE) metadata = models.ForeignKey(MetaData, on_delete=models.CASCADE)
class Currency(models.Model):
"""Currency model."""
name = models.CharField(_('name'), max_length=50)
class Meta:
verbose_name = _('currency')
verbose_name_plural = _('currencies')
def __str__(self):
return f'{self.name}'

View File

@ -43,14 +43,14 @@ class News(BaseAttributes, TraslatedFieldsMixin):
title = TJSONField( title = TJSONField(
_('title'), null=True, blank=True, _('title'), null=True, blank=True,
default=None, help_text='{"en":"some text"}') default=None, help_text='{"en-GB":"some text"}')
subtitle = TJSONField( subtitle = TJSONField(
_('subtitle'), null=True, blank=True, _('subtitle'), null=True, blank=True,
default=None, help_text='{"en":"some text"}' default=None, help_text='{"en-GB":"some text"}'
) )
description = TJSONField( description = TJSONField(
_('description'), null=True, blank=True, _('description'), null=True, blank=True,
default=None, help_text='{"en":"some text"}' default=None, help_text='{"en-GB":"some text"}'
) )
start = models.DateTimeField(_('start')) start = models.DateTimeField(_('start'))
end = models.DateTimeField(_('end')) end = models.DateTimeField(_('end'))

View File

@ -49,7 +49,7 @@ class SiteInterfaceDictionary(ProjectBaseMixin):
verbose_name=_('Page')) verbose_name=_('Page'))
keywords = models.CharField(max_length=255, verbose_name='Keywords') keywords = models.CharField(max_length=255, verbose_name='Keywords')
text = JSONField(_('Text'), null=True, blank=True, text = JSONField(_('Text'), null=True, blank=True,
default=None, help_text='{"en":"some text"}') default=None, help_text='{"en-GB":"some text"}')
objects = SiteInterfaceDictionaryManager() objects = SiteInterfaceDictionaryManager()

View File

@ -82,6 +82,7 @@ EXTERNAL_APPS = [
'django_extensions', 'django_extensions',
'rest_framework_simplejwt.token_blacklist', 'rest_framework_simplejwt.token_blacklist',
'solo', 'solo',
'phonenumber_field',
] ]

View File

@ -17,6 +17,7 @@ djangorestframework-xml
celery celery
amqp>=2.4.0 amqp>=2.4.0
geoip2==2.9.0 geoip2==2.9.0
django-phonenumber-field[phonenumbers]==2.1.0
# auth socials # auth socials
djangorestframework-oauth djangorestframework-oauth