Skip to main content

RoboPack Technical Architecture

Architecture Overview​

The RoboPack system is an automated bag labeling and inventory tracking feature for EIFS (Exterior Insulation and Finish System) production runs. It connects CodeIgniter 4 views, Tabulator.js tables, REST API endpoints, and BarTender integration to auto-generate label print jobs, deduct raw materials from inventory, and associate created bags with specific EIFS cutting jobs.

Front-End (Tabulator / JS) -> POST /api/print_job/send -> CodeIgniter API -> Insert print_job (print_type=0) & Deduct Inventory -> BarTender Integration -> Zebra Printer

Source Files​

  • Views:
    • src/app/Views/robopack/robo_pack_jobs.php (Job selection dashboard)
    • src/app/Views/robopack/robo_pack_in_progress.php (Station workstation)
    • src/app/Views/eifs/eifs_in_progress.php (Includes Link Robopack Job modal #link_robopack_modal)
  • Controllers:
    • src/app/Controllers/Robopack.php (Page rendering)
    • src/app/Controllers/Api/PrintJob.php (Label generation API)
    • src/app/Controllers/Api/EifsJob.php (Active jobs & batch coordination API)
    • src/app/Controllers/Api/EifsBag.php (EIFS bag creation API)
  • JavaScript & Styling:
    • src/public/js/robopack/robo_pack_in_progress.js (Tabulator initialization & AJAX posting)
    • src/public/js/eifs/eifs_in_progress.js (Robopack job linking handler)
    • src/public/css/eifs/robo_pack_in_progress.css (Styles & loader overlay)
  • Helpers:
    • src/app/Helpers/eifs_helper.php
    • src/app/Helpers/print_job_helper.php
    • src/app/Helpers/bag_helper.php
    • src/app/Helpers/sticker_helper.php

Controllers & Routes​

App\Controllers\Robopack​

jobs()​

  • Route: /robopack/jobs (GET)
  • Description: Queries incomplete EIFS jobs and renders the job selection view.
public function jobs(): string
{
$title['title'] = "Robo Pack";
$data['jobs'] = Job_model::has('eifs_jobs')->where('finish', NULL)
->with('eifs_jobs.sales_order')->get();
$data['warning'] = json_encode($_SESSION);

return view('templates/header', $title) .
view('robopack/robo_pack_jobs', $data) .
view('templates/footer');
}

in_progress(int $job_id)​

  • Route: /robopack/in_progress/{job_id} (GET)
  • Description: Renders the main RoboPack station workstation for a given job ID.
public function in_progress(int $job_id): string|RedirectResponse
{
$this->validation->setRule("job_id", "Job ID", "required|numeric|is_not_unique[job.id]");

if (!$this->validation->run(['job_id' => $job_id])) {
log_message("error", __CLASS__ . "::" . __FUNCTION__ . "() - Validation errors: " . json_encode($this->validation->getErrors(), JSON_PRETTY_PRINT));
return redirect()->back()->withInput()->with('errors', $this->validation->getErrors());
}

$job = Job_model::with('eifs_job')->find($job_id);

if ($job['finish'] !== NULL) {
log_message('warning', 'Attempted to start a ROBOPACK/EIFS job with ID : ' . $job_id . ' that was already complete');
return redirect()->with("messages", ["Robopack job with ID" . $job_id . " already complete"])->to('/robopack/jobs');
} else {
$data['user'] = auth()->user();
$data['job'] = $job;
$data['target_total'] = Eifs_bag_target_model::getJobTargetTotal($job_id);
$data['targets'] = Eifs_bag_target_model::with('eifs_bag_type')
->where('job_id', $job_id)
->where('quantity', '>', 0)->get();

$title['title'] = "Robo Pack In Progress";

return view('templates/header', $title) .
view('robopack/robo_pack_in_progress', $data) .
view('templates/footer');
}
}

API Endpoints​

App\Controllers\Api\PrintJob​

send()​

  • Route: POST /api/print_job/send
  • Description: Validates print job payload, calculates sequential label indices, resolves matching eifs_bag_type and available eifs_block, invokes bag/sticker inventory deductions via make_eifs_bags(), inserts a record in print_job (print_type = 0), and responds with the created record.

Validation Rules:

'resend'             => 'required|numeric|in_list[0,1]',
'size_value' => 'required|numeric|greater_than_equal_to[0]',
'size_numerator' => 'required|numeric|greater_than_equal_to[0]',
'size_denominator' => 'required|numeric|greater_than_equal_to[0]',
'quantity' => 'required|numeric|greater_than[0]',
'job_id' => 'required|numeric|is_not_unique[job.id]',
'label_name' => 'required|alpha_numeric_punct|max_length[255]',
'type' => 'required|string|in_list[eps,EPS,gps,GPS]',
'bag_type' => 'required|alpha_numeric_punct|min_length[2]|max_length[255]',
'is_drainage' => 'required|alpha|in_list[true,false]',
'sales_order' => 'permit_empty|is_not_unique[sales_order.label]',
'linked_eifs_job_id' => 'permit_empty|numeric|is_not_unique[eifs_job.id]'

Job Linking Resolution: When linked_eifs_job_id is supplied in the request body from the front-end, it is used as the $add_job_id when invoking make_eifs_bags() (falling back to $job->eifs_job->id if absent).

get_label_info()​

  • Route: POST /api/print_job/get_label_info
  • Description: Queries completed print jobs for an EIFS job and aggregates pending targets into Tabulator-ready data structures.

App\Controllers\Api\EifsJob​

get_active_with_batches()​

  • Route: POST /api/eifs_job/get_active_with_batches
  • Description: Returns all active EIFS jobs (started = 1, finish IS NULL) that have a production batch assigned, enabling RoboPack operators to coordinate printing with specific production runs.

Helper Functions​

find_eifs_bag_type()​

function find_eifs_bag_type(int $size_num, int $size_numerator, int $size_denominator, string $print_label): int

Converts numeric size components and material type into the corresponding eifs_bag_type record ID.

get_eifs_label()​

function get_eifs_label(string $type, int $size, int $num = -1, int $denom = -1): string|null

Constructs standardized label strings (e.g. "EPS 2 1/2\"" or "GPS 4\"").

find_eifs_block_id()​

function find_eifs_block_id(int $job_id, int $eifs_bag_type_id): int

Locates an available eifs_block for the given job that currently has fewer than 12 bags associated with it.

make_eifs_bags()​

function make_eifs_bags(string $bag_type_label, int $quantity, int $job_id, int $eifs_bag_type_id, int $eifs_block_id = null, int $add_job_id = null): void

Generates eifs_bag records (passing $add_job_id to link the bag to the appropriate EIFS job) and calls remove_sticker() and remove_bag() to deduct raw materials from inventory.


Front-End Scripting & Components​

The workstation page (#robo_pack_table) relies on Tabulator.js using layout: "fitColumns".

  • Row Formatting:
    • Printed rows (done === 1) are assigned a green background (rgba(125,255,99,0.54)).
    • Unprinted rows remain white.
  • Dynamic Label Naming:
    • Standard EPS/GPS set LotStickerEPS / LotStickerGPS.
    • Fractional dimensions change label name to LotStickerEPSFrac / LotStickerGPSFrac.
    • Drainage option appends DB to label name (e.g. LotStickerEPSDB or LotStickerEPSFracDB).
  • Loader Overlay:
    • CSS .loader-overlay displays an AJAX spinner during table loading and API calls.

Database Schema​

Primary audit log and queue table read by BarTender.

  • id (PK)
  • job_id (FK -> job)
  • label_name (BarTender template name)
  • copies (Quantity to print)
  • sales_order (Sales order label string)
  • size_value, size_numerator, size_denominator
  • size_count, size_total, job_count, job_total (Sequential zero-padded strings)
  • print_type (Fixed at 0 for RoboPack)

eifs_bag Table​

Records individual EIFS bags created in inventory.

  • id (PK)
  • eifs_bag_type_id (FK -> eifs_bag_type)
  • bag_type_id (FK -> bag_type)
  • eifs_block_id (FK -> eifs_block)
  • add_job_id (FK -> job, set to active linked EIFS job)
  • production_batch (Optional production batch string identifier)

eifs_bag_target Table​

Target bag counts per size for a given job.

eifs_block Table​

Cut block instances (yields ~12 bags per block).


Authentication & Error Handling​

  • Authentication: Enforced via CodeIgniter Shield (auth()->user()).
  • Validation: Failed API requests return standard JSON validation errors.
  • Logging: Operations write to system logs via log_message().