Skip to content

Fetch Jobs Implementation Documentation

kitler edited this page Feb 3, 2026 · 2 revisions

Fetch>>Jobs Implementation Documentation

Overview

The "Fetch>>Jobs" functionality allows users to search for and select transport jobs that can be consolidated into a Transport Consolidation document. The implementation provides a comprehensive dialog interface with filtering, sorting, and selection capabilities.

Architecture

1. Button Setup

The "Fetch>>Jobs" button is added to the Transport Consolidation form in the refresh event handler:

refresh(frm) {
    // Add custom button to fetch jobs (always show dialog for manual selection)
    frm.add_custom_button(__("Jobs"), function() {
        fetch_consolidatable_jobs(frm);
    }, __("Fetch"));
}

Location: Lines 6-9

Key Points:

  • Button is always visible (no conditions)
  • Clicking triggers fetch_consolidatable_jobs(frm)
  • Button is placed in the "Fetch" button group

2. Fetching Consolidatable Jobs

The fetch_consolidatable_jobs() function makes a server call to retrieve jobs that can be consolidated:

function fetch_consolidatable_jobs(frm) {
    frappe.call({
        method: "logistics.transport.doctype.transport_consolidation.transport_consolidation.get_consolidatable_jobs",
        args: {
            consolidation_type: frm.doc.consolidation_type || null,
            company: frm.doc.company || null,
            date: frm.doc.consolidation_date || null,
            current_consolidation: frm.doc.name && !frm.doc.__islocal ? frm.doc.name : null
        },
        callback: function(r) {
            if (r.message && r.message.status === "success") {
                show_jobs_dialog(frm, r.message.jobs, r.message.consolidation_groups, r.message.debug);
            }
        }
    });
}

Location: Lines 132-158

Parameters Sent to Server:

  • consolidation_type: Type of consolidation (Route, Pick, Drop, Both)
  • company: Company filter
  • date: Consolidation date filter
  • current_consolidation: Current consolidation name (to exclude already added jobs)

Server Response:

  • jobs: Array of consolidatable jobs
  • consolidation_groups: Grouped jobs by common addresses
  • debug: Debug information for diagnostics

3. Jobs Dialog Structure

The show_jobs_dialog() function creates a comprehensive dialog interface:

Location: Lines 518-1242

3.1 Dialog Fields

The dialog includes the following sections:

  1. Summary Info (HTML Field)

    • Shows count of found jobs
    • Displays consolidation groups count
    • Includes collapsible diagnostics section
  2. Filter Section (Collapsible)

    • filter_customer: Link field to filter by customer
    • filter_pick_address: Link field to filter by pick address
    • filter_drop_address: Link field to filter by drop address
    • filter_consolidation_type: Select field (Route/Pick/Drop/Both)
    • sort_by: Select field for sorting
    • sort_order: Ascending/Descending
  3. View Toggle

    • Toggle between "Jobs" view and "Transport Legs" view
    • Buttons to switch views dynamically
  4. Jobs Table (HTML Field)

    • Dynamic table showing jobs or legs
    • Includes checkboxes for selection
    • Responsive with tooltips for addresses
  5. Select All Checkbox

    • Checkbox to select/deselect all items at once

3.2 Dialog Initialization

const dialog = new frappe.ui.Dialog({
    title: __("Consolidation Suggestions"),
    size: 'large',
    fields: [/* field definitions */],
    primary_action_label: has_jobs ? __("Add Selected Jobs") : __("Close"),
    primary_action: function(values) {
        // Handle job selection and addition
    }
});

Key Features:

  • Large dialog size (90% width, max 1400px)
  • Dynamic primary action label
  • Stores dialog reference in frm._consolidation_dialog for synchronization

4. Data Management

4.1 Jobs Data Storage

The dialog maintains several data structures:

