Skip to content

Commit

Permalink
Merge branch 'develop' into work_modal
Browse files Browse the repository at this point in the history
  • Loading branch information
tom0827 committed Oct 23, 2023
2 parents 7971a79 + 048007b commit e599675
Show file tree
Hide file tree
Showing 63 changed files with 1,838 additions and 20,037 deletions.
2 changes: 1 addition & 1 deletion epictrack-api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ tag: push ## tag image
# COMMANDS - Local #
#################################################################################
run: ## Run the project in local
. venv/bin/activate && python -m flask run -p 5000
. venv/bin/activate && python -m flask run -p 3200

#################################################################################
# Self Documenting Commands #
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""added notes and pip fields to indigenous nations.
Revision ID: 7deec389ae56
Revises: d8b405f9d663
Create Date: 2023-10-18 11:46:46.577009
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '7deec389ae56'
down_revision = 'd8b405f9d663'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('indigenous_nations', schema=None) as batch_op:
batch_op.add_column(sa.Column('notes', sa.String(), nullable=True))
batch_op.add_column(sa.Column('pip_org_type_id', sa.Integer(), nullable=True))
batch_op.create_foreign_key(None, 'pip_org_types', ['pip_org_type_id'], ['id'])

with op.batch_alter_table('indigenous_nations_history', schema=None) as batch_op:
batch_op.add_column(sa.Column('notes', sa.String(), autoincrement=False, nullable=True))
batch_op.add_column(sa.Column('pip_org_type_id', sa.Integer(), autoincrement=False, nullable=True))
batch_op.create_foreign_key(None, 'pip_org_types', ['pip_org_type_id'], ['id'])

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('indigenous_nations_history', schema=None) as batch_op:
batch_op.drop_constraint(None, type_='foreignkey')
batch_op.drop_column('pip_org_type_id')
batch_op.drop_column('notes')

with op.batch_alter_table('indigenous_nations', schema=None) as batch_op:
batch_op.drop_constraint(None, type_='foreignkey')
batch_op.drop_column('pip_org_type_id')
batch_op.drop_column('notes')

# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""create pip_org_type table
Revision ID: d8b405f9d663
Revises: 47b41964f6df
Create Date: 2023-10-18 11:45:36.531064
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = 'd8b405f9d663'
down_revision = '47b41964f6df'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
pip_org_type = op.create_table('pip_org_types',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('created_by', sa.String(length=255), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text("TIMEZONE('utc', CURRENT_TIMESTAMP)"), nullable=True),
sa.Column('updated_by', sa.String(length=255), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('is_active', sa.Boolean(), server_default='t', nullable=False),
sa.Column('is_deleted', sa.Boolean(), server_default='f', nullable=False),
sa.PrimaryKeyConstraint('id'),
sqlite_autoincrement=True
)
op.create_table('pip_org_types_history',
sa.Column('id', sa.Integer(), autoincrement=False, nullable=False),
sa.Column('name', sa.String(), autoincrement=False, nullable=False),
sa.Column('created_by', sa.String(length=255), autoincrement=False, nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), autoincrement=False, nullable=True),
sa.Column('updated_by', sa.String(length=255), autoincrement=False, nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), autoincrement=False, nullable=True),
sa.Column('is_active', sa.Boolean(), autoincrement=False, nullable=False),
sa.Column('is_deleted', sa.Boolean(), autoincrement=False, nullable=False),
sa.Column('pk', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('during', postgresql.TSTZRANGE(), nullable=True),
sa.PrimaryKeyConstraint('id', 'pk'),
sqlite_autoincrement=True
)
op.bulk_insert(pip_org_type,
[
{
"name": "Clan"
},
{
"name": "First Nation"
},
{
"name": "First Nation Group"
},
{
"name": "House"
},
{
"name": "Keyoh"
},
{
"name": "Metis"
},
{
"name": "Tribal Council"
},
{
"name": "Wilp"
}
])
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('pip_org_types_history')
op.drop_table('pip_org_types')
# ### end Alembic commands ###
4 changes: 1 addition & 3 deletions epictrack-api/src/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@

from api import config
from api.config import _Config
from api.exceptions import (
PermissionDeniedError, ResourceExistsError, ResourceNotFoundError, UnprocessableEntityError)
from api.exceptions import PermissionDeniedError, ResourceExistsError, ResourceNotFoundError, UnprocessableEntityError
from api.models import db
from api.utils.auth import jwt
from api.utils.caching import AppCache
Expand All @@ -48,7 +47,6 @@ def create_app(run_mode=os.getenv('FLASK_ENV', 'production')):
db.init_app(app)

if run_mode != 'migration':

