Пример #1
0
 def post(self, request):
     stylist: Stylist = self.request.user.stylist
     try:
         appointment: Appointment = stylist.appointments.get(
             uuid=request.data['appointment_uuid'])
     except Appointment.DoesNotExist:
         raise ValidationError({
             'non_field_errors': [{
                 'code':
                 ErrorMessages.ERR_INVALID_APPOINTMENT_UUID
             }]
         })
     serializer = AppointmentPreviewRequestSerializer(data=request.data,
                                                      context={
                                                          'stylist':
                                                          stylist,
                                                          'appointment':
                                                          appointment,
                                                          'force_start':
                                                          True
                                                      })
     serializer.is_valid(raise_exception=True)
     client_uuid = serializer.validated_data.pop('client_uuid', None)
     client: Optional[Client] = None
     if client_uuid:
         client = stylist.get_preferred_clients().get(uuid=client_uuid)
     preview_request = AppointmentPreviewRequest(
         **serializer.validated_data)
     response_serializer = AppointmentPreviewResponseSerializer(
         build_appointment_preview_dict(stylist=stylist,
                                        client=client,
                                        preview_request=preview_request))
     return Response(response_serializer.data)
Пример #2
0
 def test_with_existing_client(self):
     stylist: Stylist = G(Stylist)
     service: StylistService = G(StylistService,
                                 stylist=stylist,
                                 regular_price=20)
     client: Client = G(Client)
     preview_request = AppointmentPreviewRequest(
         services=[{
             'service_uuid': service.uuid
         }],
         datetime_start_at=datetime.datetime(2018,
                                             1,
                                             1,
                                             0,
                                             0,
                                             tzinfo=pytz.UTC),
         has_tax_included=False,
         has_card_fee_included=False,
     )
     preview_dict = build_appointment_preview_dict(
         stylist=stylist, client=client, preview_request=preview_request)
     assert (preview_dict.conflicts_with.count() == 0)
     # we can't compare QuerySets, so will just replace the field
     preview_dict = preview_dict._replace(conflicts_with=None)
     assert (preview_dict == AppointmentPreviewResponse(
         grand_total=19,
         total_client_price_before_tax=19,
         total_tax=calculate_tax(Decimal(19), tax_rate=stylist.tax_rate),
         total_card_fee=calculate_card_fee(Decimal(19),
                                           card_fee=stylist.card_fee),
         duration=stylist.service_time_gap,
         conflicts_with=None,
         has_tax_included=False,
         has_card_fee_included=False,
         total_discount_percentage=5,
         total_discount_amount=1,
         services=[
             AppointmentServicePreview(
                 service_name=service.name,
                 service_uuid=service.uuid,
                 client_price=19,
                 regular_price=service.regular_price,
                 duration=service.duration,
                 is_original=True,
                 uuid=None,
             ),
         ],
         stylist=stylist,
         datetime_start_at=datetime.datetime(2018,
                                             1,
                                             1,
                                             0,
                                             0,
                                             tzinfo=pytz.UTC),
         status=AppointmentStatus.NEW,
         tax_percentage=float(stylist.tax_rate) * 100,
         card_fee_percentage=float(stylist.card_fee) * 100,
     ))
Пример #3
0
 def test_bad_appointment_uuid(self):
     stylist = G(Stylist)
     appointment = G(Appointment,
                     datetime_start_at=datetime.datetime(2018,
                                                         1,
                                                         1,
                                                         0,
                                                         0,
                                                         tzinfo=pytz.UTC))
     preview_request = AppointmentPreviewRequest(
         services=[],
         datetime_start_at=datetime.datetime(2018,
                                             1,
                                             1,
                                             0,
                                             0,
                                             tzinfo=pytz.UTC),
         has_tax_included=False,
         has_card_fee_included=False,
         appointment_uuid=appointment.uuid)
     with pytest.raises(Http404):
         build_appointment_preview_dict(stylist=stylist,
                                        client=None,
                                        preview_request=preview_request)
Пример #4
0
 def post(self, request):
     client: Client = self.request.user.client
     serializer = AppointmentPreviewRequestSerializer(
         data=request.data, context=self.get_serializer_context())
     serializer.is_valid(raise_exception=True)
     stylist: Stylist = get_object_or_404(
         Stylist,
         deactivated_at=None,
         uuid=serializer.validated_data.pop('stylist_uuid'))
     preview_request = AppointmentPreviewRequest(
         **serializer.validated_data)
     response_serializer = AppointmentPreviewResponseSerializer(
         build_appointment_preview_dict(stylist=stylist,
                                        client=client,
                                        preview_request=preview_request),
         context=self.get_serializer_context())
     return Response(response_serializer.data)
