Exemple #1
0
def test_post_default_statement_settings_daily(session, client, jwt, app):
    """Assert that the post endpoint works."""
    token = jwt.create_jwt(get_claims(), token_header)
    headers = {
        'Authorization': f'Bearer {token}',
        'content-type': 'application/json'
    }

    rv = client.post('/api/v1/payment-requests',
                     data=json.dumps(
                         get_payment_request(business_identifier='CP0002000')),
                     headers=headers)

    invoice: Invoice = Invoice.find_by_id(rv.json.get('id'))
    pay_account: PaymentAccount = PaymentAccount.find_by_id(
        invoice.payment_account_id)

    rv = client.get(
        f'/api/v1/accounts/{pay_account.auth_account_id}/statements/settings',
        data=json.dumps({}),
        headers=headers)
    assert rv.status_code == 200
    assert rv.json.get('currentFrequency').get(
        'frequency') == StatementFrequency.WEEKLY.value

    # Set the frequency to Daily and assert
    daily_frequency = {'frequency': 'DAILY'}
    rv = client.post(
        f'/api/v1/accounts/{pay_account.auth_account_id}/statements/settings',
        data=json.dumps(daily_frequency),
        headers=headers)
    assert rv.json.get('frequency') == StatementFrequency.DAILY.value
    end_date = get_week_start_and_end_date()[1]
    assert rv.json.get('fromDate') == (end_date +
                                       timedelta(days=1)).strftime('%Y-%m-%d')

    # Set the frequency to Monthly and assert
    daily_frequency = {'frequency': 'MONTHLY'}
    rv = client.post(
        f'/api/v1/accounts/{pay_account.auth_account_id}/statements/settings',
        data=json.dumps(daily_frequency),
        headers=headers)
    end_date = get_first_and_last_dates_of_month(current_local_time().month,
                                                 current_local_time().year)[1]
    assert rv.json.get('frequency') == StatementFrequency.MONTHLY.value
    assert rv.json.get('fromDate') == (end_date +
                                       timedelta(days=1)).strftime('%Y-%m-%d')

    # Get the latest frequency
    rv = client.get(
        f'/api/v1/accounts/{pay_account.auth_account_id}/statements/settings',
        data=json.dumps({}),
        headers=headers)
    assert rv.status_code == 200
    assert rv.json.get('currentFrequency').get(
        'frequency') == StatementFrequency.MONTHLY.value
Exemple #2
0
 def _get_end_of(frequency: StatementFrequency):
     """Return the end of either week or month."""
     today = datetime.today()
     end_date = current_local_time()
     if frequency == StatementFrequency.WEEKLY.value:
         end_date = get_week_start_and_end_date()[1]
     if frequency == StatementFrequency.MONTHLY.value:
         end_date = get_first_and_last_dates_of_month(
             today.month, today.year)[1]
     return end_date
Exemple #3
0
def test_get_default_statement_settings_weekly(session, client, jwt, app):
    """Assert that the default statement setting is weekly."""
    token = jwt.create_jwt(get_claims(), token_header)
    headers = {
        'Authorization': f'Bearer {token}',
        'content-type': 'application/json'
    }
    rv = client.post('/api/v1/payment-requests',
                     data=json.dumps(
                         get_payment_request(business_identifier='CP0002000')),
                     headers=headers)

    invoice: Invoice = Invoice.find_by_id(rv.json.get('id'))
    pay_account: PaymentAccount = PaymentAccount.find_by_id(
        invoice.payment_account_id)

    rv = client.get(
        f'/api/v1/accounts/{pay_account.auth_account_id}/statements/settings',
        headers=headers)
    assert rv.status_code == 200
    assert rv.json.get('currentFrequency').get(
        'frequency') == StatementFrequency.WEEKLY.value
    # Assert the array of the frequncies
    for freqeuncy in rv.json.get('frequencies'):
        if freqeuncy.get('frequency') == StatementFrequency.WEEKLY.value:
            actual_weekly = dateutil.parser.parse(
                freqeuncy.get('startDate')).date()
            expected_weekly = (get_week_start_and_end_date()[1] +
                               timedelta(days=1)).date()
            assert actual_weekly == expected_weekly, 'weekly matches'
        if freqeuncy.get('frequency') == StatementFrequency.MONTHLY.value:
            today = datetime.today()
            actual_monthly = dateutil.parser.parse(
                freqeuncy.get('startDate')).date()
            expected_monthly = (
                get_first_and_last_dates_of_month(today.month, today.year)[1] +
                timedelta(days=1)).date()
            assert actual_monthly == expected_monthly, 'monthly matches'
        if freqeuncy.get('frequency') == StatementFrequency.DAILY.value:
            actual_daily = dateutil.parser.parse(
                freqeuncy.get('startDate')).date()
            # since current frequncy is weekly , daily changes will happen at the end of the week
            expected_weekly = (get_week_start_and_end_date()[1] +
                               timedelta(days=1)).date()
            assert actual_daily == expected_weekly, 'daily matches'
