Skip to content
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
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,26 @@
"args": ["SCAN_VIRUS", "/path/to/file"],
"console": "integratedTerminal",
"justMyCode": true
},
{
"name": "EPIC CRON - Extract Work",
"type": "debugpy",
"cwd": "${workspaceFolder}/jobs/epic-cron/",
"request": "launch",
"program": "${workspaceFolder}/jobs/epic-cron/invoke_jobs.py",
"args": ["EXTRACT_WORK"],
"console": "integratedTerminal",
"justMyCode": true
},
{
"name": "EPIC CRON - Extract Phase",
"type": "debugpy",
"cwd": "${workspaceFolder}/jobs/epic-cron/",
"request": "launch",
"program": "${workspaceFolder}/jobs/epic-cron/invoke_jobs.py",
"args": ["EXTRACT_PHASE"],
"console": "integratedTerminal",
"justMyCode": true
}
]
}
1 change: 0 additions & 1 deletion deployments/charts/epic-cron/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ data:
KEYCLOAK_BASE_URL: "{{ .Values.KEYCLOAK.baseUrl }}"
KEYCLOAK_REALM_NAME: "{{ .Values.KEYCLOAK.realmName }}"
# API URLs
TRACK_API_BASE_URL: "{{ .Values.TRACK.api.url }}"
CONDITION_API_BASE_URL: "{{ .Values.CONDITION.api.url }}"
# ClamAV configuration
CLAMAV_HOST: "{{ .Values.CLAMAV.host }}"
Expand Down
5 changes: 0 additions & 5 deletions deployments/charts/epic-cron/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,6 @@ spec:
name: {{ .Values.name }}-config
key: CONNECT_TIMEOUT

- name: TRACK_API_BASE_URL
valueFrom:
configMapKeyRef:
name: {{ .Values.name }}-config
key: TRACK_API_BASE_URL
- name: CONDITION_API_BASE_URL
valueFrom:
configMapKeyRef:
Expand Down
2 changes: 0 additions & 2 deletions deployments/charts/epic-cron/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ TRACK:
database:
host: epictrack-patroni
port: "5432"
api:
url: "https://epictrack-api-c72cba-dev.apps.gold.devops.gov.bc.ca"

CENTRE:
database:
Expand Down
1 change: 0 additions & 1 deletion jobs/epic-cron/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ class _Config(): # pylint: disable=too-few-public-methods
f"postgresql://{CONDITION_DB_USER}:{CONDITION_DB_PASSWORD}@{CONDITION_DB_HOST}:{int(CONDITION_DB_PORT)}/{CONDITION_DB_NAME}"
)

TRACK_API_BASE_URL=os.getenv('TRACK_API_BASE_URL')
CONDITION_API_BASE_URL = os.getenv("CONDITION_API_BASE_URL")
KEYCLOAK_BASE_URL = os.getenv('KEYCLOAK_BASE_URL')
KEYCLOAK_REALM_NAME = os.getenv('KEYCLOAK_REALM_NAME', 'eao-epic')
Expand Down
33 changes: 31 additions & 2 deletions jobs/epic-cron/invoke_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
import config
from tasks.project_extractor import ProjectExtractor, TargetSystem # Import the enum
from tasks.proponent_extractor import ProponentExtractor
from tasks.proponent_status_updater import ProponentStatusUpdater
from tasks.virus_scanner import VirusScanner
from tasks.submit_mail import SubmitMailer
from tasks.centre_mail import CentreMailer
from tasks.sync_approved_condition import SyncApprovedCondition
from tasks.work_extractor import WorkExtractor
from tasks.phase_extractor import PhaseExtractor

setup_logging(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'logging.conf')) # important to do this first

Expand Down Expand Up @@ -74,6 +77,13 @@ def run(job_name, target_system=None, file_path=None):
ProjectExtractor.do_sync(target_system=target_system)
application.logger.info(f'Completed Project Sync for {target_system.value}')

# Update proponent eligibility status after project sync (SUBMIT only)
if target_system == TargetSystem.SUBMIT:
from epic_cron.models.db import init_submit_db
application.logger.info('Running Proponent Status Updater...')
ProponentStatusUpdater.update(init_submit_db(application))
application.logger.info(f'<<<< Completed Proponent Status Update >>>>')

elif job_name == 'SCAN_VIRUS':
application.logger.info(f'Running Virus Scanner on: {file_path}')
VirusScanner.scan_file_from_path(file_path)
Expand All @@ -92,6 +102,19 @@ def run(job_name, target_system=None, file_path=None):
from tasks.pending_access_reminder import PendingAccessReminder
PendingAccessReminder.run()
application.logger.info(f'<<<< Completed Pending Access Reminder >>>>')
elif job_name == 'EXTRACT_WORK':
application.logger.info(f'Running Project Extractor for SUBMIT before Work Extraction...')
ProponentExtractor.do_sync()
application.logger.info(f'<<<< Completed Proponent Sync for SUBMIT >>>>')
ProjectExtractor.do_sync(target_system=TargetSystem.SUBMIT)
application.logger.info(f'<<<< Completed Project Sync for SUBMIT >>>>')
application.logger.info(f'Running Work Extractor at {datetime.now()}')
WorkExtractor.do_sync()
application.logger.info(f'<<<< Completed Work Extraction >>>>')
elif job_name == 'EXTRACT_PHASE':
application.logger.info(f'Running Phase Extractor at {datetime.now()}')
PhaseExtractor.do_sync()
application.logger.info(f'<<<< Completed Phase Extraction >>>>')

