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
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
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
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)
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
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