def test_update_statement_monthly(session):
    """Assert that the statement settings by id works."""
    bcol_account = factory_premium_payment_account()
    bcol_account.save()

    payment = factory_payment()
    payment.save()
    i = factory_invoice(payment_account=bcol_account)
    i.save()
    factory_invoice_reference(i.id).save()
    factory_statement_settings(payment_account_id=bcol_account.id,
                               frequency=StatementFrequency.MONTHLY.value)

    # update to weekly
    payment_account = PaymentAccount.find_by_id(bcol_account.id)
    statement_settings = StatementSettingsService.update_statement_settings(
        payment_account.auth_account_id, StatementFrequency.WEEKLY.value)
    assert statement_settings is not None
    assert statement_settings.get(
        'frequency') == StatementFrequency.WEEKLY.value
    assert statement_settings.get('to_date') is None

    # monthly to weekly - assert weekly should start by next week first day
    end_of_month_date = get_first_and_last_dates_of_month(
        datetime.today().month,
        datetime.today().year)[1]
    assert statement_settings.get('from_date') == (
        end_of_month_date + timedelta(days=1)).strftime(DT_SHORT_FORMAT)

    # monthly to weekly - assert current active one is stil monthly ending end of the week
    current_statement_settings = StatementSettingsModel.find_active_settings(
        payment_account.auth_account_id, datetime.today())
    assert current_statement_settings is not None
    assert current_statement_settings.frequency == StatementFrequency.MONTHLY.value
    assert current_statement_settings.to_date == end_of_month_date.date()

    # travel to next week and see whats active
    with freeze_time(end_of_month_date + timedelta(days=2)):
        next_week_statement_settings = StatementSettingsModel.find_active_settings(
            payment_account.auth_account_id, datetime.today())
        assert next_week_statement_settings is not None
        assert next_week_statement_settings.frequency == StatementFrequency.WEEKLY.value
        assert next_week_statement_settings.to_date is None
Exemple #5
0
    def _create_statement_records(cls, current_time, search_filter,
                                  statement_settings):
        statement_from = None
        statement_to = None
        if search_filter.get('dateFilter', None):
            statement_from = parse(
                search_filter.get('dateFilter').get('startDate'))
            statement_to = parse(
                search_filter.get('dateFilter').get('endDate'))
        elif search_filter.get('weekFilter', None):
            index = search_filter.get('weekFilter').get('index')
            statement_from, statement_to = get_week_start_and_end_date(index)
        elif search_filter.get('monthFilter', None):
            statement_from, statement_to = get_first_and_last_dates_of_month(
                search_filter.get('monthFilter').get('month'),
                search_filter.get('monthFilter').get('year'))
        for setting, pay_account in statement_settings:
            statement = StatementModel(
                frequency=setting.frequency,
                statement_settings_id=setting.id,
                payment_account_id=pay_account.id,
                created_on=current_time,
                from_date=statement_from,
                to_date=statement_to,
                notification_status_code=NotificationStatus.PENDING.value
                if pay_account.statement_notification_enabled is True else
                NotificationStatus.SKIP.value)
            # Add to DB session
            statement = statement.flush()

            purchases, total = PaymentModel.search_purchase_history(
                auth_account_id=pay_account.auth_account_id,
                return_all=True,
                search_filter=search_filter,
                page=None,
                limit=None)
            for purchase in purchases:
                invoice = purchase[1]
                statement_invoice = StatementInvoicesModel(
                    statement_id=statement.id, invoice_id=invoice.id)
                db.session.add(statement_invoice)