let all_jobs = jobs || [];              // Original jobs list from server
let filtered_jobs = jobs || [];         // Currently filtered list
let selected_jobs = [];                 // User-selected jobs
let current_view = "jobs";              // Current view: "jobs" or "legs"

Dialog-level storage:

  • dialog._jobs_data.all_jobs: All consolidatable jobs
  • dialog._jobs_data.filtered_jobs: Filtered jobs
  • dialog._all_legs: All transport legs (when in legs view)
  • dialog._filtered_legs: Filtered legs
  • dialog._legs_job_names: Job names for which legs were fetched

4.2 View Switching

The dialog supports two views:

  1. Jobs View (Default)

    • Shows transport jobs with consolidation information
    • Displays: Job name, Customer, Scheduled Date, Load Type, Pick/Drop Addresses, Type
  2. Legs View

    • Shows individual transport legs
    • Displays: Leg name, Job, Customer, Date, Vehicle Type, Load Type, Pick/Drop Addresses, Status
    • Fetches ALL consolidatable legs system-wide (not just from jobs in Jobs View)
    • Legs are fetched on-demand when switching to this view
    • Independent view - filters apply directly to legs, not to jobs first

Switch Function: switch_view(view_type) - Lines 1044-1137


5. Filtering and Sorting

5.1 Filter Function

The filter_jobs() function handles filtering for both views:

Location: Lines 848-1038

Filter Logic:

For Jobs View:

  • Filters by customer (exact match)
  • Filters by pick address (checks if job has matching pick address in array)
  • Filters by drop address (checks if job has matching drop address in array)
  • Consolidation type filtering is done server-side

For Legs View:

  • Filters legs directly by customer, pick address, drop address
  • No job-level filtering - filters apply directly to legs
  • Fetches ALL consolidatable legs if not already cached (when fetch_all=true)
  • Applies filters to the legs array
  • Independent of Jobs View - shows all consolidatable legs system-wide

Sorting:

  • Uses sort_jobs() for jobs view (Lines 1324-1394)
  • Uses sort_legs() for legs view (Lines 1244-1322)
  • Supports multiple sort fields: Job, Customer, Date, Vehicle Type, Load Type, Addresses, Type/Status
  • Vehicle Type sorting available in both views (mapped appropriately for legs)

5.2 Filter Event Handlers

Location: Lines 1142-1241

Event handlers are set up for:

  • Link fields (customer, pick/drop addresses): Multiple event listeners to catch all changes
  • Select fields (consolidation_type, sort_by, sort_order): Standard change events
  • Consolidation type changes trigger server-side re-fetch via reload_jobs_with_filter()

Special Handling:

  • Consolidation type filter changes update the form field and trigger server re-fetch
  • Prevents recursive updates with _updating_from_dialog flag

6. Table Rendering

6.1 Jobs Table

Function: build_jobs_table_html(jobs, consolidation_groups) - Lines 1514-1744

Features:

  • Responsive table with fixed layout
  • Tooltips for Route consolidation type showing all addresses
  • Consolidation type badges (Pick/Drop/Both/Route)
  • Partial consolidation status indicator
  • Checkboxes for selection with data-job-name attribute
  • Links to job documents

Address Tooltips:

  • For Route consolidation or multiple addresses
  • Shows numbered list of all pick/drop addresses
  • Positioned dynamically on hover

6.2 Legs Table

Function: build_legs_table_html(legs) - Lines 1396-1512

Features:

  • Similar structure to jobs table
  • Shows leg name, job name, customer, date, vehicle type, load type, addresses, status
  • Status badges with color coding
  • Checkboxes with both data-job-name and data-leg-name attributes

Columns:

  1. Checkbox (40px) - Selection checkbox
  2. Leg (9%) - Transport Leg name (link)
  3. Job (9%) - Transport Job name (link)
  4. Customer (10%) - Customer name
  5. Date (9%) - Leg date (formatted)
  6. Vehicle Type (9%) - Vehicle type for the leg
  7. Load Type (9%) - Load type from parent job
  8. Pick Address (15%) - Pick address (with tooltip)
  9. Drop Address (15%) - Drop address (with tooltip)
  10. Status (7%) - Leg status badge

