"""Blueprint for accounting period API.""" from abacus_common_logic.views.create_view import CreateView from abacus_common_logic.views.item_view import ItemView from abacus_common_logic.views.list_view import ListView from flask import Blueprint, request from owsrequest import flask_request from owsresponse import response from owsresponse.adaptors.flask import flaskify from royalties.constants import error from royalties.logic import ( accounting_period as logic, accounting_period_search as search_logic, ) from royalties.models import AccountingPeriod, AccountingRun from royalties.schemas import ( AccountingPeriodDetailSchema, AccountingPeriodPostSchema, AccountingPeriodPutSchema, AccountingPeriodSalesFileSchema, AccountingRunSchema, ) from royalties.utils import authorization accounting_period_api = Blueprint('accounting_period_api', __name__) class AccountingPeriodCreateView(CreateView): """Handles accounting period creation.""" post_schema = AccountingPeriodPostSchema() def post(self, **kwargs): """Create accounting period.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) return super().post(**kwargs) def create_handler(self, **params): """Create accounting period.""" return logic.create_accounting_period(**params) class AccountingPeriodList(ListView): """View for listing accounting periods.""" model_class = AccountingPeriod list_entry_schema = AccountingPeriodDetailSchema() def get(self): """Get Accounting Period List.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) try: return flaskify(search_logic.get_accounting_periods(request.args)) except Exception as err: return flaskify( response.create_error_response('error', str(err), status=400) ) class AccountingPeriodItemView(ItemView): """View for finding an accounting period by ID.""" model_class = AccountingPeriod object_detail_schema = AccountingPeriodDetailSchema() put_schema = AccountingPeriodPutSchema() def get(self, object_id, **kwargs): """Find accounting period by its id or return an error.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: # This resource type is all-or-nothing, permissions-wise, # so id doesn't matter authorized = authorization.pdp_authorize_resource( resource_id=0, resource_type='accounting_period', ) if not authorized: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, status=403, ) ) return super().get(object_id, **kwargs) def update_handler(self, obj, **params): """Handle accounting period updates.""" return logic.update_accounting_period(obj, **params) def put(self, object_id, **kwargs): """Update an accounting period by ID.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) return super().put(object_id, **kwargs) class AccountingPeriodSalesFilesListView(ItemView): """View for finding sales files for an accounting period by ID.""" model_class = AccountingPeriod def get(self, object_id): """Build a formatted list of sales files for the period.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) period = AccountingPeriod.get_by_id_or_error(object_id) return flaskify( response.Response( AccountingPeriodSalesFileSchema().dump(period.sales_files, many=True) ) ) class AccountingRunList(ListView): """View for listing accounting runs by accounting period id.""" model_class = AccountingPeriod def get(self, object_id): """Get paginated list of accounting run's.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) query = AccountingRun.get_page(object_id) items = query.all() count = query.count() results = AccountingRunSchema().dump(items, many=True) return flaskify(response.Response({'items': results, 'total_count': count})) accounting_period_api.add_url_rule( '/accounting-period', methods=['POST'], view_func=AccountingPeriodCreateView.as_view('create_accounting_period'), ) accounting_period_api.add_url_rule( '/accounting-periods', methods=['GET'], view_func=AccountingPeriodList.as_view('list_accounting_periods'), ) accounting_period_api.add_url_rule( '/accounting-period/', methods=['GET', 'PUT'], view_func=AccountingPeriodItemView.as_view('accounting_period'), ) accounting_period_api.add_url_rule( '/accounting-period//sales-files', methods=['GET'], view_func=AccountingPeriodSalesFilesListView.as_view( 'accounting_period_list_sales_files' ), ) accounting_period_api.add_url_rule( '/accounting-period//accounting-runs', methods=['GET'], view_func=AccountingRunList.as_view('list_accounting_runs'), ) @accounting_period_api.route( '/accounting-run//accounting-period', methods=['GET'] ) def get_accounting_period_by_accounting_run_id(object_id): """Endpoint to get accounting_period from accounting_run.accounting_period_id.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) return flaskify(logic.get_accounting_period_by_accounting_run(object_id))