else:
application.logger.warning('No valid job_name passed. Exiting without running any tasks.')
Expand All @@ -103,7 +126,7 @@ def run(job_name, target_system=None, file_path=None):
args = sys.argv[1:]

if not args:
logger.error("You must provide a job type: SUBMIT/COMPLIANCE/EMAIL/SYNC_CONDITION/SCAN_VIRUS")
logger.error("You must provide a job type: SUBMIT/COMPLIANCE/EMAIL/SYNC_CONDITION/SCAN_VIRUS/EXTRACT_WORK/EXTRACT_PHASE")
sys.exit(1)

job_type = args[0]
Expand All @@ -116,6 +139,12 @@ def run(job_name, target_system=None, file_path=None):
elif job_type == "SYNC_CONDITION":
run("SYNC_CONDITION")

elif job_type == "EXTRACT_WORK":
run("EXTRACT_WORK")

elif job_type == "EXTRACT_PHASE":
run("EXTRACT_PHASE")

elif job_type == "SCAN_VIRUS":
if len(args) < 2:
logger.error("You must provide a file path for SCAN_VIRUS.")
Expand All @@ -129,6 +158,6 @@ def run(job_name, target_system=None, file_path=None):
target_system = TargetSystem(job_type)
run("EXTRACT_PROJECT", target_system)
except ValueError:
logger.error(f"Invalid job type '{job_type}'. Must be one of: SUBMIT, COMPLIANCE, EMAIL, SYNC_CONDITION, SCAN_VIRUS")
logger.error(f"Invalid job type '{job_type}'. Must be one of: SUBMIT, COMPLIANCE, EMAIL, SYNC_CONDITION, SCAN_VIRUS, EXTRACT_WORK, EXTRACT_PHASE")
sys.exit(1)

2 changes: 2 additions & 0 deletions jobs/epic-cron/run_phase_extractor.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
python invoke_jobs.py EXTRACT_PHASE
4 changes: 0 additions & 4 deletions jobs/epic-cron/sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ CENTRE_DATABASE_PORT=5432
# API CONFIGURATIONS
# ------------------------------------------------------------------------------

# TRACK API Base URL
# Base URL for the EPIC Track API
TRACK_API_BASE_URL=http://localhost:3200

# CONDITION API Base URL
# Base URL for the Condition Management API
CONDITION_API_BASE_URL=http://localhost:5000
Expand Down
6 changes: 6 additions & 0 deletions jobs/epic-cron/src/epic_cron/models/external/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
"""External models from other EPIC repositories."""

from .track_work import TrackWork
from .track_phase import TrackPhase
from .work_state import WorkState

__all__ = ['TrackWork', 'TrackPhase', 'WorkState']
32 changes: 32 additions & 0 deletions jobs/epic-cron/src/epic_cron/models/external/track_phase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Track Phase Model - Local copy for epic-cron."""

from datetime import datetime, timezone

from sqlalchemy import Boolean, Column, DateTime, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class TrackPhase(Base):
"""Track Phase Model Class."""

__tablename__ = "track_phases"

id = Column(Integer, primary_key=True, autoincrement=False)
name = Column(String(255), nullable=False)
ea_act_id = Column(Integer, nullable=True)
ea_act_name = Column(String(255), nullable=True)
work_type_id = Column(Integer, nullable=False)
work_type_name = Column(String(255), nullable=True)
sort_order = Column(Integer, nullable=True)
number_of_days = Column(Integer, nullable=True)
display_name = Column(String(255), nullable=True)
legislated = Column(Boolean, default=False, nullable=False)
enable_submit = Column(Boolean, default=False, nullable=False)
is_active = Column(Boolean, default=True, nullable=False)
is_deleted = Column(Boolean, default=False, nullable=False)
created_date = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False)
updated_date = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=True)
created_by = Column(String(100), nullable=True)
updated_by = Column(String(100), nullable=True)
26 changes: 26 additions & 0 deletions jobs/epic-cron/src/epic_cron/models/external/track_work.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Track Work Model - Local copy for epic-cron."""

from datetime import datetime, timezone

from sqlalchemy import Boolean, Column, DateTime, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class TrackWork(Base):
"""Track Work Model Class - Read-only table synchronized from EPIC.track."""

__tablename__ = "track_works"

id = Column(Integer, primary_key=True, autoincrement=False)
project_id = Column(Integer, nullable=False)
current_phase_id = Column(Integer, nullable=True)
work_state = Column(String(50), nullable=True)
title = Column(String(500), nullable=True)
is_active = Column(Boolean, default=True, nullable=False)
is_deleted = Column(Boolean, default=False, nullable=False)
created_date = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False)
updated_date = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=True)
created_by = Column(String(100), nullable=True)
updated_by = Column(String(100), nullable=True)
18 changes: 18 additions & 0 deletions jobs/epic-cron/src/epic_cron/models/external/work_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""Work State Enum - Defines valid work states for filtering."""

import enum


class WorkState(enum.Enum):
"""Enum for work states that should be excluded from proponent eligibility checks."""

# Excluded states - works in these states don't count toward proponent eligibility
COMPLETED = "COMPLETED"
TERMINATED = "TERMINATED"
CLOSED = "CLOSED"
WITHDRAWN = "WITHDRAWN"

@classmethod
def excluded_states(cls):
"""Return list of work states that should be excluded from eligibility checks."""
return [cls.COMPLETED.value, cls.TERMINATED.value, cls.CLOSED.value, cls.WITHDRAWN.value]
Loading