7. Selection Management

7.1 Checkbox Handling

Select All Functionality:

  • Header checkbox in table: .select-all-checkbox
  • Dialog field checkbox: select_all field
  • Both are synchronized

Individual Checkboxes:

  • Class: .job-checkbox
  • Data attributes: data-job-name (and data-leg-name for legs)
  • Change events update select-all state

Update Function: update_select_all_state() - Lines 1231-1240

7.2 Selection Collection

When "Add Selected Jobs" is clicked:

const checkboxes = dialog.$wrapper.find('.job-checkbox:checked');
selected_jobs = [];
const selected_job_names = new Set();

checkboxes.each(function() {
    const job_name = $(this).data('job-name');
    if (job_name) {
        selected_job_names.add(job_name);
    }
});

selected_jobs = Array.from(selected_job_names);

Location: Lines 757-769

Key Points:

  • Collects unique job names from checked checkboxes
  • Works for both jobs and legs views (legs have data-job-name)
  • Validates that at least one job is selected

8. Adding Jobs to Consolidation

Function: add_jobs_to_consolidation(frm, job_names, dialog) - Lines 1746-1775

Process:

  1. Validates document is saved (not local)
  2. Makes server call to add jobs
  3. Shows success/error alerts
  4. Closes dialog and reloads form

Server Method:

method: "logistics.transport.doctype.transport_consolidation.transport_consolidation.add_jobs_to_consolidation"
args: {
    consolidation_name: frm.doc.name,
    job_names: job_names
}

9. Transport Legs Integration

9.1 Fetching Legs

Function: fetch_legs_for_jobs(job_names, callback, company, fetch_all) - Lines 160-202

Parameters:

  • job_names: Array of job names (ignored if fetch_all=true)
  • callback: Function to call with results
  • company: Optional company filter
  • fetch_all: If true, fetches ALL consolidatable legs system-wide

Process:

  1. If fetch_all=true:
    • Fetches ALL consolidatable legs (not tied to specific jobs)
    • Filters by company if provided
    • Returns all legs that meet consolidation criteria
  2. If fetch_all=false (default):
    • Validates and cleans job names
    • Fetches legs for the given job names only
  3. Makes server call to get consolidatable legs
  4. Returns legs array via callback

Server Method:

method: "logistics.transport.doctype.transport_consolidation.transport_consolidation.get_consolidatable_legs"
args: {
    job_names: job_names,      // Ignored if fetch_all=true
    company: company,           // Optional company filter
    fetch_all: fetch_all        // Boolean: fetch all consolidatable legs
}

9.2 Consolidation Criteria (when fetch_all=true)

When fetching all consolidatable legs, the system applies these criteria:

  1. Leg Requirements:

    • Legs without run_sheet assigned
    • Legs with both pick_address and drop_address
    • Legs that are not cancelled (docstatus < 2)
  2. Job Requirements:

    • Jobs must be submitted (docstatus = 1)
    • Jobs must have Load Type with can_handle_consolidation = 1
    • Fallback: Jobs with consolidate = 1 flag (for backward compatibility)
  3. Company Filter:

    • Optional: Filter legs by company (via transport_job relationship)

9.3 Legs View Logic

When switching to legs view:

  1. Checks if legs are already cached
  2. If not, fetches ALL consolidatable legs (not just from jobs in Jobs View)
  3. Applies current filters directly to legs (customer, pick address, drop address)
  4. Renders legs table

Key Change:

  • Before: Legs view showed legs only from jobs listed in Jobs View
  • Now: Legs view shows ALL consolidatable legs system-wide (or filtered by company)
  • This makes Legs View independent and more comprehensive

Caching Strategy:

  • Legs are cached in dialog._all_legs
  • Cache is cleared when jobs are reloaded
  • When fetch_all=true, legs are fetched once and cached

