def test_send_payments_report_sends_two_csv_attachments_if_some_payments_are_not_processable_and_in_error( app): # given iban = "CF13QSDFGH456789" bic = "QSDFGH8Z555" payment1 = payments_factories.PaymentFactory(iban=iban, bic=bic, statuses=[]) payments_factories.PaymentStatusFactory(payment=payment1, status=TransactionStatus.SENT) payment2 = payments_factories.PaymentFactory(iban=iban, bic=bic, statuses=[]) payments_factories.PaymentStatusFactory(payment=payment2, status=TransactionStatus.ERROR) payment3 = payments_factories.PaymentFactory(iban=iban, bic=bic, statuses=[]) payments_factories.PaymentStatusFactory( payment=payment3, status=TransactionStatus.NOT_PROCESSABLE) payments = [payment1, payment2, payment3] # when send_payments_report(payments, ["*****@*****.**"]) # then assert len(mails_testing.outbox) == 1 assert len(mails_testing.outbox[0].sent_data["Attachments"]) == 2 assert mails_testing.outbox[0].sent_data["Attachments"][0][ "ContentType"] == "text/csv" assert mails_testing.outbox[0].sent_data["Attachments"][1][ "ContentType"] == "text/csv"
def test_send_payments_report_sends_two_csv_attachments_if_no_payments_are_in_error_or_sent( app): # given iban = "CF13QSDFGH456789" bic = "QSDFGH8Z555" payment1 = payments_factories.PaymentFactory(iban=iban, bic=bic, statuses=[]) payment2 = payments_factories.PaymentFactory(iban=iban, bic=bic, statuses=[]) for payment in (payment1, payment2): payments_factories.PaymentStatusFactory(payment=payment, status=TransactionStatus.SENT) payments = [payment1, payment2] # when send_payments_report(payments, ["*****@*****.**"]) # then assert len(mails_testing.outbox) == 1 assert len(mails_testing.outbox[0].sent_data["Attachments"]) == 2 assert mails_testing.outbox[0].sent_data["Attachments"][0][ "ContentType"] == "text/csv" assert mails_testing.outbox[0].sent_data["Attachments"][1][ "ContentType"] == "text/csv"
def test_send_payments_report_does_not_send_anything_if_no_payments_are_provided( app): # given payments = [] # when send_payments_report(payments, ["*****@*****.**"]) # then assert not mails_testing.outbox
def test_send_payments_report_does_not_send_anything_if_no_payments_are_provided( app): # given payments = [] # when send_payments_report(payments, ["*****@*****.**"]) # then app.mailjet_client.send.create.assert_not_called()
def test_send_payments_report_sends_one_csv_attachment_if_some_payments_are_not_processable(): # given batch_date = datetime.datetime.now() payments = payments_factories.PaymentFactory.create_batch(3, statuses=[], batchDate=batch_date) payments_factories.PaymentStatusFactory(payment=payments[0], status=TransactionStatus.UNDER_REVIEW) payments_factories.PaymentStatusFactory(payment=payments[1], status=TransactionStatus.ERROR) payments_factories.PaymentStatusFactory(payment=payments[2], status=TransactionStatus.NOT_PROCESSABLE) # when send_payments_report(batch_date, ["*****@*****.**"]) # then assert len(mails_testing.outbox) == 1 assert len(mails_testing.outbox[0].sent_data["Attachments"]) == 1 assert mails_testing.outbox[0].sent_data["Attachments"][0]["ContentType"] == "text/csv"
def test_send_payments_report_sends_two_csv_attachments_if_no_payments_are_in_error_or_sent( app): # given offerer1 = create_offerer(name="first offerer") user = create_user() venue1 = create_venue(offerer1) stock1 = create_stock_from_offer(create_offer_with_thing_product(venue1)) booking1 = create_booking(user=user, stock=stock1) booking2 = create_booking(user=user, stock=stock1) booking3 = create_booking(user=user, stock=stock1) deposit = create_deposit(user, amount=500) payments = [ create_payment(booking1, offerer1, 10, status=TransactionStatus.SENT, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), create_payment(booking2, offerer1, 20, status=TransactionStatus.SENT, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), create_payment(booking3, offerer1, 20, status=TransactionStatus.SENT, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), ] repository.save(deposit) repository.save(*payments) app.mailjet_client.send.create.return_value = Mock(status_code=200) # when send_payments_report(payments, ["*****@*****.**"]) # then app.mailjet_client.send.create.assert_called_once() args = app.mailjet_client.send.create.call_args assert len(args[1]["data"]["Attachments"]) == 2 assert args[1]["data"]["Attachments"][0]["ContentType"] == "text/csv" assert args[1]["data"]["Attachments"][1]["ContentType"] == "text/csv"
def generate_and_send_payments(cutoff_date: datetime.datetime, batch_date: datetime.datetime = None): logger.info("[BATCH][PAYMENTS] STEP 0 : validate bookings associated to outdated stocks") if FeatureToggle.UPDATE_BOOKING_USED.is_active(): bookings_api.auto_mark_as_used_after_event() if batch_date is None: batch_date = datetime.datetime.utcnow() generate_payments(cutoff_date, batch_date) payments_to_send = payment_queries.get_payments_by_status( (TransactionStatus.PENDING, TransactionStatus.ERROR, TransactionStatus.RETRY), batch_date ) logger.info("[BATCH][PAYMENTS] STEP 3 : send transactions") send_transactions( payments_to_send, batch_date, settings.PASS_CULTURE_IBAN, settings.PASS_CULTURE_BIC, settings.PASS_CULTURE_REMITTANCE_CODE, settings.TRANSACTIONS_RECIPIENTS, ) # `send_transactions()` updates the status of the payments. Thus, # `payments_to_send` must not be used anymore since the query # would not yield any result anymore. del payments_to_send logger.info("[BATCH][PAYMENTS] STEP 4 : send payments report") send_payments_report(batch_date, settings.PAYMENTS_REPORT_RECIPIENTS) # Recreate `payments_to_send` query, after `send_transactions()` # has updated the status of all payments. payments_to_send = payment_queries.get_payments_by_status([TransactionStatus.UNDER_REVIEW], batch_date) logger.info("[BATCH][PAYMENTS] STEP 5 : send payments details") send_payments_details(payments_to_send, settings.PAYMENTS_DETAILS_RECIPIENTS) # This is the only place where we want to catch errors, since it's # not really related to payment data (and can easily be executed # manually). try: logger.info("[BATCH][PAYMENTS] STEP 6 : send wallet balances") send_wallet_balances(settings.WALLET_BALANCES_RECIPIENTS) except Exception as e: # pylint: disable=broad-except logger.exception("[BATCH][PAYMENTS] STEP 6: %s", e) logger.info("[BATCH][PAYMENTS] generate_and_send_payments is done")
def generate_and_send_payments(payment_message_id: str = None): logger.info( "[BATCH][PAYMENTS] STEP 0 : validate bookings associated to outdated stocks" ) if feature_queries.is_active(FeatureToggle.UPDATE_BOOKING_USED): update_booking_used_after_stock_occurrence() not_processable_payments, payments_to_send = generate_or_collect_payments( payment_message_id) try: logger.info("[BATCH][PAYMENTS] STEP 3 : send transactions") send_transactions( payments_to_send, settings.PASS_CULTURE_IBAN, settings.PASS_CULTURE_BIC, settings.PASS_CULTURE_REMITTANCE_CODE, settings.TRANSACTIONS_RECIPIENTS, ) except Exception as e: # pylint: disable=broad-except logger.exception("[BATCH][PAYMENTS] STEP 3: %s", e) try: logger.info("[BATCH][PAYMENTS] STEP 4 : send payments report") send_payments_report(payments_to_send + not_processable_payments, settings.PAYMENTS_REPORT_RECIPIENTS) except Exception as e: # pylint: disable=broad-except logger.exception("[BATCH][PAYMENTS] STEP 4: %s", e) try: logger.info("[BATCH][PAYMENTS] STEP 5 : send payments details") send_payments_details(payments_to_send, settings.PAYMENTS_DETAILS_RECIPIENTS) except Exception as e: # pylint: disable=broad-except logger.exception("[BATCH][PAYMENTS] STEP 5: %s", e) try: logger.info("[BATCH][PAYMENTS] STEP 6 : send wallet balances") send_wallet_balances(settings.WALLET_BALANCES_RECIPIENTS) except Exception as e: # pylint: disable=broad-except logger.exception("[BATCH][PAYMENTS] STEP 6: %s", e) logger.info("[BATCH][PAYMENTS] generate_and_send_payments is done")