"""Contract Mechanical Deduction handlers.""" from datetime import datetime from abacus_common_logic.constants.error import ERROR_ENTITY_DOES_NOT_EXIST from abacus_common_logic.utils.authorization import permissions_authorize_many_accounts from abacus_common_logic.views.create_view import CreateView from abacus_common_logic.views.item_view import ItemView from abacus_common_logic.views.validations import validated_request_body from flask import Blueprint, g, request from owsrequest import flask_request from owsresponse import response from owsresponse.adaptors.flask import flaskify from abacus_contract.config import ows_client from abacus_contract.constants.error import \ ERROR_CODE_AUTHORIZATION, \ ERROR_CODE_FORBIDDEN, \ ERROR_INVALID_DATE, \ ERROR_MESSAGE_FORBIDDEN_USER from abacus_contract.logic import contract_mechanical_deduction as logic from abacus_contract.models import ContractMechanicalDeduction from abacus_contract.schemas.contract_mechanical_deduction \ import ContractMechanicalDeductionDetailSchema from abacus_contract.schemas.contract_mechanical_deduction \ import ContractMechanicalDeductionPostSchema from abacus_contract.schemas.contract_mechanical_deduction \ import ContractMechanicalDeductionPutSchema from abacus_contract.schemas.contract_mechanical_deduction \ import ContractWorldWideMechanicalDeductionPostSchema from abacus_contract.utils.authorization import pdp_authorize_many_accounts from abacus_contract.utils.format_error import validation_error contract_mechanical_deduction_api = \ Blueprint('contract_mechanical_deduction_api', __name__) class ContractMechanicalDeductionItemView(ItemView): """View for finding contract_mechanical_deduction by ID.""" model_class = ContractMechanicalDeduction put_schema = ContractMechanicalDeductionPutSchema() object_detail_schema = ContractMechanicalDeductionDetailSchema() def get(self, object_id): """Find object by its id or return an error.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify(response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, )) obj = self.model_class.get_by_id(object_id) if not obj or obj.deleted_at is not None or obj.deleted_by is not None: return flaskify(response.create_not_found_response( message=ERROR_ENTITY_DOES_NOT_EXIST.format( object_type='Contract Mechanical Deduction', object_id=object_id ) )) body = self.object_detail_schema.dump(obj) return flaskify(response.Response(message=body, status=200)) def put(self, object_id, **kwargs): """Update contract_mechanical_deductrion 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_CODE_AUTHORIZATION, message='Unauthorized', status=401, )) return super().put(object_id, **kwargs) def update_handler(self, obj, **params): """Handle contract_mechanical_deduction updates.""" return logic.update_contract_mechanical_deduction(obj, **params) def delete(self, object_id): """Delete a contract_mechanical_deduction.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify(response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, )) obj = self.model_class.get_by_id_or_error(object_id, 404) return flaskify(logic.soft_delete_contract_mechanical_deduction(obj)) class ContractMechanicalDeductionCreateView(CreateView): """Handles contract_mechanical_deduction creation.""" post_schema = ContractMechanicalDeductionPostSchema() def post(self, **kwargs): """Create a contract_mechanical_deduction.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify(response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, )) return super().post(**kwargs) def create_handler(self, **params): """Create a contract_mechanical_deduction.""" return logic.create_contract_mechanical_deduction(**params) contract_mechanical_deduction_api.add_url_rule( '/contract-mechanical-deduction/', methods=['GET', 'PUT', 'DELETE'], view_func=ContractMechanicalDeductionItemView.as_view( 'contract_mechanical_deduction' ) ) contract_mechanical_deduction_api.add_url_rule( '/contract//contract-mechanical-deduction/', view_func=ContractMechanicalDeductionCreateView.as_view( 'create_contract_mechanical_deduction' ) ) @contract_mechanical_deduction_api.route( '/contract//contract-mechanical-deductions/', methods=['GET'] ) def get_contract_mechanical_deductions_by_contract_id( contract_id: int ): """Get list of contract mechanical deductions for specified contract_id. Arg: contract_id(int): id of the contract """ (res, contract) = logic.get_contract_mechanical_deductions_by_contract_id( contract_id ) access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: authorized = pdp_authorize_many_accounts([contract.account_id]) if not authorized: return flaskify(response.create_error_response( code=ERROR_CODE_FORBIDDEN, message=ERROR_MESSAGE_FORBIDDEN_USER, status=403 )) account_access = permissions_authorize_many_accounts( ows_client, g.request_context.profile_type, g.request_context.profile_id, [contract.account_id] ) if not account_access: return flaskify(response.create_error_response( code=ERROR_CODE_FORBIDDEN, message=ERROR_MESSAGE_FORBIDDEN_USER, status=403 )) return flaskify(res) @contract_mechanical_deduction_api.route( '/contract//contract-mechanical-deductions/worldwide/', methods=['POST'] ) def create_contract_mechanical_deductions_worldwide( contract_id: int ): """Create contract mechanical deductions worldwide for specified contract_id. Arg: contract_id(int): id of the contract """ access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify(response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, )) post_request_body = validated_request_body( ContractWorldWideMechanicalDeductionPostSchema() ) return flaskify( logic.create_contract_mechanical_deductions_worldwide( contract_id, **post_request_body ) ) @contract_mechanical_deduction_api.route( '/contracts/mechanical-deductions/active', methods=['GET'] ) def get_active_contracts_with_mechanical_deductions(): """Get active contracts with mechanical deductions by date.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify(response.create_error_response( code=ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, )) date = request.args.get('date') or datetime.now().strftime('%Y-%m-%d') try: date = datetime.strptime(date, '%Y-%m-%d').date() except ValueError: return flaskify(validation_error(ERROR_INVALID_DATE)) return flaskify(logic.get_active_contracts_with_mechanical_deductions(date))