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().