Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/raceliciouss/YUSEN-LIMO-WAREHOUSE/llms.txt

Use this file to discover all available pages before exploring further.

The functions documented on this page are defined in assets/app.js and collectively control all shipment data access, business logic aggregation, UI rendering, and QR camera scanning on authenticated pages. Because app.js is loaded as a classic (non-module) script, all of these functions are accessible as plain globals in the browser execution context.
These are page-level globals available in the browser console on any authenticated page (dashboard.html, inbound-outbound.html, inventory.html, etc.) that loads app.js. They are not exported as a module and cannot be imported.

Shipment Storage

getStoredShipments()

Reads the raw shipments array from the warehouseShipments key in Local Storage. Applies a one-time migration pass to backfill releaseDate, releaseTime, releasePlate, and releaseDriver fields on older outbound entries that pre-date those fields. Returns an empty array if:
  • The key does not exist in Local Storage.
  • The stored value cannot be parsed as JSON.
  • The parsed value is not an array.
Falls back to an in-memory array (inMemoryShipmentStore) if Local Storage throws an exception (e.g. in a sandboxed browser context).
const shipments = getStoredShipments();
console.log(`${shipments.length} shipment records found.`);

// Inspect the most recently saved record
const latest = shipments[0];
console.log(latest.hawb, latest.client, latest.savedAt);
Returns: Array<ShipmentRecord>

saveStoredShipments(shipments)

Serializes the provided array and writes it to the warehouseShipments key in Local Storage. Falls back to the in-memory store if the write fails (e.g. storage quota exceeded). After every successful or fallback write, the function dispatches the warehouse:data-updated custom event on window. Any listeners registered for this event — including refreshInventory and refreshActivity — will re-render automatically.
shipments
Array
required
The complete, updated array of raw shipment records to persist. Pass the full array, not a diff.
// Prepend a new shipment record and save
const shipments = getStoredShipments();
shipments.unshift({
  hawb: 'HAWB-2024-001',
  client: 'Acme Corp',
  transactionType: 'RECEIVING',
  qtyIn: '10',
  unit: 'BOX',
  location: 'Bay A',
  savedAt: Date.now()
});
saveStoredShipments(shipments);
// Triggers warehouse:data-updated → refreshInventory() and refreshActivity() fire automatically
Returns: undefined

Data Aggregation

aggregateShipmentsByReference(shipments)

Groups an array of raw shipment records by their combined HAWB/MAWB reference key. Each unique reference becomes a single aggregate object that accumulates inbound quantities (qtyInValue), outbound quantities (qtyOutValue), and a computed remainingValue. This function is the core business logic layer of the warehouse system. The inventory table, activity report, and dashboard metrics all consume its output.
shipments
Array
required
The raw array returned by getStoredShipments().
Each aggregate object in the returned array has the following shape:
{
  hawb:               string;
  mawb:               string;
  invoice:            string;
  client:             string;
  destination:        string;
  location:           string;
  transactionType:    string;
  module:             string;
  flight:             string;
  date:               string;           // most recent inbound/outbound date
  time:               string;
  receivedBy:         string;
  receivingPlate:     string;
  trucker:            string;
  driver:             string;
  cargoCondition:     string;
  cargoConditionIn:   string;           // cargo condition from latest inbound entry
  cargoConditionOut:  string;           // cargo condition from latest outbound entry
  cargoHandling:      string;           // resolved from in/out conditions
  status:             string;
  partialFull:        string;
  quantity:           string;
  unit:               string;
  qtyInValue:         number;           // sum of all inbound quantities
  qtyOutValue:        number;           // sum of all outbound quantities
  remainingValue:     number;           // qtyInValue - qtyOutValue
  outboundDetails:    OutboundDetail[]; // chronological list of outbound events
  releaseDate:        string;
  releaseTime:        string;
  releasePlate:       string;
  releaseDriver:      string;
  remarks:            string;
  dateIn:             string;           // most recent inbound date
  dateOut:            string;           // most recent outbound date
  savedAt:            number;           // numeric timestamp of the latest record in this group
}
outboundDetails is an array of individual release events sorted chronologically:
{
  date:    string;
  time:    string;
  qty:     string;  // formatted quantity + unit (e.g. "5 BOX")
  plate:   string;
  driver:  string;
  remarks: string;
  savedAt: number;
}
const aggregated = aggregateShipmentsByReference(getStoredShipments());

// Find all shipments with remaining stock
const inStock = aggregated.filter(item => item.remainingValue > 0);
console.log(`${inStock.length} items in warehouse.`);

// Inspect outbound history for a specific HAWB
const item = aggregated.find(s => s.hawb === 'HAWB-2024-001');
console.table(item?.outboundDetails);
Returns: Array<AggregateShipmentObject>

QR Payload Normalization

normalizeShipmentPayload(payload)

Maps the alias keys that may appear in a scanned QR payload to the canonical field names used by form inputs (via data-field attributes). This decouples external QR code schemas from internal form field names.
payload
object
required
A parsed JSON object from a QR code scan. Non-object values are treated as an empty source.
The function resolves each canonical field from an ordered list of aliases:
Canonical fieldAccepted alias keys
clientclient, Client, shipmentClient
destinationdestination, Destination, shipTo
hawbhawb, HAWB, hawbNumber, shipmentId
mawbmawb, MAWB, mawbNumber
invoiceinvoice, invoiceNumber, markings, marking
transactionTypetransactionType, transactionTypeName, transaction_type, transactionTypeLabel, transaction, type
plateNoplateNo, plate, plateNumber, vehiclePlate, vehiclePlateNo
datedate
timetime
// QR code payload from an external scanner
const raw = {
  HAWB: 'HBL-20240512-001',
  Client: 'Acme Corp',
  shipTo: 'Manila',
  vehiclePlate: 'ABC 1234',
  transaction: 'RECEIVING'
};