AppCache.configure_cache(run_mode, app)
# pylint: disable=import-outside-toplevel
from api.resources import API_BLUEPRINT, OPS_BLUEPRINT
Expand Down
1 change: 1 addition & 0 deletions epictrack-api/src/api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,4 @@
from .action_configuration import ActionCofiguration
from .task_event_responsibility import TaskEventResponsibility
from .act_section import ActSection
from .pip_org_type import PIPOrgType
6 changes: 6 additions & 0 deletions epictrack-api/src/api/models/indigenous_nation.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class IndigenousNation(db.Model, CodeTableVersioned):
name = Column(String(255), nullable=False)
is_active = Column(Boolean, default=True, nullable=False)
pip_link = Column(URLType, default=None, nullable=True)
notes = Column(String)

relationship_holder_id = Column(
ForeignKey("staffs.id"), nullable=True, default=None
Expand All @@ -38,6 +39,11 @@ class IndigenousNation(db.Model, CodeTableVersioned):
"Staff", foreign_keys=[relationship_holder_id], lazy="select"
)

pip_org_type_id = Column(ForeignKey("pip_org_types.id"))
pip_org_type = relationship(
"PIPOrgType", foreign_keys=[pip_org_type_id], lazy="select"
)

def as_dict(self):
"""Return JSON Representation."""
result = CodeTableVersioned.as_dict(self)
Expand Down
28 changes: 28 additions & 0 deletions epictrack-api/src/api/models/pip_org_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright © 2019 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Model to handle all operations related to PIP Organization Types."""

from sqlalchemy import Column, Integer, String

from .code_table import CodeTableVersioned
from .db import db


class PIPOrgType(db.Model, CodeTableVersioned):
"""Model class for PIP Organization Types."""

__tablename__ = 'pip_org_types'

id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(), nullable=False)
7 changes: 5 additions & 2 deletions epictrack-api/src/api/models/staff.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,12 @@ def find_all_active_staff(cls):
return cls.query.filter_by(is_active=True, is_deleted=False)

@classmethod
def find_all_non_deleted_staff(cls):
def find_all_non_deleted_staff(cls, is_active=False):
"""Return all non-deleted staff"""
return cls.query.filter_by(is_deleted=False)
query = {"is_deleted": False}
if is_active:
query["is_active"] = is_active
return cls.query.filter_by(**query)

@classmethod
def check_existence(cls, email, staff_id):
Expand Down
2 changes: 1 addition & 1 deletion epictrack-api/src/api/resources/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get(event_id):
def delete(event_id):
"""Endpoint to delete a milestone event"""
req.MilestoneEventPathParameterSchema().load(request.view_args)
message = EventService.delete_milestone(event_id)
message = EventService.delete_event(event_id)
return message, HTTPStatus.OK


Expand Down
4 changes: 3 additions & 1 deletion epictrack-api/src/api/resources/indigenous_nation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.
"""Resource for indigenous nation endpoints."""
from http import HTTPStatus

from flask import jsonify, request
from flask_restx import Namespace, Resource, cors

Expand Down Expand Up @@ -99,7 +100,8 @@ class IndigenousNations(Resource):
@profiletime
def get():
"""Return all indigenous nations."""
indigenous_nations = IndigenousNationService.find_all_indigenous_nations()
args = req.BasicRequestQueryParameterSchema().load(request.args)
indigenous_nations = IndigenousNationService.find_all_indigenous_nations(args.get("is_active"))
return jsonify(res.IndigenousResponseNationSchema(many=True).dump(indigenous_nations)), HTTPStatus.OK

@staticmethod
Expand Down
3 changes: 2 additions & 1 deletion epictrack-api/src/api/resources/staff.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ def get():
current_app.logger.info('Getting staffs')
args = req.StaffByPositionsQueryParamSchema().load(request.args)
positions = args.get('positions')
is_active = args.get('is_active')
if not positions:
staffs = StaffService.find_all_non_deleted_staff()
staffs = StaffService.find_all_non_deleted_staff(is_active)
if positions:
current_app.logger.info(f'Position ids are {positions}')
staffs = StaffService.find_by_position_ids(positions)
Expand Down
8 changes: 7 additions & 1 deletion epictrack-api/src/api/schemas/request/event_request.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Event resource's input validations"""
from marshmallow import fields, validate
from marshmallow import fields, validate, pre_load

from api.schemas.request.custom_fields import IntegerList

Expand Down Expand Up @@ -87,6 +87,12 @@ class MilestoneEventBodyParameterSchema(RequestBodyParameterSchema):
allow_none=True
)

