def test_apply_with_rate(self):
        rule = factories.CustomReimbursementRuleFactory(rate=0.8)
        single = bookings_factories.BookingFactory(quantity=1)
        double = bookings_factories.BookingFactory(quantity=2)

        assert rule.apply(single) == 8
        assert rule.apply(double) == 16
    def test_apply_with_amount(self):
        rule = factories.CustomReimbursementRuleFactory(amount=10)
        single = bookings_factories.BookingFactory(quantity=1)
        double = bookings_factories.BookingFactory(quantity=2)

        assert rule.apply(single) == 10
        assert rule.apply(double) == 20
Esempio n. 3
0
 def test_cannot_change_existing_end_date(self):
     today = datetime.today()
     timespan = (today - timedelta(days=10), today)
     rule = payments_factories.CustomReimbursementRuleFactory(
         timespan=timespan)
     with pytest.raises(exceptions.WrongDateForReimbursementRule):
         api.edit_reimbursement_rule(rule,
                                     end_date=today + timedelta(days=5))
    def test_is_relevant(self):
        offer1 = offers_factories.OfferFactory()
        booking1 = bookings_factories.BookingFactory(stock__offer=offer1)
        rule = factories.CustomReimbursementRuleFactory(offer=offer1)
        assert rule.is_relevant(booking1)

        booking2 = bookings_factories.BookingFactory()
        assert not rule.is_relevant(booking2)
def test_update_from_csv_file_detects_existing_rules_and_mismatches():
    rule1 = payments_factories.CustomReimbursementRuleFactory(amount=8)
    rule2 = payments_factories.CustomReimbursementRuleFactory(amount=8)

    # fmt: off
    csv = "\n".join((
        "this,is,a,header",
        f"""name of offerer,{humanize(rule1.offerId)},"12,34€",8€""",
        f"""name of offerer,{humanize(rule2.offerId)},"12,34€",7€""",
    ))
    # fmt: on
    results = update_from_csv_file(io.StringIO(csv))

    assert not results["created"]
    assert results["errors"] == [
        f"line 3: Existing rule on offer {humanize(rule2.offerId)} ({rule2.offerId}) reimburses 8.00, file says 7"
    ]
Esempio n. 6
0
 def test_validation(self):
     # Validation is thoroughly verified in `test_validation.py`.
     # This is just an integration test.
     timespan = (datetime.today() - timedelta(days=10), None)
     rule = payments_factories.CustomReimbursementRuleFactory(
         timespan=timespan)
     end = pytz.utc.localize(datetime.today())
     with pytest.raises(exceptions.WrongDateForReimbursementRule):
         api.edit_reimbursement_rule(rule, end_date=end)
Esempio n. 7
0
    def test_edit_rule(self):
        timespan = (pytz.utc.localize(datetime(2021, 1, 1)), None)
        rule = payments_factories.CustomReimbursementRuleFactory(
            timespan=timespan)
        end = pytz.utc.localize(datetime(2030, 10, 3, 0, 0))
        api.edit_reimbursement_rule(rule, end_date=end)

        db.session.refresh(rule)
        assert rule.timespan.lower == datetime(2021, 1, 1, 0, 0)  # unchanged
        assert rule.timespan.upper == datetime(2030, 10, 3, 0, 0)
def test_check_stock_has_no_custom_reimbursement_rule():
    stock = offers_factories.StockFactory()
    validation.check_stock_has_no_custom_reimbursement_rule(
        stock)  # should not raise

    payments_factories.CustomReimbursementRuleFactory(offer=stock.offer)
    with pytest.raises(ApiErrors) as error:
        validation.check_stock_has_no_custom_reimbursement_rule(stock)
    assert error.value.errors["price"] == [
        "Vous ne pouvez pas modifier le prix de cette offre"
    ]
Esempio n. 9
0
    def test_with_custom_reimbursement_rule(self):
        booking = bookings_factories.IndividualBookingFactory()
        rule = payments_factories.CustomReimbursementRuleFactory(
            offer=booking.stock.offer, amount=2)
        reimbursement = BookingReimbursement(booking, rule, Decimal(2))
        batch_date = datetime.utcnow()

        payment = create_payment_for_booking(reimbursement, batch_date)
        assert payment.amount == 2
        assert payment.customReimbursementRuleId == rule.id
        assert payment.reimbursementRate is None
        assert payment.reimbursementRule is None
    def test_select_custom_reimbursement_rule_if_applicable(self):
        offer1 = offers_factories.DigitalOfferFactory()
        booking1 = bookings_factories.UsedBookingFactory(stock__offer=offer1)
        offer2 = offers_factories.DigitalOfferFactory()
        booking2 = bookings_factories.UsedBookingFactory(stock__offer=offer2)
        rule1 = payments_factories.CustomReimbursementRuleFactory(offer=offer1,
                                                                  amount=5)
        payments_factories.CustomReimbursementRuleFactory(
            offer=offer2,
            timespan=[booking2.dateCreated + timedelta(days=2), None])
        educational = bookings_factories.UsedEducationalBookingFactory()
        bookings = [booking1, booking2, educational]
        reimbursements = reimbursement.find_all_booking_reimbursements(
            bookings, reimbursement.CustomRuleFinder())

        assert reimbursements[0].booking == booking1
        assert reimbursements[0].rule == rule1
        assert reimbursements[0].reimbursed_amount == 5
        assert_no_reimbursement_for_digital(reimbursements[1], booking2)
        assert_total_reimbursement(
            reimbursements[2], reimbursement.EducationalOffersReimbursement,
            educational)
