def test_post_cart_not_available(self): """It should create a new sale and ignore articles which are not available""" # Create contact for the user profile = create_profile_contact(self.user) contact = profile.contact store_item1 = mommy.make(models.StoreItem, stock_count=Decimal('10')) store_item2 = mommy.make(models.StoreItem, stock_count=Decimal('0.5'), available=False) delivery_point = mommy.make(models.DeliveryPoint) data = { 'items': [ {'id': store_item1.id, 'quantity': 2}, {'id': store_item2.id, 'quantity': 1}, ], 'delivery_point': delivery_point.id, 'purchase_datetime': datetime(2015, 7, 23, 12, 0) } url = reverse('store_post_cart') response = self.client.post(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['ok'], True) self.assertEqual(len(response.data['warnings']), 1) self.assertEqual(response.data['deliveryDate'], data['purchase_datetime']) self.assertEqual(response.data['deliveryPlace'], delivery_point.name) action_type = ActionType.objects.get(name=get_cart_type_name()) action_queryset = Action.objects.filter(type=action_type) self.assertEqual(action_queryset.count(), 1) action = action_queryset[0] self.assertEqual(list(action.contacts.all()), [contact]) self.assertEqual(action.subject, '') self.assertEqual(action.detail, '') self.assertEqual(action.planned_date, data['purchase_datetime']) self.assertEqual(action.sale.saleitem_set.count(), 1) self.assertEqual(action.sale.saleitem_set.all()[0].item, store_item1) self.assertEqual(action.sale.saleitem_set.all()[0].text, store_item1.name) self.assertEqual(action.sale.saleitem_set.all()[0].unit_price(), store_item1.pre_tax_price) self.assertEqual(action.sale.saleitem_set.all()[0].vat_rate, store_item1.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[0].quantity, 2) self.assertEqual(len(mail.outbox), 2) self.assertEqual(mail.outbox[0].to, [profile.contact.email]) self.assertEqual(mail.outbox[1].to, [settings.BALAFON_NOTIFICATION_EMAIL]) store_item1 = models.StoreItem.objects.get(id=store_item1.id) self.assertEqual(store_item1.stock_count, Decimal("8")) store_item2 = models.StoreItem.objects.get(id=store_item2.id) self.assertEqual(store_item2.stock_count, Decimal("0.5"))
def test_post_cart_notes_several_lines(self): """It should create a new sale and action""" # Create contact for the user profile = create_profile_contact(self.user) contact = profile.contact store_item1 = mommy.make(models.StoreItem) store_item2 = mommy.make(models.StoreItem) delivery_point = mommy.make(models.DeliveryPoint) data = { 'items': [ {'id': store_item1.id, 'quantity': 2}, {'id': store_item2.id, 'quantity': 1}, ], 'delivery_point': delivery_point.id, 'notes': 'a\nB\nc', 'purchase_datetime': datetime(2015, 7, 23, 12, 0) } url = reverse('store_post_cart') response = self.client.post(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['ok'], True) self.assertEqual(len(response.data['warnings']), 0) self.assertEqual(response.data['deliveryDate'], data['purchase_datetime']) self.assertEqual(response.data['deliveryPlace'], delivery_point.name) action_type = ActionType.objects.get(name=get_cart_type_name()) action_queryset = Action.objects.filter(type=action_type) self.assertEqual(action_queryset.count(), 1) action = action_queryset[0] self.assertEqual(list(action.contacts.all()), [contact]) self.assertEqual(action.subject, _(u'Notes')) self.assertEqual(action.detail, 'a\nB\nc') self.assertEqual(action.planned_date, data['purchase_datetime']) self.assertEqual(action.sale.saleitem_set.count(), 2) self.assertEqual(action.sale.saleitem_set.all()[0].item, store_item1) self.assertEqual(action.sale.saleitem_set.all()[0].text, store_item1.name) self.assertEqual(action.sale.saleitem_set.all()[0].unit_price(), store_item1.pre_tax_price) self.assertEqual(action.sale.saleitem_set.all()[0].vat_rate, store_item1.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[0].quantity, 2) self.assertEqual(action.sale.saleitem_set.all()[1].item, store_item2) self.assertEqual(action.sale.saleitem_set.all()[1].text, store_item2.name) self.assertEqual(action.sale.saleitem_set.all()[1].unit_price(), store_item2.pre_tax_price) self.assertEqual(action.sale.saleitem_set.all()[1].vat_rate, store_item2.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[1].quantity, 1) self.assertEqual(len(mail.outbox), 2)
def test_post_cart_empty(self): """It should create a new sale and ignore articles which are not available""" # Create contact for the user profile = create_profile_contact(self.user) contact = profile.contact store_item1 = mommy.make(models.StoreItem, stock_count=Decimal('10'), available=False) store_item2 = mommy.make(models.StoreItem, stock_count=Decimal('0.5'), available=False) delivery_point = mommy.make(models.DeliveryPoint) data = { 'items': [ {'id': store_item1.id, 'quantity': 2}, {'id': store_item2.id, 'quantity': 1}, ], 'delivery_point': delivery_point.id, 'purchase_datetime': datetime(2015, 7, 23, 12, 0) } url = reverse('store_post_cart') response = self.client.post(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['ok'], False) self.assertEqual(len(response.data['warnings']), 2) action_type = ActionType.objects.get(name=get_cart_type_name()) action_queryset = Action.objects.filter(type=action_type) self.assertEqual(action_queryset.count(), 0) self.assertEqual(len(mail.outbox), 0) store_item1 = models.StoreItem.objects.get(id=store_item1.id) self.assertEqual(store_item1.stock_count, Decimal("10")) store_item2 = models.StoreItem.objects.get(id=store_item2.id) self.assertEqual(store_item2.stock_count, Decimal("0.5"))
def test_cart_with_discount(self): """The cart should take account discount into account""" # Create contact for the user profile = create_profile_contact(self.user) contact = profile.contact discount = mommy.make( models.Discount, active=True, name="10% si + de 5", rate=Decimal("10"), quantity=Decimal("5") ) price_class = mommy.make(models.PriceClass, name="Vrac") price_class.discounts.add(discount) price_class.save() store_item1 = mommy.make(models.StoreItem, pre_tax_price=Decimal('10'), price_class=price_class) store_item2 = mommy.make(models.StoreItem, pre_tax_price=Decimal('1'), price_class=price_class) store_item3 = mommy.make(models.StoreItem, pre_tax_price=Decimal('2'), price_class=None) delivery_point = mommy.make(models.DeliveryPoint) data = { 'items': [ {'id': store_item1.id, 'quantity': 5}, {'id': store_item2.id, 'quantity': 2}, {'id': store_item3.id, 'quantity': 5}, ], 'delivery_point': delivery_point.id, 'purchase_datetime': datetime(2015, 7, 23, 12, 0) } url = reverse('store_post_cart') response = self.client.post(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['ok'], True) self.assertEqual(len(response.data['warnings']), 0) action_type = ActionType.objects.get(name=get_cart_type_name()) action_queryset = Action.objects.filter(type=action_type) self.assertEqual(action_queryset.count(), 1) action = action_queryset[0] self.assertEqual(list(action.contacts.all()), [contact]) self.assertEqual(action.subject, '') self.assertEqual(action.detail, '') self.assertEqual(action.planned_date, data['purchase_datetime']) self.assertEqual(action.sale.saleitem_set.count(), 3) self.assertEqual(action.sale.saleitem_set.all()[0].item, store_item1) self.assertEqual(action.sale.saleitem_set.all()[0].text, store_item1.name) self.assertEqual(action.sale.saleitem_set.all()[0].unit_price(), store_item1.pre_tax_price * Decimal("0.9")) self.assertEqual(action.sale.saleitem_set.all()[0].vat_rate, store_item1.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[0].quantity, 5) self.assertEqual(action.sale.saleitem_set.all()[1].item, store_item2) self.assertEqual(action.sale.saleitem_set.all()[1].text, store_item2.name) self.assertEqual(action.sale.saleitem_set.all()[1].unit_price(), store_item2.pre_tax_price) self.assertEqual(action.sale.saleitem_set.all()[1].vat_rate, store_item2.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[1].quantity, 2) self.assertEqual(action.sale.saleitem_set.all()[2].item, store_item3) self.assertEqual(action.sale.saleitem_set.all()[2].text, store_item3.name) self.assertEqual(action.sale.saleitem_set.all()[2].unit_price(), store_item3.pre_tax_price) self.assertEqual(action.sale.saleitem_set.all()[2].vat_rate, store_item3.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[2].quantity, 5) self.assertEqual(len(mail.outbox), 2) self.assertEqual(mail.outbox[0].to, [profile.contact.email]) self.assertEqual(mail.outbox[1].to, [settings.BALAFON_NOTIFICATION_EMAIL])
def test_post_cart_notes_several_lines(self): """It should create a new sale and action""" # Create contact for the user profile = create_profile_contact(self.user) contact = profile.contact store_item1 = mommy.make(models.StoreItem) store_item2 = mommy.make(models.StoreItem) delivery_point = mommy.make(models.DeliveryPoint) data = { 'items': [ { 'id': store_item1.id, 'quantity': 2 }, { 'id': store_item2.id, 'quantity': 1 }, ], 'delivery_point': delivery_point.id, 'notes': 'a\nB\nc', 'purchase_datetime': datetime(2015, 7, 23, 12, 0) } url = reverse('store_post_cart') response = self.client.post(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['ok'], True) self.assertEqual(len(response.data['warnings']), 0) self.assertEqual(response.data['deliveryDate'], data['purchase_datetime']) self.assertEqual(response.data['deliveryPlace'], delivery_point.name) action_type = ActionType.objects.get(name=get_cart_type_name()) action_queryset = Action.objects.filter(type=action_type) self.assertEqual(action_queryset.count(), 1) action = action_queryset[0] self.assertEqual(list(action.contacts.all()), [contact]) self.assertEqual(action.subject, _('Notes')) self.assertEqual(action.detail, 'a\nB\nc') self.assertEqual(action.planned_date, data['purchase_datetime']) self.assertEqual(action.sale.saleitem_set.count(), 2) self.assertEqual(action.sale.saleitem_set.all()[0].item, store_item1) self.assertEqual(action.sale.saleitem_set.all()[0].text, store_item1.name) self.assertEqual(action.sale.saleitem_set.all()[0].unit_price(), store_item1.pre_tax_price) self.assertEqual(action.sale.saleitem_set.all()[0].vat_rate, store_item1.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[0].quantity, 2) self.assertEqual(action.sale.saleitem_set.all()[1].item, store_item2) self.assertEqual(action.sale.saleitem_set.all()[1].text, store_item2.name) self.assertEqual(action.sale.saleitem_set.all()[1].unit_price(), store_item2.pre_tax_price) self.assertEqual(action.sale.saleitem_set.all()[1].vat_rate, store_item2.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[1].quantity, 1) self.assertEqual(len(mail.outbox), 2)
def post(self, request): """receive a new cart""" cart_serializer = serializers.CartSerializer(data=request.data) if cart_serializer.is_valid(): # Get Contact try: profile = ContactProfile.objects.get(user=request.user) contact = profile.contact except ContactProfile.DoesNotExist: return Response({ 'ok': False, 'message': _("You don't have a valid profile") }) # Get Delivery point try: delivery_point = DeliveryPoint.objects.get( id=cart_serializer.validated_data["delivery_point"]) except DeliveryPoint.DoesNotExist: return Response({ 'ok': False, 'message': _("Invalid delivery point") }) # Create a new Sale action_type_name = get_cart_type_name() action_type = ActionType.objects.get_or_create( name=action_type_name)[0] # Force this type to be managed by the store StoreManagementActionType.objects.get_or_create( action_type=action_type) subject = detail = '' if 'notes' in cart_serializer.validated_data: notes = cart_serializer.validated_data["notes"].strip() if notes: subject = _('Notes') detail = notes action = Action.objects.create(planned_date=cart_serializer. validated_data['purchase_datetime'], subject=subject, detail=detail, status=action_type.default_status, status2=action_type.default_status2, type=action_type) action.contacts.add(contact) action.save() action.sale.analysis_code = SaleAnalysisCode.objects.get_or_create( name="Internet")[0] action.sale.delivery_point = delivery_point action.sale.save() warnings = [] is_empty = True # for each line add a sale item for index, item in enumerate( cart_serializer.validated_data['items']): quantity = Decimal('{0}'.format(item['quantity'])) try: store_item = StoreItem.objects.get(id=item['id']) except StoreItem.DoesNotExist: # ignore if not existing continue if not store_item.available: warnings.append( _("{0} is currently not available. It has been removed from your cart" ).format(store_item.name)) else: if store_item.stock_count is not None: store_item.stock_count = store_item.stock_count - quantity store_item.save() is_empty = False SaleItem.objects.create( sale=action.sale, quantity=quantity, item=store_item, vat_rate=store_item.vat_rate, pre_tax_price=store_item.pre_tax_price, text=store_item.name, order_index=index + 1) # Done if is_empty: action.delete() return Response({ 'ok': False, 'message': _('Your cart is empty. Your articles are not available'), 'warnings': warnings, }) else: action.sale.save() on_cart_processed = get_cart_processed_callback() if on_cart_processed: on_cart_processed(action) confirm_cart_to_user(profile, action) notify_cart_to_admin(profile, action) return Response({ 'ok': True, 'warnings': warnings, 'deliveryDate': action.planned_date, 'deliveryPlace': action.sale.delivery_point.name, }) else: return Response({ 'ok': False, 'message': ', '.join([ '{0}: {1}'.format(*err) for err in cart_serializer.errors.items() ]) })
def post(self, request): """receive a new cart""" cart_serializer = self.get_serializer() if cart_serializer.is_valid(): self.cart_serializer = cart_serializer discounts = {} vat_rates = {} voucher_code = cart_serializer.validated_data.get( 'voucher_code', '') voucher = Voucher.get_active_voucher(voucher_code) try: contact = self.get_buyer_contact() except Contact.DoesNotExist as exc: return Response({'ok': False, 'message': exc}) # Get Delivery point try: delivery_point = DeliveryPoint.objects.get( id=cart_serializer.validated_data["delivery_point"]) except DeliveryPoint.DoesNotExist: return Response({ 'ok': False, 'message': _("Invalid delivery point") }) # Get Payment mode payment_mode_id = cart_serializer.validated_data.get( 'payment_mode') if payment_mode_id: try: payment_mode = PaymentMode.objects.get(id=payment_mode_id) except PaymentMode.DoesNotExist: return Response({ 'ok': False, 'message': _("Invalid payment mode") }) else: payment_mode = None # Create a new Sale action_type_name = get_cart_type_name() action_type = ActionType.objects.get_or_create( name=action_type_name)[0] # Force this type to be managed by the store StoreManagementActionType.objects.get_or_create( action_type=action_type) subject = detail = '' if 'notes' in cart_serializer.validated_data: notes = cart_serializer.validated_data["notes"].strip() if notes: subject = _('Notes') detail = notes action = Action.objects.create(planned_date=cart_serializer. validated_data['purchase_datetime'], subject=subject, detail=detail, status=action_type.default_status, status2=action_type.default_status2, type=action_type) action.contacts.add(contact) action.save() action.sale.analysis_code = SaleAnalysisCode.objects.get_or_create( name="Internet")[0] action.sale.delivery_point = delivery_point action.sale.payment_mode = payment_mode action.sale.save() warnings = [] is_empty = True # for each line add a sale item counter = 0 for index, item in enumerate( cart_serializer.validated_data['items']): quantity = Decimal('{0}'.format(item['quantity'])) try: store_item = StoreItem.objects.get(id=item['id']) except StoreItem.DoesNotExist: # ignore if not existing continue if not store_item.available: warnings.append( _("{0} is currently not available. It has been removed from your cart" ).format(store_item.name)) else: if store_item.stock_count is not None: store_item.stock_count = store_item.stock_count - quantity store_item.save() is_empty = False SaleItem.objects.create( sale=action.sale, quantity=quantity, item=store_item, vat_rate=store_item.vat_rate, pre_tax_price=store_item.pre_tax_price, text=store_item.name, order_index=index + 1) counter = index # calcule s'il y a une réduction Code Promo # Crée une ligne réduction pour ce code if voucher: discount = store_item.pre_tax_price * voucher.rate / 100 vat_id = store_item.vat_rate.id if store_item.vat_rate else 0 if vat_id not in discounts: vat_rates[vat_id] = store_item.vat_rate discounts[vat_id] = 0 discounts[vat_id] += discount * quantity for discount_vat, discount_value in discounts.items(): counter += 1 SaleItem.objects.create(sale=action.sale, quantity=1, item=None, vat_rate=vat_rates[discount_vat], pre_tax_price=-discount_value, text=voucher.label, order_index=counter, is_discount=True) # Done if is_empty: action.delete() return Response({ 'ok': False, 'message': _('Your cart is empty. Your articles are not available'), 'warnings': warnings, }) else: action.sale.save() on_cart_processed = get_cart_processed_callback() if on_cart_processed: on_cart_processed(action) notify_cart_callback = get_notify_cart_callback() if notify_cart_callback is None: confirm_cart_to_user(contact, action) notify_cart_to_admin(contact, action) else: notify_cart_callback(contact, action) return Response({ 'ok': True, 'action': action.id, 'warnings': warnings, 'deliveryDate': action.planned_date, 'deliveryPlace': action.sale.delivery_point.name, }) else: return Response({ 'ok': False, 'message': ', '.join([ '{0}: {1}'.format(*err) for err in cart_serializer.errors.items() ]) })
def test_post_cart_no_profile(self): """It should create a new sale and action""" store_item1 = mommy.make(models.StoreItem) store_item2 = mommy.make(models.StoreItem) delivery_point = mommy.make(models.DeliveryPoint) zone_type = ZoneType.objects.get_or_create(type="country")[0] default_country = get_default_country() country = Zone.objects.get_or_create(name=default_country, type=zone_type, parent=None)[0] contact_data = { 'lastname': 'Dupond', 'firstname': 'Paul', 'email': '*****@*****.**', 'address': '1 rue la ré', 'city': 'Lyon', 'zip_code': '69000', 'country': country.id, } data = { 'items': [ {'id': store_item1.id, 'quantity': 2}, {'id': store_item2.id, 'quantity': 1}, ], 'delivery_point': delivery_point.id, 'purchase_datetime': datetime(2015, 7, 23, 12, 0), 'contact': contact_data, } url = reverse('store_post_cart_no_profile') response = self.client.post(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['ok'], True) self.assertEqual(len(response.data['warnings']), 0) self.assertEqual(response.data['deliveryDate'], data['purchase_datetime']) self.assertEqual(response.data['deliveryPlace'], delivery_point.name) action_type = ActionType.objects.get(name=get_cart_type_name()) action_queryset = Action.objects.filter(type=action_type) self.assertEqual(action_queryset.count(), 1) action = action_queryset[0] self.assertEqual(response.data['action'], action.id) self.assertEqual(action.contacts.count(), 1) contact = action.contacts.all()[0] self.assertEqual(contact.lastname, contact_data['lastname']) self.assertEqual(contact.firstname, contact_data['firstname']) self.assertEqual(contact.email, contact_data['email']) self.assertEqual(contact.address, contact_data['address']) self.assertEqual(contact.city.name, contact_data['city']) self.assertEqual(contact.zip_code, contact_data['zip_code']) self.assertEqual(contact.get_country(), country) self.assertEqual(action.subject, '') self.assertEqual(action.detail, '') self.assertEqual(action.planned_date, data['purchase_datetime']) self.assertEqual(action.sale.payment_mode, None) self.assertEqual(action.sale.analysis_code, models.SaleAnalysisCode.objects.get(name='Internet')) self.assertEqual(action.sale.saleitem_set.count(), 2) self.assertEqual(action.sale.saleitem_set.all()[0].item, store_item1) self.assertEqual(action.sale.saleitem_set.all()[0].text, store_item1.name) self.assertEqual(action.sale.saleitem_set.all()[0].unit_price(), store_item1.pre_tax_price) self.assertEqual(action.sale.saleitem_set.all()[0].vat_rate, store_item1.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[0].quantity, 2) self.assertEqual(action.sale.saleitem_set.all()[1].item, store_item2) self.assertEqual(action.sale.saleitem_set.all()[1].text, store_item2.name) self.assertEqual(action.sale.saleitem_set.all()[1].unit_price(), store_item2.pre_tax_price) self.assertEqual(action.sale.saleitem_set.all()[1].vat_rate, store_item2.vat_rate) self.assertEqual(action.sale.saleitem_set.all()[1].quantity, 1) self.assertEqual(len(mail.outbox), 2) self.assertEqual(mail.outbox[0].to, [contact.email]) self.assertEqual(mail.outbox[1].to, [settings.BALAFON_NOTIFICATION_EMAIL]) store_item1 = models.StoreItem.objects.get(id=store_item1.id) self.assertEqual(store_item1.stock_count, None) store_item2 = models.StoreItem.objects.get(id=store_item2.id) self.assertEqual(store_item2.stock_count, None)