Exemple #6
0
    def search_purchase_history(cls,  # pylint:disable=too-many-arguments, too-many-locals, too-many-branches
                                auth_account_id: str, search_filter: Dict,
                                page: int, limit: int, return_all: bool, max_no_records: int = 0):
        """Search for purchase history."""
        # Payment Account Sub Query
        payment_account_sub_query = db.session.query(PaymentAccount).filter(
            PaymentAccount.auth_account_id == auth_account_id).subquery('pay_accnt')

        query = db.session.query(Payment, Invoice) \
            .join(Invoice) \
            .outerjoin(CreditPaymentAccount) \
            .outerjoin(BcolPaymentAccount) \
            .outerjoin(InternalPaymentAccount) \
            .filter(or_(InternalPaymentAccount.account_id == payment_account_sub_query.c.id,
                        BcolPaymentAccount.account_id == payment_account_sub_query.c.id,
                        CreditPaymentAccount.account_id == payment_account_sub_query.c.id))

        if search_filter.get('status', None):
            query = query.filter(Payment.payment_status_code == search_filter.get('status'))
        if search_filter.get('folioNumber', None):
            query = query.filter(Invoice.folio_number == search_filter.get('folioNumber'))
        if search_filter.get('businessIdentifier', None):
            query = query.filter(Invoice.business_identifier == search_filter.get('businessIdentifier'))
        if search_filter.get('createdBy', None):  # pylint: disable=no-member
            query = query.filter(
                Payment.created_name.like('%' + search_filter.get('createdBy') + '%'))  # pylint: disable=no-member

        # Find start and end dates
        created_from: datetime = None
        created_to: datetime = None
        if get_str_by_path(search_filter, 'dateFilter/startDate'):
            created_from = datetime.strptime(get_str_by_path(search_filter, 'dateFilter/startDate'), '%m/%d/%Y')
        if get_str_by_path(search_filter, 'dateFilter/endDate'):
            created_to = datetime.strptime(get_str_by_path(search_filter, 'dateFilter/endDate'), '%m/%d/%Y')
        if get_str_by_path(search_filter, 'weekFilter/index'):
            created_from, created_to = get_week_start_and_end_date(
                int(get_str_by_path(search_filter, 'weekFilter/index')))
        if get_str_by_path(search_filter, 'monthFilter/month') and get_str_by_path(search_filter, 'monthFilter/year'):
            month = int(get_str_by_path(search_filter, 'monthFilter/month'))
            year = int(get_str_by_path(search_filter, 'monthFilter/year'))
            created_from, created_to = get_first_and_last_dates_of_month(month=month, year=year)

        if created_from and created_to:
            # Truncate time for from date and add max time for to date
            tz_name = current_app.config['LEGISLATIVE_TIMEZONE']
            tz_local = pytz.timezone(tz_name)

            created_from = created_from.replace(hour=0, minute=0, second=0, microsecond=0).astimezone(tz_local)
            created_to = created_to.replace(hour=23, minute=59, second=59, microsecond=999999).astimezone(tz_local)
            query = query.filter(
                func.timezone(tz_name, func.timezone('UTC', Payment.created_on)).between(created_from, created_to))

        # Add ordering
        query = query.order_by(Payment.created_on.desc())

        if not return_all:
            # Add pagination
            pagination = query.paginate(per_page=limit, page=page)
            result, count = pagination.items, pagination.total
            # If maximum number of records is provided, return it as total
            if max_no_records > 0:
                count = max_no_records if max_no_records < count else count
        else:
            # If maximum number of records is provided, set the page with that number
            if max_no_records > 0:
                pagination = query.paginate(per_page=max_no_records, page=1)
                result, count = pagination.items, max_no_records
            else:
                result = query.all()
                count = len(result)

        return result, count
