Example #1
0
    def test_quote_price_with_datetime_rules(self, an_order):
        an_order.date = datetime.strptime('Sat, 30 Nov 2019 18:30:00 -0300',
                                          "%a, %d %b %Y %H:%M:%S %z")
        an_order.save()

        Rule(name='5% discount today',
             conditions=[
                 RuleCondition(
                     variable=RuleCondition.ORDER_DATE,
                     operator=RuleCondition.IS,
                     condition_value='Sat, 30 Nov 2019 18:30:00 -0300'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.PERCENTAGE,
                 value=-5)).save()
        Rule(name='base price',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='0'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=20)).save()

        assert self.rule_service.quote_price(an_order.id) == 19
Example #2
0
    def test_20_percent_discount_from_fifth_order(self, an_order_factory):
        an_order = an_order_factory()
        an_order_factory()
        an_order_factory()
        an_order_factory()
        an_order_factory()

        Rule(name='Minimum delivery cost of $20',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='0'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=20)).save()

        Rule(name='%20 discount from 5th order',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_QUANTITY,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='5'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.PERCENTAGE,
                 value=-20)).save()

        self.assert_price(an_order, 16)
Example #3
0
    def test_recharge_of_10_from_monday_to_friday_from_5_pm_to_7_pm(
            self, an_order_factory):
        an_order = an_order_factory()
        an_order.date = datetime.strptime('Wed, 27 Nov 2019 17:30:00 GMT',
                                          "%a, %d %b %Y %H:%M:%S %Z")
        an_order.save()

        another_order = an_order_factory()
        another_order.date = datetime.strptime('Sat, 30 Nov 2019 17:30:00 GMT',
                                               "%a, %d %b %Y %H:%M:%S %Z")
        another_order.save()

        Rule(name='$10 recharge from monday to friday from 5pm to 7pm',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_DAY,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='1'),
                 RuleCondition(variable=RuleCondition.ORDER_DAY,
                               operator=RuleCondition.LESS_THAN_EQUAL,
                               condition_value='5'),
                 RuleCondition(
                     variable=RuleCondition.ORDER_TIME,
                     operator=RuleCondition.GREATER_THAN_EQUAL,
                     condition_value='Sat, 30 Nov 2019 15:00:00 -0300'),
                 RuleCondition(
                     variable=RuleCondition.ORDER_TIME,
                     operator=RuleCondition.LESS_THAN_EQUAL,
                     condition_value='Sat, 30 Nov 2019 19:00:00 -0300'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=10)).save()

        self.assert_price(an_order, 10)
        self.assert_price(another_order, 0)
Example #4
0
    def test_quote_price_with_distance_rule(self, mocked_get, an_order,
                                            a_distance_response):
        mocked_get.return_value = a_distance_response(54)

        # to Escobar
        an_order.owner.location.latitude = -34.3467
        an_order.owner.location.longitude = -58.8186
        an_order.owner.save()

        # from Buenos Aires
        an_order.ordered_products[
            0].product.place.coordinates.latitude = -34.603722
        an_order.ordered_products[
            0].product.place.coordinates.longitude = -58.381592
        an_order.ordered_products[0].product.place.save()

        Rule(name='$200 if distance is greater than 50km',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_DISTANCE,
                               operator=RuleCondition.GREATER_THAN,
                               condition_value='50'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=200)).save()

        # rule should apply cause the distance is ~54 > 50
        assert self.rule_service.quote_price(an_order.id) == 200
Example #5
0
    def test_quote_price_with_value_per_unit_consequence(
            self, mocked_get, an_order, a_distance_response):
        mocked_get.return_value = a_distance_response(54)

        # to Escobar
        an_order.owner.location.latitude = -34.3467
        an_order.owner.location.longitude = -58.8186
        an_order.owner.save()

        # from Buenos Aires
        an_order.ordered_products[
            0].product.place.coordinates.latitude = -34.603722
        an_order.ordered_products[
            0].product.place.coordinates.longitude = -58.381592
        an_order.ordered_products[0].product.place.save()

        Rule(name='$20 per km',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_DISTANCE,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='20'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.PER_UNIT_VALUE,
                 value=20,
                 variable=RuleCondition.ORDER_DISTANCE)).save()

        assert self.rule_service.quote_price(an_order.id) == 20 * 54