9.4 Server-Side Implementation

Python Method: get_consolidatable_legs(job_names, company, fetch_all) - Lines 1964-2065

Parameters:

  • job_names: List of Transport Job names (ignored if fetch_all=True)
  • company: Optional company filter
  • fetch_all: Boolean flag to fetch all consolidatable legs

When fetch_all=True:

  1. Builds filters for consolidatable legs:

    • docstatus < 2 (not cancelled)
    • pick_address != "" (must have pick address)
    • drop_address != "" (must have drop address)
    • run_sheet is empty/null (not assigned to run sheet)
    • Optional: transport_job in company jobs (if company provided)
  2. Fetches all matching legs from database

  3. Validates each leg's parent job:

    • Job must be submitted (docstatus = 1)
    • Job's Load Type must have can_handle_consolidation = 1
    • Fallback: Job has consolidate = 1 flag
  4. Enriches legs with:

    • Job information (customer, load_type, scheduled_date, company)
    • Address titles (pick_address_title, drop_address_title)

When fetch_all=False (default):

  • Fetches legs for the given job_names only
  • Applies same validation and enrichment

Return Format:

{
    "status": "success",
    "legs": [
        {
            "name": "LEG-00001",
            "transport_job": "TRJ-00001",
            "customer": "Customer A",
            "load_type": "FTL",
            "vehicle_type": "Truck",
            "pick_address": "ADDR-001",
            "pick_address_title": "Warehouse A",
            "drop_address": "ADDR-002",
            "drop_address_title": "Warehouse B",
            "status": "Open",
            "date": "2025-01-15",
            # ... other fields
        }
    ]
}

10. Form-Dialog Synchronization

10.1 Consolidation Type Sync

The form and dialog stay synchronized for consolidation type:

Form → Dialog:

  • When form field changes, dialog field updates (Lines 40-61)
  • Triggers filter update if dialog is open

Dialog → Form:

  • When dialog filter changes, form field updates (Lines 1179-1195)
  • Triggers server re-fetch of jobs

Prevention of Recursion:

  • Uses _updating_from_dialog flag
  • Checks current values before updating

10.2 Dialog Reference Management

// Store reference
frm._consolidation_dialog = dialog;

// Clean up on close
const original_hide = dialog.hide;
dialog.hide = function() {
    if (frm._consolidation_dialog === dialog) {
        frm._consolidation_dialog = null;
    }
    original_hide.call(this);
};

Location: Lines 823, 839-845


11. Helper Functions

11.1 Sorting Functions

sort_jobs(jobs, sort_by, sort_order) - Lines 1324-1394

  • Sorts jobs by various fields
  • Handles date comparison
  • Case-insensitive string comparison

sort_legs(legs, sort_by, sort_order) - Lines 1244-1322

  • Maps job sort options to leg fields
  • Handles date comparison
  • Status-based sorting for "Type" option

11.2 UI Setup Functions

setup_address_tooltips(dialog) - Lines 337-382

  • Sets up tooltip positioning for addresses
  • Handles scroll events
  • Fixed positioning for tooltips

setup_filter_toggle(dialog) - Lines 274-335

  • Sets up collapsible filter section
  • Moves filter fields into collapsible container
  • Handles toggle animation

setup_diagnostics_toggle(dialog) - Lines 254-272

  • Sets up collapsible diagnostics section
  • Handles toggle animation

11.3 Update Functions

update_dialog_jobs(dialog, jobs, consolidation_groups, debug_info) - Lines 384-516

  • Updates jobs data in dialog
  • Rebuilds table HTML
  • Re-applies filters
  • Updates summary and diagnostics
  • Clears legs cache

reload_jobs_with_filter(frm, dialog, consolidation_type) - Lines 204-252

  • Re-fetches jobs from server with new filter
  • Updates dialog with new data
  • Clears legs cache
  • Switches back to jobs view if in legs view