const normalized = normalizeShipmentPayload(raw);
console.log(normalized);
// {
//   hawb: 'HBL-20240512-001',
//   client: 'Acme Corp',
//   destination: 'Manila',
//   plateNo: 'ABC 1234',
//   transactionType: 'RECEIVING',
//   mawb: '', invoice: '', date: '', time: ''
// }
Returns: NormalizedPayloadObject — an object with exactly the nine canonical keys listed above.

populateShipmentForm(payload, context)

Writes the normalized payload values into the currently active shipment form. Field targeting is done via [data-field] attribute selectors. For <select> elements, it uses fuzzy matching (exact text/value first, then partial match). For plain inputs, it sets value directly and fires an input event. If date or time are missing from the payload, the function falls back to the current Philippine time (Asia/Manila timezone). If the HAWB/MAWB in the payload matches an existing stored shipment, the function additionally pre-fills the location and unit fields from that stored record.
payload
object
required
A parsed QR payload object — typically the raw scan output before or after normalization.
context
Element
Optional DOM element to scope field queries within (e.g. the active tab’s container). Defaults to document.querySelector('.tab-content.active'), then document.
// Manually populate the inbound form from a payload (e.g. from a file import)
const payload = {
  hawb: 'HBL-20240512-001',
  client: 'Acme Corp',
  transactionType: 'RECEIVING'
};
const inboundTab = document.getElementById('inbound-content');
populateShipmentForm(payload, inboundTab);
Returns: undefined

UI Rendering

renderDashboardData()

Reads the current shipment store, runs it through aggregateShipmentsByReference(), and updates the three metric cards and recent shipments list on dashboard.html. The metric cards updated are:
DOM element IDValue displayed
dashboardTotalShipmentsCount of unique aggregated shipment references
dashboardCargoInWarehouseSum of all remainingValue across aggregates
dashboardOutgoingTodayCount of aggregates with an outbound event dated today
The recent shipments table (#recentShipmentsBody) is populated with the 5 most recently saved aggregates, sorted by savedAt descending.
// Force a dashboard refresh after a manual data import
renderDashboardData();
Returns: undefined

refreshInventory()

Re-renders the inventory table on inventory.html from page 1, applying all active filter and sort controls. Internally calls renderInventoryPage(1). This variable is null on non-inventory pages and is assigned only after the inventory page’s DOMContentLoaded initialisation block runs. Always guard calls with a type check:
if (typeof refreshInventory === 'function') {
  refreshInventory();
}
refreshInventory is called automatically by saveStoredShipments() (via the warehouse:data-updated event listener) and is also bound to all filter/search input events on the inventory page. Returns: undefined

refreshActivity()

Re-renders the activity report table on the activity report section, applying current filters. Internally calls renderActivityPage(1). Like refreshInventory, this variable is null on pages where the activity report section is absent:
if (typeof refreshActivity === 'function') {
  refreshActivity();
}
Bound to search, date range, transaction type, and location filter inputs on the activity page. Also called automatically on warehouse:data-updated. Returns: undefined

QR Scanning

startQrScanner(modal, context)

Opens the QR scan modal, requests rear-facing camera access via navigator.mediaDevices.getUserMedia, and starts a requestAnimationFrame loop that decodes each video frame using the jsQR library.
modal
HTMLElement
required
The scan modal element (typically document.getElementById('scanModal')). The function queries for video#cameraPreview, .scan-camera, and .camera-fallback within this element.
context
Element
Optional DOM context passed to populateShipmentForm() when a QR code is successfully decoded and a form is present. Defaults to the active tab content.
When a QR code is decoded:
  • If the current page has a search input (#inventorySearchInput or #activitySearchInput), the scanned value is applied as a search filter instead of populating a form.
  • Otherwise, populateShipmentForm() is called with the decoded payload.
  • The modal is closed and the camera stream is stopped.
If the browser or device does not support getUserMedia at all, the .camera-fallback element displays "Camera not supported on this device or browser." If the API is available but the user denies permission (or another runtime error occurs), the fallback displays "Unable to access camera. Please allow camera permission or use a compatible device."
// Programmatically trigger the QR scanner (mirrors the scan button click handler)
const modal = document.getElementById('scanModal');
modal.style.display = 'flex';
const activeTab = document.querySelector('.tab-content.active');
await startQrScanner(modal, activeTab);
Returns: Promise<void> (async function)
startQrScanner requires the jsQR library to be loaded on the page (window.jsQR must be a function). The library is included via a <script> tag in each HTML page that supports scanning.

Profile Storage

saveStoredProfile(profile)

Persists a profile object to the warehouseProfile key in Local Storage, then updates all profile-related UI elements on the page (updateProfileUi is called internally). Fields from the current AuthService session (employeeId, position, and name) are merged into the profile automatically, ensuring the stored profile stays consistent with the auth account record.
profile
object
required
Profile data object. Recognized fields: firstName, lastName, employeeId, position, email, phone. Missing fields fall back to the default profile values.
saveStoredProfile({
  firstName: 'Joseph',
  lastName: 'Dela Cruz',
  email: 'joseph@warehouse.com',
  phone: '+63 912 345 6789'
});
Returns: undefined

Build docs developers (and LLMs) love