Example #6
0
    def test_five_percent_discount_wednesdays_from_three_pm_to_four_pm(
            self, an_order_factory):
        an_order = an_order_factory()
        an_order.date = datetime.strptime('Wed, 27 Nov 2019 15:30:00 GMT',
                                          "%a, %d %b %Y %H:%M:%S %Z")
        an_order.save()

        another_order = an_order_factory()
        another_order.date = datetime.strptime('Wed, 27 Nov 2019 16:30:00 GMT',
                                               "%a, %d %b %Y %H:%M:%S %Z")
        another_order.save()

        Rule(name='Minimum delivery cost of $20',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='0'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=20)).save()

        Rule(name='5% discount on wednesdays from 3pm to 4pm',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_DAY,
                               operator=RuleCondition.IS,
                               condition_value='3'),
                 RuleCondition(
                     variable=RuleCondition.ORDER_TIME,
                     operator=RuleCondition.GREATER_THAN_EQUAL,
                     condition_value='Sat, 30 Nov 2019 15:00:00 -0300'),
                 RuleCondition(
                     variable=RuleCondition.ORDER_TIME,
                     operator=RuleCondition.LESS_THAN_EQUAL,
                     condition_value='Sat, 30 Nov 2019 16:00:00 -0300')
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.PERCENTAGE,
                 value=-5,
             )).save()

        self.assert_price(an_order, 19.0)
        self.assert_price(another_order, 20)
Example #7
0
    def test_apply_with_value_per_unit_should_multiple_value_by_condition_variable(
            self, mocked_distance, a_client, an_order):
        # pylint: disable=unused-argument
        mocked_distance.return_value = 10
        consequence = RuleConsequence(
            consequence_type=RuleConsequence.PER_UNIT_VALUE,
            value=-10,
            variable=RuleCondition.ORDER_DISTANCE)
        result = self.consequence_service.apply(consequence, 200, an_order)

        assert result == 100
Example #8
0
    def test_percentage_consequence_should_apply_last(self, an_order):
        Rule(name='new rule',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.LESS_THAN,
                               condition_value='2'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.PERCENTAGE,
                 value=-10)).save()

        Rule(name='new rule',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.LESS_THAN,
                               condition_value='2'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=10)).save()

        assert self.rule_service.quote_price(an_order.id) == 9
Example #9
0
    def test_price_per_extra_km(self, mocked_get, an_order,
                                a_distance_response):
        mocked_get.return_value = a_distance_response(54)

        # to Escobar
        an_order.owner.location.latitude = -34.3467
        an_order.owner.location.longitude = -58.8186
        an_order.owner.save()

        # from Buenos Aires
        an_order.ordered_products[
            0].product.place.coordinates.latitude = -34.603722
        an_order.ordered_products[
            0].product.place.coordinates.longitude = -58.381592
        an_order.ordered_products[0].product.place.save()

        Rule(name='$15 per extra kilometer above 2',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_DISTANCE,
                               operator=RuleCondition.GREATER_THAN,
                               condition_value='2'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.PER_UNIT_VALUE,
                 value=15,
                 variable=RuleCondition.ORDER_DISTANCE)).save()

        Rule(name='discount first 2km',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_DISTANCE,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='2'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE,
                 value=-30,
             )).save()

        self.assert_price(an_order, 52 * 15)
Example #10
0
    def test_should_return_zero_if_quotation_is_negative(self, an_order):
        Rule(name='$20 discount',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='0'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE,
                 value=-20,
             )).save()

        assert self.rule_service.quote_price(an_order.id) == 0
Example #11
0
    def test_minimum_delivery_cost(self, mocked_get, an_order,
                                   a_distance_response):
        mocked_get.return_value = a_distance_response(1)

        Rule(name='Minimum delivery cost of $20',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_DISTANCE,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='0'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=20)).save()

        self.assert_price(an_order, 20)
Example #12
0
    def test_mark_order_as_completed_increases_delivery_balance_by_85_percent_of_order_trip(
            self, a_client, a_client_user, an_order, a_delivery_user):
        Rule(name='$20 base',
             conditions=[],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value='20')).save()

        self.login(a_client, a_client_user.email, a_client_user.password)
        self.patch(a_client, 'api/v1/orders/{}'.format(str(an_order.id)),
                   {'delivery': a_delivery_user.id})
        self.patch(a_client, 'api/v1/orders/{}'.format(str(an_order.id)),
                   {'status': Order.DELIVERED_STATUS})

        assert Order.objects.get(id=an_order.id).delivery.balance == 0.85 * 20
Example #13
0
 def test_redeemable_rule_should_be_benefit(self):
     with pytest.raises(ValidationError):
         self.rule_service.create(
             name='Minimum delivery cost of $10 for premium users',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='0'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=10),
             benefit=False,
             redeemable=True,
         )
Example #14
0
    def test_apply_consequence_with_one_rule(self, an_order):
        Rule(name='new rule',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.LESS_THAN,
                               condition_value='2')
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=5)).save()

        an_order.owner.reputation = 1
        an_order.owner.save()

        assert self.rule_service.quote_price(an_order.id) == 5
Example #15
0
    def test_create_benefit_redeemable_rule_without_cost_sets_it_to_zero(self):
        rule = Rule(
            name='Minimum delivery cost of $10 for premium users',
            conditions=[
                RuleCondition(variable=RuleCondition.USER_REPUTATION,
                              operator=RuleCondition.GREATER_THAN_EQUAL,
                              condition_value='0'),
            ],
            consequence=RuleConsequence(consequence_type=RuleConsequence.VALUE,
                                        value=10),
            benefit=True,
            redeemable=True,
        ).save()

        assert rule.cost == 0