12. Error Handling

Validation:

  • Checks if document is saved before adding jobs
  • Validates at least one job is selected
  • Handles empty job/leg lists gracefully

Error Messages:

  • Server errors shown via frappe.show_alert()
  • User-friendly error messages
  • Loading indicators during async operations

13. User Experience Features

  1. Loading Indicators:

    • Spinner shown when fetching jobs/legs
    • "Loading..." messages
  2. Empty States:

    • Friendly messages when no jobs/legs found
    • Clear indication of filter results
  3. Tooltips:

    • Address tooltips for Route consolidation
    • Status tooltips
    • Field descriptions
  4. Responsive Design:

    • Wide dialog (90% width, max 1400px)
    • Scrollable tables
    • Fixed table layout for consistent columns
  5. Diagnostics:

    • Collapsible diagnostics section
    • Shows filtering statistics
    • Debug information for troubleshooting

14. Data Flow Summary

User clicks "Fetch>>Jobs"
    ↓
fetch_consolidatable_jobs()
    ↓
Server: get_consolidatable_jobs()
    ↓
show_jobs_dialog() with jobs data
    ↓
Dialog renders with filters and table
    ↓
User applies filters/sorting
    ↓
filter_jobs() updates table
    ↓
User selects jobs and clicks "Add Selected Jobs"
    ↓
add_jobs_to_consolidation()
    ↓
Server: add_jobs_to_consolidation()
    ↓
Form reloads with new jobs

15. Key Design Decisions

  1. Always Show Dialog:

    • Even when no jobs found, dialog shows for transparency
    • Allows users to see why no jobs match
  2. Two-View System:

    • Jobs view for high-level overview
    • Legs view for detailed leg-level selection
    • Legs view is now independent - shows ALL consolidatable legs, not just from visible jobs
    • Allows discovery of consolidatable legs across the entire system
  3. Client-Side Filtering:

    • Fast filtering without server calls
    • Server-side filtering for consolidation_type (affects which jobs are consolidatable)
  4. Caching Strategy:

    • Jobs cached in dialog
    • Legs cached when fetched with fetch_all=true
    • Legs cache cleared when jobs are reloaded
    • Prevents unnecessary server calls
    • When fetch_all=true, legs are fetched once and reused
  5. Bidirectional Sync:

    • Form and dialog stay in sync
    • Prevents user confusion


16. Recent Updates

16.1 Independent Legs View (Latest)

Key Changes:

  • Legs View now fetches ALL consolidatable legs system-wide
  • No longer dependent on jobs shown in Jobs View
  • Uses fetch_all=true parameter to fetch all eligible legs
  • Filters apply directly to legs (not to jobs first)

Benefits:

  • Better discovery of consolidatable legs across the system
  • Independent filtering and selection
  • Company-level filtering support
  • More comprehensive leg selection

16.2 Vehicle Type Column

  • Added Vehicle Type column to legs table
  • Added Vehicle Type to sort options
  • Displays vehicle type information for each leg
  • Helps in consolidation planning

16.3 Enhanced Load Type Validation

  • Validates Load Type's can_handle_consolidation flag
  • Falls back to job's consolidate flag for backward compatibility
  • Ensures only truly consolidatable legs are shown

Conclusion

The Fetch>>Jobs implementation provides a comprehensive, user-friendly interface for finding and selecting transport jobs for consolidation. It balances functionality with performance through client-side filtering, intelligent caching, and a responsive UI design.

Recent enhancements have made the Legs View independent and more powerful, allowing users to discover and select consolidatable legs across the entire system, not just from currently visible jobs. The addition of Vehicle Type information and improved Load Type validation further enhances the consolidation workflow.

Getting Started

Setup and Settings

Sea Freight

Air Freight

Transport

Customs

Warehousing

Pricing Center

Job Management

Sustainability

Intercompany

Special Projects

Pages

Features

Reports

Glossary

Clone this wiki locally