"""Release Approval Queue Model.""" import datetime from oto import response, status from sqlalchemy import Column from sqlalchemy import DateTime from sqlalchemy import Enum from sqlalchemy import ForeignKey from sqlalchemy import Integer from sqlalchemy.orm import relationship from product_workflow.connectors import mysql from product_workflow.constants import error from product_workflow.constants import release_approval_queue_status as raqs from product_workflow.constants import release_correction_status as rcs from product_workflow.models import release_correction as rc class ReleaseApprovalQueue(mysql.BaseModel): """Model for release approval queue.""" __tablename__ = 'release_approval_queue' release_approval_id = Column( Integer, primary_key=True, autoincrement=True, nullable=False) release_id = Column(Integer, nullable=False) release_correction_id = Column( Integer, ForeignKey('release_correction.release_correction_id'), default=None, nullable=True ) status = Column( Enum(raqs.APPROVED, raqs.CHECKED_OUT, raqs.CHECKED_IN, raqs.REJECTED), nullable=False) checked_out_by = Column(Integer) admin_approval = Column(Enum('N', 'Y')) date_submitted = Column(DateTime, nullable=False) last_updated = Column(DateTime, nullable=False) rejection_notes = relationship( 'RejectionNote', cascade='delete', lazy='joined') def to_dict(self): """Format the properties of this approval queue object as a dict.""" return { 'release_approval_id': self.release_approval_id, 'release_correction_id': self.release_correction_id, 'release_id': self.release_id, 'status': self.status, 'checked_out_by': self.checked_out_by} @mysql.wrap_db_errors def create(column_data): """Create a new release approval queue record. :param column_data: Column data to insert for the record. :return: Response containing the created release approval queue data. """ release_approval_queue = ReleaseApprovalQueue( release_id=column_data.get('release_id'), release_correction_id=column_data.get('release_correction_id'), status=column_data.get('status'), admin_approval=column_data.get('admin_approval'), last_updated=datetime.datetime.now(), date_submitted=datetime.datetime.now() ) with mysql.db_session() as session: session.add(release_approval_queue) session.flush() return response.Response( message=release_approval_queue.to_dict(), status=201 ) def _get_lates_approval_query(release_id, session): """Return the latest approval queue.""" return session.query(ReleaseApprovalQueue).filter_by(release_id=release_id).order_by( ReleaseApprovalQueue.release_approval_id.desc()).first() @mysql.wrap_db_errors def get_last_approval(release_id): """Get the most recent approval record for the given release.""" with mysql.db_session() as session: approval = _get_lates_approval_query(release_id, session) if not approval: return response.create_not_found_response( message='no release approval record found') return response.Response(message=approval.to_dict()) @mysql.wrap_db_errors def delete_release_approval_queue(approval): """Delete a release_approval_queue record.""" with mysql.db_session() as session: session.delete(approval) return response.Response( message=dict(message='release approval deleted'), status=202 ) def get_approval_for_correction(session, release_correction_id): """Get release_approval_queue record for a given release_correction_id.""" return session.query(ReleaseApprovalQueue).filter_by( release_correction_id=release_correction_id).first() @mysql.wrap_db_errors def delete_latest_release_approval_queue(product_id, account_id, account_type): """Delete the latest release approval queue part of unsubmitting products. Args: product_id (int): id of the product to fetch account_id (int): the user account id in the header. account_type (str): correlation id for logs """ with mysql.db_session() as session: approval = _get_lates_approval_query(product_id, session) if not approval: return response.create_not_found_response( message=error.ERROR_MESSAGE_PRODUCT_APPROVAL_NOT_FOUND.format(product_id)) elif approval.status != raqs.CHECKED_IN: return response.create_error_response( code=error.ERROR_CODE_BAD_REQUEST, status=400, message=error.ERROR_MESSAGE_PRODUCT_NOT_CHECKED_IN.format(product_id)) correction = None if approval.release_correction_id: correction = rc.get_correction_object(session, approval.release_correction_id) session.delete(approval) if correction: correction.status = rcs.ACTIVE correction.last_updated = datetime.datetime.now() correction.last_updated_by = account_id correction.last_updated_type = account_type return response.Response( message={'message': 'release approval deleted'}, status=status.OK )