@pre_load
def translate_empty_date_strings(self, data, *args, **kwargs): # pylint: disable=unused-argument
"""Translate empty date string to None"""
data['actual_date'] = data.get('actual_date') or None
return data


class MilestoneEventPathParameterSchema(RequestPathParameterSchema):
"""Milestone event path parameter schema"""
Expand Down
18 changes: 18 additions & 0 deletions epictrack-api/src/api/schemas/request/indigenous_nation_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,24 @@ class IndigenousNationBodyParameterSchema(RequestBodyParameterSchema):
is_active = fields.Bool(
metadata={"description": "Active state of the indigenous nation"})

notes = fields.Str(
metadata={"description": "Notes for the indigenous nation"},
allow_none=True
)

pip_org_type_id = fields.Int(
metadata={"description": "PIP organization type for the indigenous nation"},
validate=validate.Range(min=1),
allow_none=True,
missing=None
)

pip_link = fields.Str(
metadata={"description": "PIP site URL for indigenous nation"},
allow_none=True,
missing=None
)


class IndigenousNationExistenceQueryParamSchema(RequestQueryParameterSchema):
"""IndigenousNation existance check query parameters"""
Expand Down
6 changes: 4 additions & 2 deletions epictrack-api/src/api/schemas/request/staff_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

from api.schemas.validators import Phone

from .base import RequestBodyParameterSchema, RequestPathParameterSchema, RequestQueryParameterSchema
from .base import (
BasicRequestQueryParameterSchema, RequestBodyParameterSchema, RequestPathParameterSchema,
RequestQueryParameterSchema)
from .custom_fields import IntegerList


Expand Down Expand Up @@ -46,7 +48,7 @@ class StaffExistanceQueryParamSchema(RequestQueryParameterSchema):
)


class StaffByPositionsQueryParamSchema(RequestQueryParameterSchema):
class StaffByPositionsQueryParamSchema(BasicRequestQueryParameterSchema):
"""Staff by positions query parameter"""

positions = IntegerList(metadata={"description": "comma separated position ids"})
Expand Down
9 changes: 7 additions & 2 deletions epictrack-api/src/api/services/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,10 +539,15 @@ def bulk_delete_milestones(cls, milestone_ids: List):
return "Deleted successfully"

@classmethod
def delete_milestone(cls, milestone_id: int):
def delete_event(cls, event_id: int):
"""Mark milestone as deleted by id"""
event = Event.find_by_id(event_id)
if not event:
raise ResourceNotFoundError("No event found with given id")
if event.actual_date:
raise UnprocessableEntityError("Locked events cannot be deleted")
db.session.query(Event).filter(
or_(Event.id == milestone_id, Event.source_event_id == milestone_id)
or_(Event.id == event_id, Event.source_event_id == event_id)
).update({"is_active": False, "is_deleted": True})
db.session.commit()
return "Deleted successfully"
4 changes: 2 additions & 2 deletions epictrack-api/src/api/services/indigenous_nation.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def check_existence(cls, name, indigenous_nation_id=None):
return IndigenousNation.check_existence(name, indigenous_nation_id)

@classmethod
def find_all_indigenous_nations(cls):
def find_all_indigenous_nations(cls, is_active):
"""Find all active indigenous nations"""
indigenous_nations = IndigenousNation.find_all(default_filters=False)
indigenous_nations = IndigenousNation.find_all(default_filters=is_active)
return indigenous_nations

@classmethod
Expand Down
6 changes: 3 additions & 3 deletions epictrack-api/src/api/services/staff.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"""Service to manage Staffs."""

from flask import current_app
from api.exceptions import ResourceExistsError, ResourceNotFoundError

from api.exceptions import ResourceExistsError, ResourceNotFoundError
from api.models import Staff
from api.schemas.response import StaffResponseSchema

Expand Down Expand Up @@ -48,9 +48,9 @@ def find_all_active_staff(cls):
return response

@classmethod
def find_all_non_deleted_staff(cls):
def find_all_non_deleted_staff(cls, is_active=False):
"""Find all non-deleted staff"""
staffs = Staff.find_all_non_deleted_staff()
staffs = Staff.find_all_non_deleted_staff(is_active)
return staffs

@classmethod
Expand Down
1 change: 0 additions & 1 deletion epictrack-api/src/api/services/work.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,6 @@ def import_first_nations(cls, work_id: int, indigenous_nation_ids: [int]):
)

# Mark removed entries as inactive
# TODO:CHECK THIS LOGIC
disabled_count = existing_first_nations_qry.filter(
IndigenousWork.is_active.is_(True),
IndigenousWork.indigenous_nation_id.notin_(indigenous_nation_ids),
Expand Down
Loading

0 comments on commit e599675

Please sign in to comment.