fix(amas): priority queue + connecting tick + drop role column
- import_bulk_employees gains a `queue` arg so callers can route the job
off the contended default queue. The bar that hangs on "Preparing
import..." for ~a minute post-setup is queue wait: a single `bench
worker` drains short→default→long, so the import sat behind the
post-setup backlog. The wizard now enqueues on "short".
- Emit a "connecting" progress tick the instant the worker starts, so the
bar leaves the "queued" seed and shows it's actually running (vs still
waiting) before the first detail fetch.
- Org selection: drop the Role column ("Hüquqi şəxs" for every row) — the
name + VÖEN are enough. The role value is still sent to the API.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
15047ffbaa
commit
a275f4144e
|
|
@ -2731,10 +2731,15 @@ def on_delete_employee(doc, method):
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def import_bulk_employees(asan_login_name, employees_data, company, create_designation=0):
|
def import_bulk_employees(asan_login_name, employees_data, company, create_designation=0, queue="default"):
|
||||||
"""Enqueue bulk employee import as a background job with realtime progress via Socket.IO.
|
"""Enqueue bulk employee import as a background job with realtime progress via Socket.IO.
|
||||||
|
|
||||||
Refuses to enqueue if an import for the same Asan Login is already running.
|
Refuses to enqueue if an import for the same Asan Login is already running.
|
||||||
|
|
||||||
|
``queue`` lets callers pick a less-contended RQ queue. The setup wizard passes
|
||||||
|
"short" so the import isn't stuck behind the pile of post-setup jobs on the
|
||||||
|
default queue (a single `bench worker` drains queues short→default→long, so
|
||||||
|
"short" jumps the line and starts as soon as the worker frees).
|
||||||
"""
|
"""
|
||||||
if isinstance(employees_data, str):
|
if isinstance(employees_data, str):
|
||||||
employees_data = json.loads(employees_data)
|
employees_data = json.loads(employees_data)
|
||||||
|
|
@ -2774,7 +2779,7 @@ def import_bulk_employees(asan_login_name, employees_data, company, create_desig
|
||||||
company=company,
|
company=company,
|
||||||
create_designation=create_designation,
|
create_designation=create_designation,
|
||||||
user=user,
|
user=user,
|
||||||
queue="default",
|
queue=queue or "default",
|
||||||
timeout=1200,
|
timeout=1200,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -2948,6 +2953,16 @@ def _process_bulk_employees_import(asan_login_name, employees, company, create_d
|
||||||
updated_count = 0
|
updated_count = 0
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
|
# First tick the instant the worker picks up the job: flips the bar from the
|
||||||
|
# "queued" seed to "connecting" so the user can tell the job actually started
|
||||||
|
# (vs. still waiting in the queue) even before the first detail fetch lands.
|
||||||
|
_set_import_progress(asan_login_name, 0, total, "connecting", None, 1)
|
||||||
|
frappe.publish_realtime(
|
||||||
|
"amas_import_progress",
|
||||||
|
{"current": 0, "total": total, "phase": "connecting", "percent": 1},
|
||||||
|
user=user,
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Refresh the plaintext CSRF token from /core.dashboard once before going
|
# Refresh the plaintext CSRF token from /core.dashboard once before going
|
||||||
# parallel. The DB may have a stale (or previously-corrupted) token; the
|
# parallel. The DB may have a stale (or previously-corrupted) token; the
|
||||||
|
|
|
||||||
|
|
@ -730,6 +730,8 @@ function attach_amas_import_listeners(listview, asan_login_name, total_hint) {
|
||||||
const phaseLabel = function(phase) {
|
const phaseLabel = function(phase) {
|
||||||
if (phase === 'save') return __('Saving employees');
|
if (phase === 'save') return __('Saving employees');
|
||||||
if (phase === 'fetch') return __('Fetching details');
|
if (phase === 'fetch') return __('Fetching details');
|
||||||
|
if (phase === 'connecting') return __('Connecting to ƏMAS...');
|
||||||
|
if (phase === 'queued') return __('Waiting to start...');
|
||||||
return __('Preparing import...');
|
return __('Preparing import...');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -754,7 +756,7 @@ function attach_amas_import_listeners(listview, asan_login_name, total_hint) {
|
||||||
|
|
||||||
const label = phaseLabel(phase);
|
const label = phaseLabel(phase);
|
||||||
let detail;
|
let detail;
|
||||||
if (phase === 'queued' || !(total > 0)) {
|
if (phase === 'queued' || phase === 'connecting' || !(total > 0)) {
|
||||||
detail = label;
|
detail = label;
|
||||||
} else if (employee_name) {
|
} else if (employee_name) {
|
||||||
detail = label + ': ' + employee_name + ' (' + current + '/' + total + ')';
|
detail = label + ': ' + employee_name + ' (' + current + '/' + total + ')';
|
||||||
|
|
@ -1461,7 +1463,7 @@ function show_amas_accounts_dialog(asan_login_name, accounts, retry_callback) {
|
||||||
// Build accounts table
|
// Build accounts table
|
||||||
let table_html = '<div style="max-height: 400px; overflow-y: auto;">';
|
let table_html = '<div style="max-height: 400px; overflow-y: auto;">';
|
||||||
table_html += '<table class="table table-bordered table-hover">';
|
table_html += '<table class="table table-bordered table-hover">';
|
||||||
table_html += '<thead><tr><th style="width: 50%;">Organization Name</th><th style="width: 25%;">VOEN</th><th style="width: 15%;">Role</th><th style="width: 10%;">Action</th></tr></thead>';
|
table_html += '<thead><tr><th style="width: 60%;">Organization Name</th><th style="width: 30%;">VOEN</th><th style="width: 10%;">Action</th></tr></thead>';
|
||||||
table_html += '<tbody>';
|
table_html += '<tbody>';
|
||||||
|
|
||||||
accounts.forEach(function(account, index) {
|
accounts.forEach(function(account, index) {
|
||||||
|
|
@ -1473,7 +1475,6 @@ function show_amas_accounts_dialog(asan_login_name, accounts, retry_callback) {
|
||||||
table_html += `<tr>
|
table_html += `<tr>
|
||||||
<td>${frappe.utils.escape_html(name)}</td>
|
<td>${frappe.utils.escape_html(name)}</td>
|
||||||
<td>${frappe.utils.escape_html(voen)}</td>
|
<td>${frappe.utils.escape_html(voen)}</td>
|
||||||
<td>${frappe.utils.escape_html(role)}</td>
|
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-xs btn-primary select-amas-account"
|
<button class="btn btn-xs btn-primary select-amas-account"
|
||||||
data-oid="${frappe.utils.escape_html(oid)}"
|
data-oid="${frappe.utils.escape_html(oid)}"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue