def setStatus(self, status: TransactionStatus, detail: str = None):
        payment_status = PaymentStatus()
        payment_status.status = status
        payment_status.date = datetime.utcnow()
        payment_status.detail = detail

        self.statuses.append(payment_status)
        def test_payment_date_should_return_payment_date_for_status_sent(self):
            # Given
            payment_date = datetime.utcnow()
            payment = Payment()
            payment_status = PaymentStatus()
            payment_status.status = TransactionStatus.SENT
            payment_status.date = payment_date
            payment.statuses = [payment_status]

            # When/Then
            payment_sent_date = payment.lastProcessedDate
            assert payment_sent_date == payment_date  # pylint: disable=comparison-with-callable
Beispiel #3
0
        def test_payment_date_should_return_no_payment_date_for_status_pending(self):
            # Given
            payment_date = datetime.utcnow()
            payment = Payment()
            payment_status = PaymentStatus()
            payment_status.status = TransactionStatus.PENDING
            payment_status.date = payment_date
            payment.statuses = [payment_status]

            # When/Then
            payment_sent_date = payment.lastProcessedDate
            assert payment_sent_date is None
def mark_payments_as_sent(transaction_label: str,
                          batch_size: int = 1000) -> None:
    modified_sum = 0
    min_id = db.session.query(func.min(Payment.id)).filter(
        Payment.transactionLabel == transaction_label).scalar()
    max_id = db.session.query(func.max(Payment.id)).filter(
        Payment.transactionLabel == transaction_label).scalar()

    if min_id is None or max_id is None:
        logger.info("No payments needed to be marked as sent")
        return

    now = datetime.datetime.utcnow()
    for batch_start in range(min_id, max_id + 1, batch_size):
        payments_ids = get_payments_ids_under_review(batch_start, batch_size,
                                                     transaction_label)
        if len(payments_ids) == 0:
            continue

        payment_statuses_to_add: list[PaymentStatus] = []
        for payment_id in payments_ids:
            payment_statuses_to_add.append(
                PaymentStatus(paymentId=payment_id,
                              status=TransactionStatus.SENT,
                              date=now))

        db.session.bulk_save_objects(payment_statuses_to_add)
        mark_bookings_as_reimbursed_from_payment_ids(payments_ids, now)
        db.session.commit()

        modified_sum += len(payments_ids)

    logger.info("%d payments have been marked as sent for transaction %s",
                modified_sum, transaction_label)
Beispiel #5
0
def create_payment(
    booking: Booking,
    offerer: Offerer,
    amount: int = 10,
    author: str = "test author",
    bic: str = None,
    comment: str = None,
    iban: str = None,
    idx: int = None,
    payment_message: PaymentMessage = None,
    payment_message_name: str = None,
    reimbursement_rate: float = 0.5,
    reimbursement_rule: str = "remboursement à 100%",
    status: TransactionStatus = TransactionStatus.PENDING,
    detail: str = None,
    status_date: datetime = datetime.utcnow(),
    transaction_end_to_end_id: str = None,
    transaction_label: str = None,
) -> Payment:
    payment_status = PaymentStatus()
    payment_status.status = status
    payment_status.date = status_date
    payment_status.detail = detail

    payment = Payment()
    payment.amount = amount
    payment.author = author
    payment.bic = bic
    payment.booking = booking
    payment.comment = comment
    payment.iban = iban
    payment.id = idx
    if payment_message_name:
        payment.paymentMessage = create_payment_message(
            name=payment_message_name)
    elif payment_message:
        payment.paymentMessage = payment_message
    payment.recipientName = offerer.name
    payment.recipientSiren = offerer.siren
    payment.reimbursementRate = reimbursement_rate
    payment.reimbursementRule = reimbursement_rule
    payment.statuses = [payment_status]
    payment.transactionEndToEndId = transaction_end_to_end_id
    payment.transactionLabel = transaction_label

    return payment
    def test_appends_a_status_to_a_payment_with_existing_status(self):
        # given
        one_second = timedelta(seconds=1)
        now = datetime.utcnow()
        payment = Payment()
        payment_status = PaymentStatus()
        payment_status.status = TransactionStatus.PENDING
        payment_status.date = datetime.utcnow()
        payment.statuses = [payment_status]

        # when
        payment.setStatus(TransactionStatus.SENT)

        # then
        assert len(payment.statuses) == 2
        assert payment.statuses[1].status == TransactionStatus.SENT
        assert payment.statuses[1].detail is None
        assert now - one_second < payment.statuses[1].date < now + one_second