Пример #5
0
 def test_without_services(self):
     stylist: Stylist = G(Stylist)
     preview_request = AppointmentPreviewRequest(
         services=[],
         datetime_start_at=datetime.datetime(2018,
                                             1,
                                             1,
                                             0,
                                             0,
                                             tzinfo=pytz.UTC),
         has_tax_included=False,
         has_card_fee_included=False,
     )
     preview_dict = build_appointment_preview_dict(
         stylist=stylist, client=None, preview_request=preview_request)
     assert (preview_dict.conflicts_with.count() == 0)
     # we can't compare QuerySets, so will just replace the field
     preview_dict = preview_dict._replace(conflicts_with=None)
     assert (preview_dict == AppointmentPreviewResponse(
         grand_total=0,
         total_client_price_before_tax=0,
         total_tax=0,
         total_card_fee=0,
         duration=stylist.service_time_gap,
         conflicts_with=None,
         has_tax_included=False,
         has_card_fee_included=False,
         services=[],
         stylist=stylist,
         datetime_start_at=datetime.datetime(2018,
                                             1,
                                             1,
                                             0,
                                             0,
                                             tzinfo=pytz.UTC),
         status=AppointmentStatus.NEW,
         total_discount_percentage=0,
         total_discount_amount=0,
         tax_percentage=float(stylist.tax_rate) * 100,
         card_fee_percentage=float(stylist.card_fee) * 100,
     ))
Пример #6
0
 def test_with_existing_appointment_with_new_services(self):
     stylist: Stylist = G(Stylist)
     existing_service: StylistService = G(
         StylistService,
         stylist=stylist,
         regular_price=20,
     )
     service: StylistService = G(StylistService,
                                 stylist=stylist,
                                 regular_price=50)
     service2: StylistService = G(StylistService,
                                  stylist=stylist,
                                  regular_price=50)
     appointment: Appointment = G(Appointment,
                                  stylist=stylist,
                                  datetime_start_at=datetime.datetime(
                                      2018, 1, 1, 0, 0, tzinfo=pytz.UTC),
                                  total_discount_percentage=50,
                                  discount_type=DiscountType.WEEKDAY)
     appointment_service: AppointmentService = G(
         AppointmentService,
         appointment=appointment,
         service_uuid=existing_service.uuid,
         is_original=True,
         service_name=existing_service.name,
         regular_price=20,
         calculated_price=10,
         client_price=10,
         applied_discount=DiscountType.WEEKDAY,
         discount_percentage=50)
     preview_request = AppointmentPreviewRequest(
         services=[
             {
                 'service_uuid': service.uuid
             },
             {
                 'service_uuid': service2.uuid,
                 'client_price': 5
             },
             {
                 'service_uuid': existing_service.uuid
             },
         ],
         datetime_start_at=datetime.datetime(2018,
                                             1,
                                             1,
                                             0,
                                             0,
                                             tzinfo=pytz.UTC),
         has_tax_included=False,
         has_card_fee_included=False,
         appointment_uuid=appointment.uuid)
     preview_dict = build_appointment_preview_dict(
         stylist=stylist, client=None, preview_request=preview_request)
     assert (preview_dict.conflicts_with.count() == 0)
     # we can't compare QuerySets, so will just replace the field
     preview_dict = preview_dict._replace(conflicts_with=None)
     assert (preview_dict == AppointmentPreviewResponse(
         grand_total=38,
         total_client_price_before_tax=38,
         total_tax=calculate_tax(Decimal(38), tax_rate=stylist.tax_rate),
         total_card_fee=calculate_card_fee(Decimal(38),
                                           card_fee=stylist.card_fee),
         duration=stylist.service_time_gap,
         conflicts_with=None,
         has_tax_included=False,
         has_card_fee_included=False,
         services=[
             AppointmentServicePreview(
                 service_name=service.name,
                 service_uuid=service.uuid,
                 client_price=25,
                 regular_price=50,
                 duration=service.duration,
                 is_original=False,
                 uuid=None,
             ),
             AppointmentServicePreview(
                 service_name=service2.name,
                 service_uuid=service2.uuid,
                 client_price=
                 3,  # 50% discount should have been applied + round_half_up to $3
                 regular_price=50,
                 duration=service.duration,
                 is_original=False,
                 uuid=None,
             ),
             AppointmentServicePreview(
                 service_name=existing_service.name,
                 service_uuid=existing_service.uuid,
                 client_price=10,
                 regular_price=20,
                 duration=existing_service.duration,
                 is_original=True,
                 uuid=appointment_service.uuid,
             ),
         ],
         stylist=stylist,
         datetime_start_at=datetime.datetime(2018,
                                             1,
                                             1,
                                             0,
                                             0,
                                             tzinfo=pytz.UTC),
         status=appointment.status,
         total_discount_percentage=50,
         total_discount_amount=82,
         tax_percentage=float(stylist.tax_rate) * 100,
         card_fee_percentage=float(stylist.card_fee) * 100,
     ))