Exemple #7
0
    def search_purchase_history(
            cls,  # pylint:disable=too-many-arguments, too-many-locals, too-many-branches
            auth_account_id: str,
            search_filter: Dict,
            page: int,
            limit: int,
            return_all: bool,
            max_no_records: int = 0,
            **kwargs):
        """Search for purchase history."""
        user: UserContext = kwargs['user']
        product_code = user.product_code

        query = db.session.query(Invoice) \
            .outerjoin(PaymentAccount, Invoice.payment_account_id == PaymentAccount.id) \
            .filter(PaymentAccount.auth_account_id == auth_account_id)
        # If a product code is present in token (service account), then filter only that product's invoices.
        if product_code:
            query = query.join(CorpType, CorpType.code == Invoice.corp_type_code)\
                .filter(CorpType.product == product_code)
        if search_filter.get('status', None):
            query = query.filter(
                Invoice.invoice_status_code == search_filter.get('status'))
        if search_filter.get('folioNumber', None):
            query = query.filter(
                Invoice.folio_number == search_filter.get('folioNumber'))
        if search_filter.get('businessIdentifier', None):
            query = query.filter(Invoice.business_identifier ==
                                 search_filter.get('businessIdentifier'))
        if search_filter.get('createdBy', None):  # pylint: disable=no-member
            query = query.filter(
                Invoice.created_name.ilike('%' +
                                           search_filter.get('createdBy') +
                                           '%'))  # pylint: disable=no-member

        # Find start and end dates
        created_from: datetime = None
        created_to: datetime = None
        if get_str_by_path(search_filter, 'dateFilter/startDate'):
            created_from = datetime.strptime(
                get_str_by_path(search_filter, 'dateFilter/startDate'),
                DT_SHORT_FORMAT)
        if get_str_by_path(search_filter, 'dateFilter/endDate'):
            created_to = datetime.strptime(
                get_str_by_path(search_filter, 'dateFilter/endDate'),
                DT_SHORT_FORMAT)
        if get_str_by_path(search_filter, 'weekFilter/index'):
            created_from, created_to = get_week_start_and_end_date(
                int(get_str_by_path(search_filter, 'weekFilter/index')))
        if get_str_by_path(search_filter,
                           'monthFilter/month') and get_str_by_path(
                               search_filter, 'monthFilter/year'):
            month = int(get_str_by_path(search_filter, 'monthFilter/month'))
            year = int(get_str_by_path(search_filter, 'monthFilter/year'))
            created_from, created_to = get_first_and_last_dates_of_month(
                month=month, year=year)

        if created_from and created_to:
            # Truncate time for from date and add max time for to date
            tz_name = current_app.config['LEGISLATIVE_TIMEZONE']
            tz_local = pytz.timezone(tz_name)

            created_from = created_from.replace(
                hour=0, minute=0, second=0, microsecond=0).astimezone(tz_local)
            created_to = created_to.replace(
                hour=23, minute=59, second=59,
                microsecond=999999).astimezone(tz_local)
            query = query.filter(
                func.timezone(tz_name,
                              func.timezone('UTC',
                                            Invoice.created_on)).between(
                                                created_from, created_to))

        # Add ordering
        query = query.order_by(Invoice.created_on.desc())

        if not return_all:
            # Add pagination
            pagination = query.paginate(per_page=limit, page=page)
            result, count = pagination.items, pagination.total
            # If maximum number of records is provided, return it as total
            if max_no_records > 0:
                count = max_no_records if max_no_records < count else count
        else:
            # If maximum number of records is provided, set the page with that number
            if max_no_records > 0:
                pagination = query.paginate(per_page=max_no_records, page=1)
                result, count = pagination.items, max_no_records
            else:
                result = query.all()
                count = len(result)

        return result, count