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.phpsrc/app/Helpers/print_job_helper.phpsrc/app/Helpers/bag_helper.phpsrc/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_typeand availableeifs_block, invokes bag/sticker inventory deductions viamake_eifs_bags(), inserts a record inprint_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.
- Printed rows (
- Dynamic Label Naming:
- Standard EPS/GPS set
LotStickerEPS/LotStickerGPS. - Fractional dimensions change label name to
LotStickerEPSFrac/LotStickerGPSFrac. - Drainage option appends
DBto label name (e.g.LotStickerEPSDBorLotStickerEPSFracDB).
- Standard EPS/GPS set
- Loader Overlay:
- CSS
.loader-overlaydisplays an AJAX spinner during table loading and API calls.
- CSS
Database Schema
print_job Table
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_denominatorsize_count,size_total,job_count,job_total(Sequential zero-padded strings)print_type(Fixed at0for 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().