"""Logic for Payment Hold.""" from datetime import datetime import logging from owsresponse import response import tzlocal from abacus_account import models from abacus_account.config import Config from abacus_account.constants.error import ( ERROR_INVALID_HOLD_STATUS_REASON, ERROR_INVALID_START_DATE) from abacus_account.schemas import PaymentHoldSchema logger = logging.getLogger(Config.LOGGER_NAME) schema = PaymentHoldSchema() def create_or_update_payment_hold(**params): """Create or update a account's payment hold.""" account = models.Account.get_by_id_or_error(params.get('account_id')) start_date = params.get('start_date') today = datetime.now(tz=tzlocal.get_localzone()) if start_date < today.date(): message = ERROR_INVALID_START_DATE.format( start_date=start_date.strftime('%Y-%m-%d'), today=today.strftime('%Y-%m-%d'), tz=today.strftime('%Z%z'), ) logger.error(message) return response.create_error_response(code='error', status=400, message=message) if account.payment_hold: return update_payment_hold(account.payment_hold, **params) new_hold = models.PaymentHold.create(**params) return response.Response(message=schema.dump(new_hold), status=201) def get_payment_hold(account_id): """Retrieve payment hold info for the specified account.""" account_obj = models.Account.get_by_id_or_error(account_id) return response.Response(message=schema.dump(account_obj.payment_hold), status=200) def get_payment_holds(limit, offset, account_ids=None): """Retrieve payment holds with optional account filter.""" items, total_count = models.PaymentHold.get_filtered_items( limit=limit, offset=offset, account_ids=account_ids, ) return response.Response( { 'items': schema.dump(items, many=True), 'total_count': total_count, } ) def update_payment_hold(current_payment_hold, **params): """Update specified payment hold.""" is_on_hold, reason = params.get('is_on_hold'), params.get('reason') if ( current_payment_hold.is_on_hold == is_on_hold and current_payment_hold.reason == reason ): status = 'on hold' if is_on_hold else 'active' return response.create_error_response( code='error', message=ERROR_INVALID_HOLD_STATUS_REASON.format( hold_status=status, reason=reason), status=400 ) current_payment_hold.update_attributes(**params) current_payment_hold.commit_changes() return response.Response( message=schema.dump(current_payment_hold), status=201 )