diff --git a/apps/establishment/migrations/0064_auto_20191119_1546.py b/apps/establishment/migrations/0064_auto_20191119_1546.py new file mode 100644 index 00000000..80d4135b --- /dev/null +++ b/apps/establishment/migrations/0064_auto_20191119_1546.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.7 on 2019-11-19 15:46 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('establishment', '0063_company'), + ] + + operations = [ + migrations.AlterField( + model_name='establishmentnote', + name='establishment', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='notes', to='establishment.Establishment', verbose_name='establishment'), + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index e9f230f1..3aee6c31 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -413,13 +413,15 @@ class Establishment(GalleryModelMixin, ProjectBaseMixin, URLImageMixin, Translat """Overridden delete method""" # Delete all related companies self.companies.all().delete() + # Delete all related notes + self.notes.all().delete() return super().delete(using, keep_parents) @property def visible_tags(self): return super().visible_tags\ - .exclude(category__index_name__in=['guide', 'collection', 'purchased_item', - 'business_tag', 'business_tags_de'])\ + .exclude(category__index_name__in=['guide', 'collection', 'purchased_item', + 'business_tag', 'business_tags_de'])\ # todo: recalculate toque_number def recalculate_toque_number(self): @@ -578,7 +580,7 @@ class EstablishmentNote(ProjectBaseMixin): old_id = models.PositiveIntegerField(null=True, blank=True) text = models.TextField(verbose_name=_('text')) establishment = models.ForeignKey(Establishment, on_delete=models.PROTECT, - related_name='establishment_notes', + related_name='notes', verbose_name=_('establishment')) user = models.ForeignKey('account.User', on_delete=models.PROTECT, null=True, diff --git a/apps/establishment/serializers/back.py b/apps/establishment/serializers/back.py index 3b80da72..a78bce07 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -8,6 +8,7 @@ from utils.decorators import with_base_attributes from utils.serializers import TimeZoneChoiceField from gallery.models import Image from django.utils.translation import gettext_lazy as _ +from account.serializers.common import UserShortSerializer class EstablishmentListCreateSerializer(model_serializers.EstablishmentBaseSerializer): @@ -224,3 +225,55 @@ class EstablishmentCompanyListCreateSerializer(model_serializers.CompanyBaseSeri """Overridden create method.""" validated_data['establishment'] = self.context.get('view').get_object() return super().create(validated_data) + + +class EstablishmentNoteBaseSerializer(serializers.ModelSerializer): + """Serializer for model EstablishmentNote.""" + + user_detail = UserShortSerializer(read_only=True, source='user') + + class Meta: + """Meta class.""" + model = models.EstablishmentNote + fields = [ + 'id', + 'created', + 'modified', + 'text', + 'user', + 'user_detail', + 'establishment', + ] + extra_kwargs = { + 'created': {'read_only': True}, + 'modified': {'read_only': True}, + 'establishment': {'required': False, 'write_only': True}, + 'user': {'required': False, 'write_only': True}, + } + + @property + def serializer_view(self): + """Return view instance.""" + return self.context.get('view') + + +class EstablishmentNoteListCreateSerializer(EstablishmentNoteBaseSerializer): + """Serializer for List|Create action for model EstablishmentNote.""" + + def create(self, validated_data): + """Overridden create method.""" + validated_data['user'] = self.user + validated_data['establishment'] = self.establishment + return super().create(validated_data) + + @property + def user(self): + """Return user instance from view.""" + if self.serializer_view: + return self.serializer_view.request.user + + @property + def establishment(self): + """Return establishment instance from view.""" + if self.serializer_view: + return self.serializer_view.get_object() diff --git a/apps/establishment/urls/back.py b/apps/establishment/urls/back.py index 47ac2357..f06e2187 100644 --- a/apps/establishment/urls/back.py +++ b/apps/establishment/urls/back.py @@ -22,6 +22,10 @@ urlpatterns = [ name='company-list-create'), path('/companies//', views.EstablishmentCompanyRUDView.as_view(), name='company-rud'), + path('/notes/', views.EstablishmentNoteListCreateView.as_view(), + name='note-list-create'), + path('/notes//', views.EstablishmentNoteRUDView.as_view(), + name='note-rud'), path('menus/', views.MenuListCreateView.as_view(), name='menu-list'), path('menus//', views.MenuRUDView.as_view(), name='menu-rud'), path('plates/', views.PlateListCreateView.as_view(), name='plates'), diff --git a/apps/establishment/views/back.py b/apps/establishment/views/back.py index 24b47720..ad38e806 100644 --- a/apps/establishment/views/back.py +++ b/apps/establishment/views/back.py @@ -191,7 +191,7 @@ class EstablishmentSubtypeRUDView(generics.RetrieveUpdateDestroyAPIView): class EstablishmentGalleryCreateDestroyView(EstablishmentMixinViews, CreateDestroyGalleryViewMixin): - """Resource for a create|destroy gallery for product for back-office users.""" + """Resource for a create|destroy gallery for establishment for back-office users.""" serializer_class = serializers.EstablishmentBackOfficeGallerySerializer def get_object(self): @@ -271,3 +271,45 @@ class EstablishmentCompanyRUDView(EstablishmentMixinViews, return company + +class EstablishmentNoteListCreateView(EstablishmentMixinViews, + generics.ListCreateAPIView): + """Retrieve|Update|Destroy establishment note view.""" + + serializer_class = serializers.EstablishmentNoteListCreateSerializer + + def get_object(self): + """Returns the object the view is displaying.""" + establishment_qs = models.Establishment.objects.all() + filtered_establishment_qs = self.filter_queryset(establishment_qs) + + establishment = get_object_or_404(filtered_establishment_qs, pk=self.kwargs['pk']) + + # May raise a permission denied + self.check_object_permissions(self.request, establishment) + + return establishment + + def get_queryset(self): + """Overridden get_queryset method.""" + return self.get_object().notes.all() + + +class EstablishmentNoteRUDView(EstablishmentMixinViews, + generics.RetrieveUpdateDestroyAPIView): + """Create|Retrieve|Update|Destroy establishment note view.""" + + serializer_class = serializers.EstablishmentNoteBaseSerializer + + def get_object(self): + """Returns the object the view is displaying.""" + establishment_qs = models.Establishment.objects.all() + filtered_establishment_qs = self.filter_queryset(establishment_qs) + + establishment = get_object_or_404(filtered_establishment_qs, pk=self.kwargs['pk']) + note = get_object_or_404(establishment.notes.all(), pk=self.kwargs['note_pk']) + + # May raise a permission denied + self.check_object_permissions(self.request, note) + + return note diff --git a/apps/product/migrations/0017_auto_20191119_1546.py b/apps/product/migrations/0017_auto_20191119_1546.py new file mode 100644 index 00000000..38eff085 --- /dev/null +++ b/apps/product/migrations/0017_auto_20191119_1546.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.7 on 2019-11-19 15:46 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('product', '0016_product_average_price'), + ] + + operations = [ + migrations.AlterField( + model_name='productnote', + name='product', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='notes', to='product.Product', verbose_name='product'), + ), + ]