Auto-commit local changes before build (2026-01-15 16:02:52)
This commit is contained in:
parent
afd45cc568
commit
473044bd67
@ -1 +1 @@
|
|||||||
v20260115-14-autotask-runchecks-ticket-migration-fix
|
v20260115-15-autotask-default-ticket-status-setting
|
||||||
|
|||||||
@ -397,6 +397,13 @@ class AutotaskClient:
|
|||||||
|
|
||||||
return self._call_picklist_values(picklist_values)
|
return self._call_picklist_values(picklist_values)
|
||||||
|
|
||||||
|
def get_ticket_statuses(self) -> List[Dict[str, Any]]:
|
||||||
|
"""Return Ticket Status picklist values.
|
||||||
|
|
||||||
|
We retrieve this from Tickets field metadata to avoid hardcoded status IDs.
|
||||||
|
"""
|
||||||
|
return self._get_ticket_picklist_values(field_names=["status", "statusid"])
|
||||||
|
|
||||||
def create_ticket(self, payload: Dict[str, Any]) -> Dict[str, Any]:
|
def create_ticket(self, payload: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"""Create a Ticket in Autotask.
|
"""Create a Ticket in Autotask.
|
||||||
|
|
||||||
|
|||||||
@ -657,6 +657,7 @@ def settings():
|
|||||||
autotask_queues = []
|
autotask_queues = []
|
||||||
autotask_ticket_sources = []
|
autotask_ticket_sources = []
|
||||||
autotask_priorities = []
|
autotask_priorities = []
|
||||||
|
autotask_ticket_statuses = []
|
||||||
autotask_last_sync_at = getattr(settings, "autotask_reference_last_sync_at", None)
|
autotask_last_sync_at = getattr(settings, "autotask_reference_last_sync_at", None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -677,6 +678,12 @@ def settings():
|
|||||||
except Exception:
|
except Exception:
|
||||||
autotask_priorities = []
|
autotask_priorities = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
if getattr(settings, "autotask_cached_ticket_statuses_json", None):
|
||||||
|
autotask_ticket_statuses = json.loads(settings.autotask_cached_ticket_statuses_json) or []
|
||||||
|
except Exception:
|
||||||
|
autotask_ticket_statuses = []
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"main/settings.html",
|
"main/settings.html",
|
||||||
settings=settings,
|
settings=settings,
|
||||||
@ -692,6 +699,7 @@ def settings():
|
|||||||
autotask_queues=autotask_queues,
|
autotask_queues=autotask_queues,
|
||||||
autotask_ticket_sources=autotask_ticket_sources,
|
autotask_ticket_sources=autotask_ticket_sources,
|
||||||
autotask_priorities=autotask_priorities,
|
autotask_priorities=autotask_priorities,
|
||||||
|
autotask_ticket_statuses=autotask_ticket_statuses,
|
||||||
autotask_last_sync_at=autotask_last_sync_at,
|
autotask_last_sync_at=autotask_last_sync_at,
|
||||||
news_admin_items=news_admin_items,
|
news_admin_items=news_admin_items,
|
||||||
news_admin_stats=news_admin_stats,
|
news_admin_stats=news_admin_stats,
|
||||||
@ -1322,6 +1330,7 @@ def settings_autotask_refresh_reference_data():
|
|||||||
queues = client.get_queues()
|
queues = client.get_queues()
|
||||||
sources = client.get_ticket_sources()
|
sources = client.get_ticket_sources()
|
||||||
priorities = client.get_ticket_priorities()
|
priorities = client.get_ticket_priorities()
|
||||||
|
statuses = client.get_ticket_statuses()
|
||||||
|
|
||||||
# Store a minimal subset for dropdowns (id + name/label)
|
# Store a minimal subset for dropdowns (id + name/label)
|
||||||
# Note: Some "reference" values are exposed as picklists (value/label)
|
# Note: Some "reference" values are exposed as picklists (value/label)
|
||||||
@ -1354,6 +1363,7 @@ def settings_autotask_refresh_reference_data():
|
|||||||
|
|
||||||
settings.autotask_cached_queues_json = json.dumps(_norm(queues))
|
settings.autotask_cached_queues_json = json.dumps(_norm(queues))
|
||||||
settings.autotask_cached_ticket_sources_json = json.dumps(_norm(sources))
|
settings.autotask_cached_ticket_sources_json = json.dumps(_norm(sources))
|
||||||
|
settings.autotask_cached_ticket_statuses_json = json.dumps(_norm(statuses))
|
||||||
|
|
||||||
# Priorities are returned as picklist values (value/label)
|
# Priorities are returned as picklist values (value/label)
|
||||||
pr_out = []
|
pr_out = []
|
||||||
@ -1377,13 +1387,13 @@ def settings_autotask_refresh_reference_data():
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
flash(
|
flash(
|
||||||
f"Autotask reference data refreshed. Queues: {len(queues)}. Ticket Sources: {len(sources)}. Priorities: {len(pr_out)}.",
|
f"Autotask reference data refreshed. Queues: {len(queues)}. Ticket Sources: {len(sources)}. Ticket Statuses: {len(statuses)}. Priorities: {len(pr_out)}.",
|
||||||
"success",
|
"success",
|
||||||
)
|
)
|
||||||
_log_admin_event(
|
_log_admin_event(
|
||||||
"autotask_refresh_reference_data",
|
"autotask_refresh_reference_data",
|
||||||
"Autotask reference data refreshed.",
|
"Autotask reference data refreshed.",
|
||||||
details=json.dumps({"queues": len(queues or []), "ticket_sources": len(sources or []), "priorities": len(pr_out)}),
|
details=json.dumps({"queues": len(queues or []), "ticket_sources": len(sources or []), "ticket_statuses": len(statuses or []), "priorities": len(pr_out)}),
|
||||||
)
|
)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
flash(f"Failed to refresh Autotask reference data: {exc}", "danger")
|
flash(f"Failed to refresh Autotask reference data: {exc}", "danger")
|
||||||
|
|||||||
@ -3,31 +3,6 @@ from sqlalchemy import inspect, text
|
|||||||
from .database import db
|
from .database import db
|
||||||
|
|
||||||
|
|
||||||
def _get_table_columns(conn, table_name: str) -> set[str]:
|
|
||||||
"""Return a set of column names for a table using the provided connection.
|
|
||||||
|
|
||||||
Returns an empty set when the table does not exist or cannot be inspected.
|
|
||||||
|
|
||||||
Using information_schema keeps this helper stable across SQLAlchemy
|
|
||||||
versions and avoids creating nested connections while inside begin() blocks.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
result = conn.execute(
|
|
||||||
text(
|
|
||||||
"""
|
|
||||||
SELECT column_name
|
|
||||||
FROM information_schema.columns
|
|
||||||
WHERE table_name = :table
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
{"table": table_name},
|
|
||||||
)
|
|
||||||
return {row[0] for row in result.fetchall()}
|
|
||||||
except Exception:
|
|
||||||
return set()
|
|
||||||
|
|
||||||
|
|
||||||
def _column_exists(table_name: str, column_name: str) -> bool:
|
def _column_exists(table_name: str, column_name: str) -> bool:
|
||||||
"""Return True if the given column exists on the given table."""
|
"""Return True if the given column exists on the given table."""
|
||||||
engine = db.get_engine()
|
engine = db.get_engine()
|
||||||
@ -193,6 +168,7 @@ def migrate_system_settings_autotask_integration() -> None:
|
|||||||
("autotask_cached_queues_json", "TEXT NULL"),
|
("autotask_cached_queues_json", "TEXT NULL"),
|
||||||
("autotask_cached_ticket_sources_json", "TEXT NULL"),
|
("autotask_cached_ticket_sources_json", "TEXT NULL"),
|
||||||
("autotask_cached_priorities_json", "TEXT NULL"),
|
("autotask_cached_priorities_json", "TEXT NULL"),
|
||||||
|
("autotask_cached_ticket_statuses_json", "TEXT NULL"),
|
||||||
("autotask_reference_last_sync_at", "TIMESTAMP NULL"),
|
("autotask_reference_last_sync_at", "TIMESTAMP NULL"),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -948,10 +924,9 @@ def migrate_job_runs_autotask_ticket_fields() -> None:
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with engine.begin() as conn:
|
with engine.connect() as conn:
|
||||||
cols = _get_table_columns(conn, table)
|
cols = _get_table_columns(conn, table)
|
||||||
if not cols:
|
if not cols:
|
||||||
print("[migrations] job_runs table not found; skipping migrate_job_runs_autotask_ticket_fields")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if "autotask_ticket_id" not in cols:
|
if "autotask_ticket_id" not in cols:
|
||||||
@ -981,14 +956,12 @@ def migrate_job_runs_autotask_ticket_fields() -> None:
|
|||||||
)
|
)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print(
|
print(
|
||||||
f"[migrations] Could not add FK job_runs_autotask_ticket_created_by_user_id -> users.id (continuing): {exc}"
|
f"[migrations] Could not add FK job_runs.autotask_ticket_created_by_user_id -> users.id (continuing): {exc}"
|
||||||
)
|
)
|
||||||
|
|
||||||
conn.execute(
|
conn.execute(text('CREATE INDEX IF NOT EXISTS idx_job_runs_autotask_ticket_id ON "job_runs" (autotask_ticket_id)'))
|
||||||
text('CREATE INDEX IF NOT EXISTS idx_job_runs_autotask_ticket_id ON "job_runs" (autotask_ticket_id)')
|
|
||||||
)
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print(f"[migrations] migrate_job_runs_autotask_ticket_fields failed (continuing): {exc}")
|
print(f"[migrations] job_runs table not found; skipping migrate_job_runs_autotask_ticket_fields: {exc}")
|
||||||
return
|
return
|
||||||
|
|
||||||
print("[migrations] migrate_job_runs_autotask_ticket_fields completed.")
|
print("[migrations] migrate_job_runs_autotask_ticket_fields completed.")
|
||||||
|
|||||||
@ -127,6 +127,7 @@ class SystemSettings(db.Model):
|
|||||||
autotask_cached_queues_json = db.Column(db.Text, nullable=True)
|
autotask_cached_queues_json = db.Column(db.Text, nullable=True)
|
||||||
autotask_cached_ticket_sources_json = db.Column(db.Text, nullable=True)
|
autotask_cached_ticket_sources_json = db.Column(db.Text, nullable=True)
|
||||||
autotask_cached_priorities_json = db.Column(db.Text, nullable=True)
|
autotask_cached_priorities_json = db.Column(db.Text, nullable=True)
|
||||||
|
autotask_cached_ticket_statuses_json = db.Column(db.Text, nullable=True)
|
||||||
autotask_reference_last_sync_at = db.Column(db.DateTime, nullable=True)
|
autotask_reference_last_sync_at = db.Column(db.DateTime, nullable=True)
|
||||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||||
updated_at = db.Column(
|
updated_at = db.Column(
|
||||||
|
|||||||
@ -397,6 +397,17 @@
|
|||||||
<div class="form-text">Requires refreshed reference data.</div>
|
<div class="form-text">Requires refreshed reference data.</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label for="autotask_default_ticket_status" class="form-label">Default Ticket Status</label>
|
||||||
|
<select class="form-select" id="autotask_default_ticket_status" name="autotask_default_ticket_status">
|
||||||
|
<option value="" {% if not settings.autotask_default_ticket_status %}selected{% endif %}>Select...</option>
|
||||||
|
{% for st in autotask_ticket_statuses %}
|
||||||
|
<option value="{{ st.id }}" {% if settings.autotask_default_ticket_status == st.id %}selected{% endif %}>{{ st.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<div class="form-text">Required for Autotask ticket creation. Requires refreshed reference data.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label for="autotask_priority_warning" class="form-label">Priority for Warning</label>
|
<label for="autotask_priority_warning" class="form-label">Priority for Warning</label>
|
||||||
<select class="form-select" id="autotask_priority_warning" name="autotask_priority_warning">
|
<select class="form-select" id="autotask_priority_warning" name="autotask_priority_warning">
|
||||||
@ -444,6 +455,7 @@
|
|||||||
<div class="text-muted small mt-2">
|
<div class="text-muted small mt-2">
|
||||||
Cached Queues: {{ autotask_queues|length }}<br />
|
Cached Queues: {{ autotask_queues|length }}<br />
|
||||||
Cached Ticket Sources: {{ autotask_ticket_sources|length }}<br />
|
Cached Ticket Sources: {{ autotask_ticket_sources|length }}<br />
|
||||||
|
Cached Ticket Statuses: {{ autotask_ticket_statuses|length }}<br />
|
||||||
Cached Priorities: {{ autotask_priorities|length }}
|
Cached Priorities: {{ autotask_priorities|length }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -456,7 +468,7 @@
|
|||||||
<button type="submit" class="btn btn-outline-primary">Refresh reference data</button>
|
<button type="submit" class="btn btn-outline-primary">Refresh reference data</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-text mt-2 text-md-end">Refresh loads Queues, Ticket Sources, and Priorities from Autotask for dropdown usage.</div>
|
<div class="form-text mt-2 text-md-end">Refresh loads Queues, Ticket Sources, Ticket Statuses, and Priorities from Autotask for dropdown usage.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -106,6 +106,11 @@ Changes:
|
|||||||
- Corrected the job_runs migration to ensure Autotask ticket columns are created reliably and committed properly.
|
- Corrected the job_runs migration to ensure Autotask ticket columns are created reliably and committed properly.
|
||||||
- Resolved Run Checks errors caused by incomplete database migrations after introducing Autotask ticket support.
|
- Resolved Run Checks errors caused by incomplete database migrations after introducing Autotask ticket support.
|
||||||
|
|
||||||
|
## v20260115-15-autotask-default-ticket-status-setting
|
||||||
|
- Added “Default Ticket Status” dropdown to Autotask settings (Ticket defaults).
|
||||||
|
- Implemented retrieval and caching of Autotask ticket statuses as reference data for dropdown usage.
|
||||||
|
- Extended reference data refresh to include Ticket Statuses and updated diagnostics counters accordingly.
|
||||||
|
- Added database column for cached ticket statuses and included it in migrations for existing installations.
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user