Example #16
0
    def test_benefit_rules_do_not_apply_to_flat_users(self, a_customer_user,
                                                      an_order):
        an_order.owner = a_customer_user
        an_order.save()

        Rule(name='Minimum delivery cost of $10 for premium users',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='0'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=10),
             benefit=True).save()

        assert not self.rule_service.quote_price(an_order.id)
Example #17
0
    def test_should_not_apply_rule_if_its_not_active(self, an_order):
        rule = Rule(name='$20 base',
                    conditions=[
                        RuleCondition(
                            variable=RuleCondition.USER_REPUTATION,
                            operator=RuleCondition.GREATER_THAN_EQUAL,
                            condition_value='0'),
                    ],
                    consequence=RuleConsequence(
                        consequence_type=RuleConsequence.VALUE,
                        value=20,
                    )).save()

        rule.active = False
        rule.save()

        assert self.rule_service.quote_price(an_order.id) == 0
Example #18
0
    def test_100_discount_on_first_order(self, an_order_factory):
        an_order = an_order_factory()

        Rule(name='$100 discount on first order',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_QUANTITY,
                               operator=RuleCondition.IS,
                               condition_value='1'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=-100)).save()

        self.assert_price(an_order, 0)

        an_order_factory()

        self.assert_price(an_order, 0)
Example #19
0
    def test_quote_price_with_location_rule(self, mocked_get, an_order,
                                            a_geocode_response):
        mocked_get.return_value = a_geocode_response('Ingeniero Maschwitz')
        # Ing Maschwitz
        an_order.owner.location.latitude = -34.3814
        an_order.owner.location.longitude = -58.7569
        an_order.owner.save()

        Rule(name='$200 if order is in Ingeniero Maschwitz',
             conditions=[
                 RuleCondition(variable=RuleCondition.ORDER_POSITION,
                               operator=RuleCondition.IS,
                               condition_value='Ingeniero Maschwitz'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=200)).save()

        assert self.rule_service.quote_price(an_order.id) == 200
Example #20
0
    def test_quote_order_returns_order_quotation(self, a_client, a_client_user,
                                                 an_order):
        Rule(name='$20 base',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='0')
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value='20')).save()

        self.login(a_client, a_client_user.email, a_client_user.password)
        response = self.get(
            a_client, 'api/v1/orders/{}/quotation'.format(str(an_order.id)))

        assert_200(response)

        assert json.loads(response.data) == {'price': 20}
Example #21
0
    def test_redeemable_benefits_apply_to_users_with_the_benefit(
            self, a_customer_user, an_order):
        an_order.owner = a_customer_user
        an_order.save()

        Rule(name='Minimum delivery cost of $10 for premium users',
             conditions=[
                 RuleCondition(variable=RuleCondition.USER_REPUTATION,
                               operator=RuleCondition.GREATER_THAN_EQUAL,
                               condition_value='0'),
             ],
             consequence=RuleConsequence(
                 consequence_type=RuleConsequence.VALUE, value=10),
             benefit=True,
             redeemable=True,
             redeemed_by=[a_customer_user.id]).save()

        assert self.rule_service.quote_price(an_order.id) == 10
Example #22
0
def a_consequence():
    return RuleConsequence(consequence_type=RuleConsequence.VALUE, value=0)
Example #23
0
    def test_apply_with_negative_value_should_reduce_it(self):
        consequence = RuleConsequence(consequence_type=RuleConsequence.VALUE,
                                      value=-1)
        result = self.consequence_service.apply(consequence, 10)

        assert result == 9
Example #24
0
    def test_apply_with_percentage_should_add_right_value(self):
        consequence = RuleConsequence(
            consequence_type=RuleConsequence.PERCENTAGE, value=10)
        result = self.consequence_service.apply(consequence, 10)

        assert result == 11.0
Example #25
0
    def test_apply_with_percentage_and_negative_value_should_reduce(self):
        consequence = RuleConsequence(
            consequence_type=RuleConsequence.PERCENTAGE, value=-10)
        result = self.consequence_service.apply(consequence, 10)

        assert result == 9.0
Example #26
0
    def test_apply_with_positive_value_adds_it(self):
        consequence = RuleConsequence(consequence_type=RuleConsequence.VALUE,
                                      value=1)
        result = self.consequence_service.apply(consequence, 10)

        assert result == 11
Example #27
0
 def test_should_apply_consequence_if_no_condition(self, an_order):
     Rule(name='new rule',
          conditions=[],
          consequence=RuleConsequence(
              consequence_type=RuleConsequence.VALUE, value=5)).save()
     assert self.rule_service.quote_price(an_order.id) == 5