Beispiel #7
0
    def test_a_list_of_payments_is_returned_with_statuses_in_error_or_retry_or_pending(
            self, app):
        # Given
        user = create_user()
        booking = create_booking(user=user)
        deposit = create_deposit(user)
        offerer = booking.stock.offer.venue.managingOfferer

        error_payment = create_payment(booking, offerer, 10)
        retry_payment = create_payment(booking, offerer, 10)
        pending_payment = create_payment(booking, offerer, 10)
        not_processable_payment = create_payment(booking, offerer, 10)

        error_status = PaymentStatus()
        error_status.status = TransactionStatus.ERROR
        error_payment.statuses.append(error_status)

        retry_status = PaymentStatus()
        retry_status.status = TransactionStatus.RETRY
        retry_payment.statuses.append(retry_status)

        not_processable_status = PaymentStatus()
        not_processable_status.status = TransactionStatus.NOT_PROCESSABLE
        not_processable_payment.statuses.append(not_processable_status)

        repository.save(error_payment, retry_payment, pending_payment, deposit)

        # When
        payments = concatenate_payments_with_errors_and_retries(
            [pending_payment])

        # Then
        assert len(payments) == 3
        allowed_statuses = (TransactionStatus.RETRY, TransactionStatus.ERROR,
                            TransactionStatus.PENDING)
        assert all(
            map(lambda p: p.currentStatus.status in allowed_statuses,
                payments))
Beispiel #8
0
        def test_payment_date_should_return_oldest_payment_date_for_status_sent_if_several(self, app):
            # Given
            payment_date = datetime.utcnow()
            payment = Payment()
            payment_status = PaymentStatus()
            payment_status.status = TransactionStatus.SENT
            payment_status.date = payment_date
            payment.statuses = [payment_status]
            older_payment_date = datetime.utcnow() - timedelta(days=1)
            payment_status.status = TransactionStatus.SENT
            payment_status.date = older_payment_date
            payment.statuses = [payment_status]

            # When/Then
            payment_sent_date = payment.lastProcessedDate
            assert payment_sent_date == older_payment_date  # pylint: disable=comparison-with-callable
    def test_does_not_return_payment_if_has_status_error_but_not_last(
            self, app):
        # Given
        user = users_factories.UserFactory()
        booking = create_booking(user=user)
        error_payment = create_payment(
            booking, booking.stock.offer.venue.managingOfferer, 10)
        pending_payment = create_payment(
            booking, booking.stock.offer.venue.managingOfferer, 10)
        error_status = PaymentStatus()
        error_status.status = TransactionStatus.ERROR
        sent_status = PaymentStatus()
        sent_status.status = TransactionStatus.SENT
        error_payment.statuses.extend([error_status, sent_status])
        repository.save(error_payment, pending_payment)

        # When
        payments = payment_queries.find_error_payments()

        # Then
        assert payments == []
Beispiel #10
0
    def test_does_not_return_payment_if_has_status_retry_but_not_last(
            self, app):
        # Given
        user = create_user()
        booking = create_booking(user=user)
        create_deposit(user)
        payment = create_payment(booking,
                                 booking.stock.offer.venue.managingOfferer, 10)
        payment = create_payment(booking,
                                 booking.stock.offer.venue.managingOfferer, 10)
        pending_payment = create_payment(
            booking, booking.stock.offer.venue.managingOfferer, 10)
        retry_status = PaymentStatus()
        retry_status.status = TransactionStatus.RETRY
        sent_status = PaymentStatus()
        sent_status.status = TransactionStatus.SENT
        payment.statuses.extend([retry_status, sent_status])
        repository.save(payment, pending_payment)

        # When
        payments = payment_queries.find_retry_payments()

        # Then
        assert payments == []