Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sorting , fixed field to datetime #1195

Merged
merged 8 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""changed column type to datetime

Revision ID: 73c6150268e5
Revises: 8e4bb9cd046c
Create Date: 2023-11-08 09:44:54.419908

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '73c6150268e5'
down_revision = '8e4bb9cd046c'
branch_labels = None
depends_on = None


def upgrade():
# Change the column type to DateTime with timezone
op.alter_column('work_statuses', 'posted_date', type_=sa.DateTime(timezone=True))


def downgrade():
# If needed, revert the column type change
op.alter_column('work_statuses', 'posted_date', type_=sa.Date())
14 changes: 13 additions & 1 deletion epictrack-api/src/api/models/work_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Model to handle all operations related to Issues."""
from __future__ import annotations

from typing import List

from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
Expand All @@ -36,5 +39,14 @@ class WorkIssues(BaseModelVersioned):
work_id = Column(ForeignKey('works.id'), nullable=False)
work = relationship('Work', foreign_keys=[work_id], lazy='select')

# Define a relationship to WorkIssueUpdates
updates = relationship('WorkIssueUpdates', back_populates='work_issue', lazy='joined')

@classmethod
def list_issues_for_work_id(cls, work_id) -> List[WorkIssues]:
"""List all WorkIssues sorted by start_date, with approved issues first."""
query = (
WorkIssues.query
.filter(cls.work_id == work_id)
.order_by(cls.is_approved.desc(), cls.start_date)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grabbing your attention to this line, will this have the latest start date at the first index or the oldest? We might need to discuss to decide

)
return query.all()
12 changes: 10 additions & 2 deletions epictrack-api/src/api/models/work_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Model to handle all operations related to WorkStatus."""
from __future__ import annotations

from sqlalchemy import Boolean, Column, Date, ForeignKey, Integer, String, Text
from typing import List

from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Text, DateTime, desc
from sqlalchemy.orm import relationship

from .base_model import BaseModelVersioned
Expand All @@ -27,9 +30,14 @@ class WorkStatus(BaseModelVersioned):
id = Column(Integer, primary_key=True, autoincrement=True)
description = Column(String(2000), nullable=False)
notes = Column(Text)
posted_date = Column(Date, nullable=False)
posted_date = Column(DateTime(timezone=True), nullable=False)
posted_by = Column(String(100), nullable=True)
work_id = Column(ForeignKey('works.id'), nullable=False)
work = relationship('Work', foreign_keys=[work_id], lazy='select')
is_approved = Column(Boolean(), default=False, nullable=False)
approved_by = Column(String(255), default=None, nullable=True)

@classmethod
def list_statuses_for_work_id(cls, work_id) -> List[WorkStatus]:
"""Return all WorkStatus records for a specific work_id"""
return WorkStatus.query.filter_by(work_id=work_id).order_by(desc(WorkStatus.posted_date)).all()
16 changes: 16 additions & 0 deletions epictrack-api/src/api/resources/work_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,19 @@ def patch(work_id, status_id):
approved_work_status = WorkStatusService.approve_work_status(existing_work_status)

return res.WorkStatusResponseSchema().dump(approved_work_status), HTTPStatus.OK


@cors_preflight("PATCH")
@API.route("/<int:status_id>/notes", methods=["PATCH", "OPTIONS"])
class StatusNotes(Resource):
"""Endpoints to handle status notes"""

@staticmethod
@cors.crossdomain(origin="*")
@auth.require
@profiletime
def patch(work_id, status_id):
"""Save the notes to corresponding work"""
notes = req.WorkStatusNotesBodySchema().load(API.payload)["notes"]
work_status = WorkStatusService.save_notes(work_id, status_id, notes)
return res.WorkStatusResponseSchema().dump(work_status), HTTPStatus.OK
2 changes: 1 addition & 1 deletion epictrack-api/src/api/schemas/request/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@
WorkBodyParameterSchema, WorkExistenceQueryParamSchema, WorkFirstNationImportBodyParamSchema,
WorkFirstNationNotesBodySchema, WorkIdPathParameterSchema, WorkIdPhaseIdPathParameterSchema,
WorkPlanDownloadQueryParamSchema, WorkTypeIdQueryParamSchema, WorkStatusParameterSchema,
WorkIssuesParameterSchema, WorkIssuesUpdateSchema)
WorkIssuesParameterSchema, WorkIssuesUpdateSchema, WorkStatusNotesBodySchema)
from .act_section_request import ActSectionQueryParameterSchema
10 changes: 10 additions & 0 deletions epictrack-api/src/api/schemas/request/work_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,13 @@ class WorkIssuesUpdateSchema(WorkIssuesParameterSchema):
metadata={"description": "List of updates for the issue with IDs"},
required=False,
)


class WorkStatusNotesBodySchema(RequestBodyParameterSchema):
"""Work status notes body parameter schema"""

notes = fields.Str(
metadata={"description": "Work status notes"},
validate=validate.Length(min=1),
required=True,
)
2 changes: 1 addition & 1 deletion epictrack-api/src/api/services/work_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class WorkIssuesService: # pylint: disable=too-many-public-methods
@classmethod
def find_all_work_issues(cls, work_id):
"""Find all issues related to a work"""
work_issues = WorkIssuesModel.find_by_params({"work_id": work_id})
work_issues = WorkIssuesModel.list_issues_for_work_id(work_id)
return work_issues

@classmethod
Expand Down
15 changes: 13 additions & 2 deletions epictrack-api/src/api/services/work_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"""Service to manage Work status."""
from http import HTTPStatus
from typing import Dict

from api.exceptions import ResourceNotFoundError
from api.exceptions import BusinessError
from api.models import WorkStatus as WorkStatusModel
from api.utils import TokenInfo
Expand All @@ -28,7 +28,7 @@ class WorkStatusService: # pylint: disable=too-many-public-methods
@classmethod
def find_all_work_status(cls, work_id):
"""Find all status related to a work"""
return WorkStatusModel.find_by_params({"work_id": work_id})
return WorkStatusModel.list_statuses_for_work_id(work_id)

@classmethod
def find_work_status_by_id(cls, work_id, status_id):
Expand Down Expand Up @@ -62,6 +62,17 @@ def update_work_status(cls, work_status: WorkStatusModel, work_status_data: dict

return work_status

@classmethod
def save_notes(cls, work_id, status_id, notes: str) -> WorkStatusModel:
"""Save a work status note."""
work_status: WorkStatusModel = WorkStatusService.find_work_status_by_id(work_id, status_id)
if not work_status:
raise ResourceNotFoundError("Work status not found")
work_status.notes = notes
work_status.save()

return work_status

@classmethod
def approve_work_status(cls, work_status):
"""Approve a work status."""
Expand Down
Loading