Esempio n. 11
0
    def test_is_active(self):
        start = datetime.datetime(2021, 1, 12, 0, 0)
        rule = factories.CustomReimbursementRuleFactory(timespan=(start, None))

        # Test without upper bound
        assert rule.is_active(DummyBooking(start))
        assert rule.is_active(
            DummyBooking(start + datetime.timedelta(seconds=2)))
        assert not rule.is_active(
            DummyBooking(start - datetime.timedelta(seconds=2)))

        # Test with upper bound
        end = datetime.datetime(2021, 5, 12, 0, 0)
        rule = factories.CustomReimbursementRuleFactory(timespan=(start, end))
        assert rule.is_active(
            DummyBooking(start + datetime.timedelta(seconds=2)))
        assert not rule.is_active(
            DummyBooking(start - datetime.timedelta(seconds=2)))
        assert rule.is_active(DummyBooking(end -
                                           datetime.timedelta(seconds=2)))
        assert not rule.is_active(DummyBooking(end))
        assert not rule.is_active(
            DummyBooking(end + datetime.timedelta(seconds=2)))
Esempio n. 12
0
def test_edit_rule(mocked_validate_csrf_token, client, app):
    admin = users_factories.AdminFactory()
    timespan = (datetime.datetime.today() - datetime.timedelta(days=10), None)
    rule = payments_factories.CustomReimbursementRuleFactory(timespan=timespan)

    client = client.with_session_auth(admin.email)
    data = {"end_date": "2030-10-01"}
    response = client.post(
        f"/pc/back-office/customreimbursementrule/edit/?id={rule.id}",
        form=data)

    assert response.status_code == 302
    rule = payments_models.CustomReimbursementRule.query.one()
    assert rule.timespan.lower == timespan[0]  # unchanged
    assert rule.timespan.upper == datetime.datetime(2030, 9, 30, 22, 0)  # UTC
    def test_offerer_without_category_rule(self):
        yesterday = datetime.now() - timedelta(days=1)
        far_in_the_past = datetime.now() - timedelta(days=800)
        booking1 = bookings_factories.UsedBookingFactory()
        offerer = booking1.offerer
        booking2 = bookings_factories.UsedBookingFactory(
            offerer=offerer, dateUsed=far_in_the_past)
        booking3 = bookings_factories.UsedBookingFactory()
        rule = payments_factories.CustomReimbursementRuleFactory(
            offerer=offerer, timespan=(yesterday, None))

        finder = reimbursement.CustomRuleFinder()
        assert finder.get_rule(booking1) == rule
        assert finder.get_rule(booking2) is None  # outside `rule.timespan`
        assert finder.get_rule(booking3) is None  # no rule for this offerer
    def test_use_custom_reimbursement_rule_with_rate(self):
        booking = bookings_factories.UsedBookingFactory(amount=10, quantity=2)
        offerer = booking.offerer
        rule = payments_factories.CustomReimbursementRuleFactory(
            offerer=booking.offerer, rate=0.8)
        offers_factories.BankInformationFactory(offerer=offerer,
                                                iban="iban1",
                                                bic="bic1")

        cutoff = batch_date = datetime.datetime.now()
        generate_new_payments(cutoff, batch_date)

        payment = Payment.query.one()
        assert payment.amount == 16  # 2 (quantity) * 0.8 (rate) * 10 (amount)
        assert payment.customReimbursementRule == rule
        assert payment.reimbursementRate == Decimal("0.8")
    def test_use_custom_reimbursement_rule_with_amount(self):
        offer = offers_factories.DigitalOfferFactory()
        offers_factories.BankInformationFactory(venue=offer.venue,
                                                iban="iban1",
                                                bic="bic1")
        bookings_factories.UsedBookingFactory(amount=10,
                                              quantity=2,
                                              stock__offer=offer)
        rule = payments_factories.CustomReimbursementRuleFactory(offer=offer,
                                                                 amount=7)

        cutoff = batch_date = datetime.datetime.now()
        generate_new_payments(cutoff, batch_date)

        payment = Payment.query.one()
        assert payment.amount == 14  # 2 (booking.quantity) * 7 (Rule.amount)
        assert payment.customReimbursementRule == rule
        assert payment.reimbursementRate is None
    def test_offerer_with_category_rule(self):
        yesterday = datetime.now() - timedelta(days=1)
        far_in_the_past = datetime.now() - timedelta(days=800)
        booking1 = bookings_factories.UsedBookingFactory(
            stock__offer__subcategoryId=subcategories.FESTIVAL_CINE.id)
        offerer = booking1.offerer
        booking2 = bookings_factories.UsedBookingFactory(
            stock__offer__subcategoryId=subcategories.LIVRE_PAPIER.id,
            stock__offer__venue__managingOfferer=offerer)
        booking3 = bookings_factories.UsedBookingFactory(
            offerer=offerer,
            stock__offer__subcategoryId=subcategories.FESTIVAL_CINE.id,
            dateUsed=far_in_the_past)
        booking4 = bookings_factories.UsedBookingFactory()
        rule = payments_factories.CustomReimbursementRuleFactory(
            offerer=offerer,
            subcategories=[subcategories.FESTIVAL_CINE.id],
            timespan=(yesterday, None))

        finder = reimbursement.CustomRuleFinder()
        assert finder.get_rule(booking1) == rule
        assert finder.get_rule(booking2) is None  # wrong category
        assert finder.get_rule(booking3) is None  # outside `rule.timespan`
        assert finder.get_rule(booking4) is None  # no rule for this offerer