// data.jsx — dummy data + RBAC matrix // === Master data: Categories ========================================= const CATEGORIES = [ { id: 'mc', name: 'Mobile Crane', color: '#0B1F3A' }, { id: 'sl', name: 'Skylift', color: '#2B6CB0' }, { id: 'scl', name: 'Scissor Lift', color: '#0E7C66' }, { id: 'lc', name: 'Lorry Crane', color: '#B45309' }, { id: 'lr', name: 'Lorry', color: '#6B4F2A' }, { id: 'bl', name: 'Boom Lift', color: '#7C3AED' }, { id: 'fl', name: 'Forklift', color: '#0F766E' }, { id: 'rt', name: 'Rough Terrain Crane', color: '#9B1C1C' }, { id: 'cr', name: 'Cross Rent', color: '#6D28D9' }, { id: 'ut', name: 'Utility', color: '#475569' }, { id: 'car', name: 'Car', color: '#1D4ED8' }, ]; // === Master data: Machines =========================================== // machine_status: 'available' | 'occupied' | 'unavailable' // available = green dot, ready to assign // occupied = red dot, currently on a booking // unavailable= grey dot, in workshop / leave / standby // Each machine has an `operator` field — the default driver assigned to that // machine. Used by Create Booking to auto-fill the operator when an available // machine row is picked from Current Bookings. const MACHINES = [ // === MOBILE CRANES + RT CRANE ===================================== { id: 'PLC-001', name: '8382 (50T)', plate: 'JSB 8382', category: 'Mobile Crane', tonnage: '50T', status: 'occupied', operator: 'Muthu' }, { id: 'PLC-002', name: '6382 (45T)', plate: 'BLR 6382', category: 'Mobile Crane', tonnage: '45T', status: 'available', operator: 'Zorkapli' }, { id: 'PLC-003', name: '7838 (120T)', plate: 'JYH 7838', category: 'Mobile Crane', tonnage: '120T', status: 'occupied', operator: 'Zul30ton' }, { id: 'PLC-004', name: '1484 (20T)', plate: 'WHN 1484', category: 'Mobile Crane', tonnage: '20T', status: 'available', operator: 'Hairul' }, { id: 'PLC-005', name: '9744 (20T)', plate: 'JGA 9744', category: 'Mobile Crane', tonnage: '20T', status: 'occupied', operator: 'Rajah' }, { id: 'PLC-006', name: '4758 (20T)', plate: 'JFW 4758', category: 'Mobile Crane', tonnage: '20T', status: 'occupied', operator: 'Izzul' }, { id: 'PLC-007', name: '9552 (20T)', plate: 'WDE 9552', category: 'Mobile Crane', tonnage: '20T', status: 'available', operator: 'Teon' }, { id: 'PLC-008', name: '8908 (25T)', plate: 'AMX 8908', category: 'Rough Terrain Crane', tonnage: '25T', status: 'occupied', operator: 'Hisham' }, { id: 'PLC-009', name: '8569 (20T)', plate: 'JEF 8569', category: 'Mobile Crane', tonnage: '20T', status: 'occupied', operator: 'Rohezal' }, { id: 'PLC-010', name: '4368 (20T)', plate: 'JFR 4368', category: 'Mobile Crane', tonnage: '20T', status: 'unavailable', operator: 'Ganis' }, { id: 'PLC-011', name: '5114 (20T)', plate: 'JEM 5114', category: 'Mobile Crane', tonnage: '20T', status: 'occupied', operator: 'Kanisan' }, { id: 'PLC-012', name: '8172 (20T)', plate: 'JCN 8172', category: 'Mobile Crane', tonnage: '20T', status: 'available', operator: 'Selva' }, { id: 'PLC-013', name: '284 (20T)', plate: 'WEC 284', category: 'Mobile Crane', tonnage: '20T', status: 'available', operator: 'Shafiq' }, { id: 'PLC-014', name: '239 (20T)', plate: 'JEQ 239', category: 'Mobile Crane', tonnage: '20T', status: 'occupied', operator: 'Yusof' }, { id: 'PLC-015', name: '3135 (7T)', plate: 'BRS 3135', category: 'Mobile Crane', tonnage: '7T', status: 'unavailable', operator: 'Radzi' }, // === SKYLIFTS ===================================================== { id: 'PLC-016', name: '5936 (45M)', plate: 'CEU 5936', category: 'Skylift', tonnage: '45M', status: 'available', operator: 'Jembri' }, { id: 'PLC-017', name: '9437 (26M)', plate: 'BKV 9437', category: 'Skylift', tonnage: '26M', status: 'occupied', operator: 'Ahmad' }, { id: 'PLC-018', name: '328 (24M)', plate: 'BHX 328', category: 'Skylift', tonnage: '24M', status: 'available', operator: 'Hanapi' }, { id: 'PLC-019', name: '2122 (22M)', plate: 'JMA 2122', category: 'Skylift', tonnage: '22M', status: 'occupied', operator: 'Azizi' }, { id: 'PLC-020', name: '9418 (20M)', plate: 'JEM 9418', category: 'Skylift', tonnage: '20M', status: 'available', operator: 'Richard' }, // === SCISSOR LIFT ================================================= { id: 'SCL-001', name: 'GS-3246.1', plate: '—', category: 'Scissor Lift', tonnage: '—', status: 'available', operator: '' }, // === CROSS RENT (machines rented from other companies) ============ { id: 'CR-001', name: 'Cross Rent 1', plate: 'Cross Rent 1', category: 'Cross Rent', tonnage: '—', status: 'available', operator: '' }, { id: 'CR-002', name: 'Cross Rent 2', plate: 'Cross Rent 2', category: 'Cross Rent', tonnage: '—', status: 'available', operator: '' }, { id: 'CR-003', name: 'Cross Rent 3', plate: 'Cross Rent 3', category: 'Cross Rent', tonnage: '—', status: 'available', operator: '' }, { id: 'CR-004', name: 'Cross Rent 4', plate: 'Cross Rent 4', category: 'Cross Rent', tonnage: '—', status: 'available', operator: '' }, { id: 'CR-005', name: 'Cross Rent 5', plate: 'Cross Rent 5', category: 'Cross Rent', tonnage: '—', status: 'available', operator: '' }, { id: 'CR-006', name: 'Cross Rent 6', plate: 'Cross Rent 6', category: 'Cross Rent', tonnage: '—', status: 'available', operator: '' }, // === CARS (company vehicles) ====================================== { id: 'CAR-001', name: 'JLU5315', plate: 'JLU5315', category: 'Car', tonnage: '—', status: 'available', operator: '' }, { id: 'CAR-002', name: 'JJA1906', plate: 'JJA1906', category: 'Car', tonnage: '—', status: 'available', operator: '' }, { id: 'CAR-003', name: 'JMR3817', plate: 'JMR3817', category: 'Car', tonnage: '—', status: 'available', operator: '' }, { id: 'CAR-004', name: 'WVT2370', plate: 'WVT2370', category: 'Car', tonnage: '—', status: 'available', operator: '' }, ]; // === Machine display label =========================================== // Every machine is shown across the app by its fleet number + tonnage with // no space, e.g. "8382(50T)". Non-tonnage assets (scissor lifts, cross rent, // cars) fall back to their name/plate. function machineLabel(m) { if (!m) return ''; if (m.tonnage && m.tonnage !== '—') { const num = (m.name || '').split(' ')[0]; // numeric fleet no. e.g. "8382" return `${num}(${m.tonnage})`; // → "8382(50T)" } return (m.plate && m.plate !== '—') ? m.plate : m.name; } // Resolve a booking (machine = "PLC-005 …" + bare plate) to the same label. function bookingMachineLabel(b) { const id = ((b && b.machine) || '').split(' ')[0]; const m = MACHINES.find(x => x.id === id); if (m) return machineLabel(m); return (b && b.machine) ? b.machine.replace(/^[A-Z]+-\d+\s+/, '') : ''; } // === Master data: Customers ========================================== // Each customer has a list of contacts (each with phone) and a list of // frequently-used job-site locations. Selecting a customer in Create // Booking filters the contact dropdown to that customer's contacts; the // linked phone auto-fills when a contact is selected. const CUSTOMERS = [ { id: 'C-001', name: 'Ace Engineering', jobs: 24, email: 'accounts@aceeng.com.my', contacts: [ { name: 'Lim Wei Ming', phone: '+60 12-345 6789', email: 'wm.lim@aceeng.com.my' }, { name: 'James Lim', phone: '+60 12-988 1122', email: 'james@aceeng.com.my' }, ], locations: ['Pasir Gudang Industrial Park, Lot 14B', 'PGI Phase 2', 'PGI Phase 3'], }, { id: 'C-002', name: 'Greenword Sdn Bhd', jobs: 31, email: 'admin@greenword.com.my', contacts: [ { name: 'Sarah Tan', phone: '+60 13-887 2210', email: 'sarah.tan@greenword.com.my' }, { name: 'Goh Wei Han', phone: '+60 12-664 7733', email: 'wh.goh@greenword.com.my' }, ], locations: ['Medini Iskandar, Plot J-7', 'Medini Iskandar, Plot K-2'], }, { id: 'C-003', name: 'QRE Logistics', jobs: 18, email: 'ops@qrelogistics.com', contacts: [ { name: 'David Ng', phone: '+60 17-223 4456', email: 'david.ng@qrelogistics.com' }, { name: 'Sharon Yeoh', phone: '+60 16-554 9988', email: 'sharon@qrelogistics.com' }, ], locations: ['PTP Berth 8, container yard', 'PTP Berth 8 Yard'], }, { id: 'C-004', name: 'DYC Aviation', jobs: 9, email: 'cargo@dycaviation.com', contacts: [ { name: 'Aminah Yusof', phone: '+60 19-554 8821', email: 'aminah@dycaviation.com' }, ], locations: ['Senai Airport Cargo Terminal 2', 'Senai Cargo Terminal 1'], }, { id: 'C-005', name: 'KSB Builders', jobs: 14, email: 'projects@ksbbuilders.com.my', contacts: [ { name: 'Tan Chee Keong', phone: '+60 12-998 7766', email: 'ck.tan@ksbbuilders.com.my' }, { name: 'Lee Boon Hin', phone: '+60 11-664 2299', email: 'bh.lee@ksbbuilders.com.my' }, ], locations: ['Bukit Indah Phase 4, Block C', 'Bukit Indah Phase 4, Block D'], }, { id: 'C-006', name: 'MTC Petrochem', jobs: 7, email: 'procurement@mtcpetrochem.com', contacts: [ { name: 'Khairul Anwar', phone: '+60 13-445 9911', email: 'khairul@mtcpetrochem.com' }, ], locations: ['Tanjung Langsat Terminal Bay 3'], }, { id: 'C-007', name: 'JEC Industrial', jobs: 11, email: 'enquiry@jecindustrial.com.my', contacts: [ { name: 'Vincent Lee', phone: '+60 14-552 2299', email: 'vincent.lee@jecindustrial.com.my' }, ], locations: ['Kulai PLO 12, Lot 88', 'Kulai PLO 12, Lot 22', 'Kulai PLO 12, Lot 90'], }, ]; // Global pool of all recurring site locations across customers const LOCATIONS = [ ...new Set(CUSTOMERS.flatMap(c => c.locations)) ]; // === Customer price list ============================================ // Per-customer negotiated day-rates (RM) for every machine type Pow Lee // hires out. Each row carries the CURRENT given price + the date it took // effect, plus the PREVIOUS price and its date — so Account & Finance can // see how a customer's rate has moved over time. // // PRICE_MACHINE_TYPES is the canonical priceable catalogue; the actual // per-customer numbers are generated deterministically (seeded by // customer + machine type) so they stay stable across renders. const PRICE_MACHINE_TYPES = [ { id: 'mc-20', category: 'Mobile Crane', spec: '20T', base: 1200 }, { id: 'mc-25', category: 'Mobile Crane', spec: '25T', base: 1500 }, { id: 'mc-45', category: 'Mobile Crane', spec: '45T', base: 2400 }, { id: 'mc-50', category: 'Mobile Crane', spec: '50T', base: 2800 }, { id: 'mc-120', category: 'Mobile Crane', spec: '120T', base: 6500 }, { id: 'rt-25', category: 'Rough Terrain Crane', spec: '25T', base: 1800 }, { id: 'sl-20', category: 'Skylift', spec: '20M', base: 700 }, { id: 'sl-22', category: 'Skylift', spec: '22M', base: 800 }, { id: 'sl-24', category: 'Skylift', spec: '24M', base: 900 }, { id: 'sl-26', category: 'Skylift', spec: '26M', base: 1000 }, { id: 'sl-45', category: 'Skylift', spec: '45M', base: 1800 }, { id: 'scl', category: 'Scissor Lift', spec: 'GS-3246', base: 350 }, { id: 'lc', category: 'Lorry Crane', spec: '10T', base: 950 }, { id: 'bl', category: 'Boom Lift', spec: '16M', base: 1100 }, { id: 'fl', category: 'Forklift', spec: '3T', base: 600 }, ]; // FNV-1a hash → stable unsigned int from a string seed function _priceSeed(str) { let h = 2166136261; for (let i = 0; i < str.length; i++) { h ^= str.charCodeAt(i); h = Math.imul(h, 16777619); } return h >>> 0; } const _round50 = (n) => Math.round(n / 50) * 50; const _isoMinus = (iso, months) => { const d = new Date(iso + 'T12:00:00'); d.setMonth(d.getMonth() - months); const y = d.getFullYear(), m = String(d.getMonth() + 1).padStart(2, '0'), dd = String(d.getDate()).padStart(2, '0'); return `${y}-${m}-${dd}`; }; // Build the price rows for one customer. function priceListFor(customerId) { return PRICE_MACHINE_TYPES.map(t => { const s = _priceSeed(customerId + '|' + t.id); // Negotiated factor 0.90–1.10 off the catalogue base const factor = 0.90 + (s % 21) / 100; const current = _round50(t.base * factor); // Whether the price changed at the last revision (≈75% did) const changed = (s % 4) !== 0; // Last revision was a 4–11% lower price (rates trend upward over time) const incrPct = 4 + (s % 8); const last = changed ? _round50(current / (1 + incrPct / 100)) : current; // Current price effective 1–10 months ago; previous 12–20 months before that const curMonthsAgo = 1 + (s % 10); const priceDate = _isoMinus(TODAY, curMonthsAgo); const lastDate = _isoMinus(priceDate, 12 + (s % 9)); return { typeId: t.id, category: t.category, spec: t.spec, current, priceDate, last, lastDate, changed, }; }); } // === Operator certifications ======================================== // Short codes shown as coloured dots in the operator picker. The legend // (code → label + colour) is rendered at the top of the dropdown so // dispatch can read the dots at a glance while assigning a job. const CERT_LEGEND = [ { code: 'NTSP', label: 'NIOSH Tower Safety Passport', color: '#2563EB' }, { code: 'OGSP', label: 'Oil & Gas Safety Passport', color: '#0891B2' }, { code: 'CIDB', label: 'CIDB Green Card', color: '#059669' }, { code: 'JKKP', label: 'JKKP / DOSH Competency (PMA)', color: '#D97706' }, { code: 'H', label: 'Class H — Heavy machinery', color: '#7C3AED' }, { code: 'E', label: 'Class E — Heavy vehicle', color: '#DC2626' }, { code: 'D', label: 'Class D — Car / light', color: '#DB2777' }, { code: 'B2', label: 'Class B2 — Motorcycle', color: '#0B1F3A' }, ]; const CERT_COLOR = Object.fromEntries(CERT_LEGEND.map(c => [c.code, c.color])); const CERT_LABEL = Object.fromEntries(CERT_LEGEND.map(c => [c.code, c.label])); // === Master data: Operators (drivers) ================================ // Each cert now carries an expiry date (`exp`, ISO yyyy-mm-dd). Expired // certs are hidden from the operator picker; certs expiring within // CERT_RENEW_WINDOW_DAYS trigger a renewal reminder notification. const OPERATORS = [ { id: 'OP-01', name: 'Muthu', phone: '+60 17-554 1188', license: 'OPL-A-2241', status: 'On Job', certs: [{code:'NTSP',exp:'2027-03-15'},{code:'JKKP',exp:'2026-07-20'},{code:'CIDB',exp:'2027-01-10'},{code:'H',exp:'2028-05-01'},{code:'E',exp:'2028-05-01'}] }, { id: 'OP-02', name: 'Zorkapli', phone: '+60 12-998 7766', license: 'OPL-A-2198', status: 'Available', certs: [{code:'NTSP',exp:'2026-11-05'},{code:'CIDB',exp:'2027-06-12'},{code:'H',exp:'2029-02-20'},{code:'E',exp:'2029-02-20'}] }, { id: 'OP-03', name: 'Zul30ton', phone: '+60 19-554 8821', license: 'OPL-A-2305', status: 'On Job', certs: [{code:'NTSP',exp:'2026-06-28'},{code:'OGSP',exp:'2027-04-18'},{code:'JKKP',exp:'2027-09-30'},{code:'CIDB',exp:'2026-12-01'},{code:'H',exp:'2028-08-15'},{code:'E',exp:'2028-08-15'}] }, { id: 'OP-04', name: 'Hairul', phone: '+60 11-887 9911', license: 'OPL-A-2155', status: 'Available', certs: [{code:'NTSP',exp:'2027-02-14'},{code:'JKKP',exp:'2026-05-12'},{code:'H',exp:'2028-03-22'},{code:'E',exp:'2028-03-22'}] }, { id: 'OP-05', name: 'Rajah', phone: '+60 16-223 4456', license: 'OPL-A-2410', status: 'On Job', certs: [{code:'NTSP',exp:'2027-07-08'},{code:'CIDB',exp:'2027-03-19'},{code:'OGSP',exp:'2026-07-30'},{code:'H',exp:'2028-11-01'},{code:'E',exp:'2028-11-01'}] }, { id: 'OP-06', name: 'Izzul', phone: '+60 13-441 7782', license: 'OPL-A-2433', status: 'On Job', certs: [{code:'NTSP',exp:'2028-01-25'},{code:'JKKP',exp:'2027-05-14'},{code:'CIDB',exp:'2027-08-09'},{code:'H',exp:'2029-04-12'},{code:'E',exp:'2029-04-12'},{code:'D',exp:'2030-06-30'}] }, { id: 'OP-07', name: 'Teon', phone: '+60 17-220 9914', license: 'OPL-A-2451', status: 'Available', certs: [{code:'NTSP',exp:'2027-10-03'},{code:'OGSP',exp:'2027-12-20'},{code:'JKKP',exp:'2026-07-11'},{code:'CIDB',exp:'2027-02-28'},{code:'H',exp:'2028-09-19'},{code:'E',exp:'2028-09-19'}] }, { id: 'OP-08', name: 'Hisham', phone: '+60 12-665 3320', license: 'OPL-A-2477', status: 'On Job', certs: [{code:'NTSP',exp:'2026-04-22'},{code:'CIDB',exp:'2027-05-30'},{code:'H',exp:'2028-07-07'},{code:'E',exp:'2028-07-07'}] }, { id: 'OP-09', name: 'Rohezal', phone: '+60 19-883 1156', license: 'OPL-A-2489', status: 'On Job', certs: [{code:'NTSP',exp:'2027-06-15'},{code:'JKKP',exp:'2027-11-22'},{code:'H',exp:'2028-12-30'},{code:'E',exp:'2028-12-30'}] }, { id: 'OP-10', name: 'Ganis', phone: '+60 14-552 6610', license: 'OPL-A-2502', status: 'Available', certs: [{code:'NTSP',exp:'2027-09-01'},{code:'CIDB',exp:'2026-07-25'},{code:'H',exp:'2029-01-18'},{code:'E',exp:'2029-01-18'},{code:'D',exp:'2030-03-12'}] }, { id: 'OP-11', name: 'Kanisan', phone: '+60 16-770 4488', license: 'OPL-A-2518', status: 'On Job', certs: [{code:'NTSP',exp:'2027-04-09'},{code:'OGSP',exp:'2027-08-14'},{code:'CIDB',exp:'2027-12-05'},{code:'H',exp:'2028-10-22'},{code:'E',exp:'2028-10-22'}] }, { id: 'OP-12', name: 'Selva', phone: '+60 17-331 2299', license: 'OPL-A-2530', status: 'Available', certs: [{code:'NTSP',exp:'2027-01-30'},{code:'JKKP',exp:'2027-07-19'},{code:'H',exp:'2028-06-25'},{code:'E',exp:'2028-06-25'}] }, { id: 'OP-13', name: 'Shafiq', phone: '+60 11-225 8843', license: 'OPL-A-2547', status: 'Available', certs: [{code:'NTSP',exp:'2026-12-12'},{code:'CIDB',exp:'2027-03-08'},{code:'H',exp:'2028-08-30'},{code:'E',exp:'2028-08-30'}] }, { id: 'OP-14', name: 'Yusof', phone: '+60 13-558 1102', license: 'OPL-A-2561', status: 'On Job', certs: [{code:'NTSP',exp:'2027-05-20'},{code:'JKKP',exp:'2027-10-11'},{code:'CIDB',exp:'2027-06-28'},{code:'OGSP',exp:'2026-07-18'},{code:'H',exp:'2029-03-05'},{code:'E',exp:'2029-03-05'}] }, { id: 'OP-15', name: 'Radzi', phone: '+60 12-884 7790', license: 'OPL-A-2578', status: 'Available', certs: [{code:'NTSP',exp:'2027-08-22'},{code:'CIDB',exp:'2027-11-14'},{code:'H',exp:'2028-05-17'},{code:'E',exp:'2028-05-17'}] }, { id: 'OP-16', name: 'Jembri', phone: '+60 19-446 2218', license: 'OPL-S-3104', status: 'Available', certs: [{code:'NTSP',exp:'2027-02-26'},{code:'JKKP',exp:'2027-09-03'},{code:'H',exp:'2028-12-08'},{code:'D',exp:'2029-10-20'}] }, { id: 'OP-17', name: 'Ahmad', phone: '+60 17-882 5531', license: 'OPL-S-3122', status: 'On Job', certs: [{code:'NTSP',exp:'2027-07-30'},{code:'CIDB',exp:'2027-04-25'},{code:'H',exp:'2028-11-19'},{code:'D',exp:'2029-08-14'},{code:'B2',exp:'2030-01-09'}] }, { id: 'OP-18', name: 'Hanapi', phone: '+60 16-334 9907', license: 'OPL-S-3140', status: 'Available', certs: [{code:'NTSP',exp:'2026-07-05'},{code:'JKKP',exp:'2027-06-21'},{code:'H',exp:'2028-09-28'},{code:'D',exp:'2029-12-15'}] }, { id: 'OP-19', name: 'Azizi', phone: '+60 11-559 6643', license: 'OPL-S-3158', status: 'On Job', certs: [{code:'NTSP',exp:'2027-03-11'},{code:'CIDB',exp:'2027-08-27'},{code:'H',exp:'2028-07-23'},{code:'D',exp:'2029-05-30'}] }, { id: 'OP-20', name: 'Richard', phone: '+60 14-221 7785', license: 'OPL-S-3171', status: 'Available', certs: [{code:'NTSP',exp:'2027-10-18'},{code:'OGSP',exp:'2027-05-09'},{code:'H',exp:'2028-10-04'},{code:'D',exp:'2029-09-22'},{code:'B2',exp:'2030-02-28'}] }, ]; // === Certification expiry helpers =================================== // Fixed "today" keeps the demo deterministic; swap for `new Date()` live. const CERT_TODAY = new Date('2026-06-04'); const CERT_RENEW_WINDOW_DAYS = 60; // ~2 months — remind before a cert lapses function certDaysLeft(iso, now = CERT_TODAY) { return Math.round((new Date(iso + 'T00:00:00') - now) / 86400000); } function certState(iso, now = CERT_TODAY) { const left = certDaysLeft(iso, now); if (left < 0) return 'expired'; if (left <= CERT_RENEW_WINDOW_DAYS) return 'expiring'; return 'valid'; } // Certs fit to show — expired ones are dropped entirely. function activeCerts(certs, now = CERT_TODAY) { return (certs || []).filter(c => certState(c.exp, now) !== 'expired'); } function fmtCertDate(iso) { if (!iso) return '—'; return new Date(iso + 'T00:00:00').toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' }); } // Flat, soonest-first list of renewals due (expiring) or overdue (expired) // across all operators — feeds the renewal reminders in Notifications. function certReminders(operators = OPERATORS, now = CERT_TODAY) { const out = []; operators.forEach(o => (o.certs || []).forEach(c => { const state = certState(c.exp, now); if (state === 'expiring' || state === 'expired') { out.push({ operator: o.name, opId: o.id, code: c.code, label: CERT_LABEL[c.code] || c.code, exp: c.exp, days: certDaysLeft(c.exp, now), state }); } })); return out.sort((a, b) => a.days - b.days); } const RIGGERS = [ { id: 'RG-01', name: 'Ahmad Faizal', phone: '+60 13-445 9911', cert: 'NIOSH-RG-1102', status: 'On Job' }, { id: 'RG-02', name: 'Subash Kumar', phone: '+60 14-552 2299', cert: 'NIOSH-RG-1105', status: 'On Job' }, { id: 'RG-03', name: 'Bala Krishnan', phone: '+60 17-223 4456', cert: 'NIOSH-RG-1108', status: 'Available' }, { id: 'RG-04', name: 'Pravin Raj', phone: '+60 12-887 2210', cert: 'NIOSH-RG-1112', status: 'On Job' }, ]; // === Master data: Site Tools / Equipment ============================ // Admin-managed list of accessories an operator may need to bring on site. // Surfaced in Create Booking as a multi-select; managed from Administration → Tools. const TOOLS = [ { id: 'T-01', name: 'Outrigger Pads (steel)', category: 'Stability', default: true }, { id: 'T-02', name: 'Outrigger Pads (timber)', category: 'Stability', default: false }, { id: 'T-03', name: 'Spreader Bar — 2t', category: 'Rigging', default: false }, { id: 'T-04', name: 'Spreader Bar — 5t', category: 'Rigging', default: false }, { id: 'T-05', name: 'Wire Sling — 3m', category: 'Rigging', default: false }, { id: 'T-06', name: 'Wire Sling — 6m', category: 'Rigging', default: false }, { id: 'T-07', name: 'Chain Block — 1t', category: 'Rigging', default: false }, { id: 'T-08', name: 'Bow Shackle 17t', category: 'Rigging', default: false }, { id: 'T-09', name: 'Wheel Chocks', category: 'Safety', default: true }, { id: 'T-10', name: 'Safety Cones (10×)', category: 'Safety', default: true }, { id: 'T-11', name: 'Barrier Tape Roll', category: 'Safety', default: false }, { id: 'T-12', name: 'Spotter Radio (pair)', category: 'Comms', default: false }, { id: 'T-13', name: 'Diesel Jerry Can 20L', category: 'Fuel', default: false }, ]; // === Shift options =================================================== // Three only — locked by user requirement const SHIFT_OPTIONS = [ { id: 'fullday', label: '8am – 5pm', start: '08:00', end: '17:00' }, { id: 'morning', label: '8am – 12pm', start: '08:00', end: '12:00' }, { id: 'afternoon', label: '1pm – 5pm', start: '13:00', end: '17:00' }, { id: 'custom', label: 'Custom Time', start: '', end: '' }, ]; // === Dynamic "today" anchored to Malaysia time (UTC+8) ============== // The demo data was authored around ANCHOR_DATE. We compute the real current // date in Asia/Kuala_Lumpur (GMT+8, no DST) and shift every booking date by the // same offset — so "Today" in Current Bookings is ALWAYS the real Malaysia day // while the yesterday/today/tomorrow demo structure is preserved. const ANCHOR_DATE = '2026-04-29'; function klTodayISO() { const now = new Date(); // Shift the UTC instant to UTC+8, then read its calendar date. const kl = new Date(now.getTime() + (now.getTimezoneOffset() + 480) * 60000); const y = kl.getFullYear(); const m = String(kl.getMonth() + 1).padStart(2, '0'); const d = String(kl.getDate()).padStart(2, '0'); return `${y}-${m}-${d}`; } function isoFromLocal(d) { return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`; } function addDaysISO(iso, n) { if (!iso) return iso; const d = new Date(iso + 'T00:00:00'); d.setDate(d.getDate() + n); return isoFromLocal(d); } function daysBetweenISO(a, b) { return Math.round((new Date(b + 'T00:00:00') - new Date(a + 'T00:00:00')) / 86400000); } const TODAY = klTodayISO(); const DATE_SHIFT = daysBetweenISO(ANCHOR_DATE, TODAY); // === Bookings (formerly Work Orders) ================================= // Today = 2026-04-29, so we have yesterday/today/tomorrow/day-after data. const BOOKINGS = [ // YESTERDAY 2026-04-28 { id: 'BK-2026-00418', customer: 'KSB Builders', contact: 'Tan Chee Keong', phone: '+60 12-998 7766', location: 'Bukit Indah Phase 4, Block C', machine: 'PLC-005 Tadano GR-500EX', plate: '9744', category: 'Mobile Crane', tonnage: '50t', date: '2026-04-28', shift: 'morning', start: '08:00', end: '12:00', operator: 'Yong Ah Seng', rigger: 'Bala Krishnan', desc: 'Erect tower crane mast sections.', price: 'RM 5,200', diesel: 'RM 360', remarks: '', status: 'Job Completed', urgency: 'normal' }, { id: 'BK-2026-00419', customer: 'JEC Industrial', contact: 'Vincent Lee', phone: '+60 14-552 2299', location: 'Kulai PLO 12, Lot 88', machine: 'PLC-003 Tadano GR-300EX', plate: '7838', category: 'Mobile Crane', tonnage: '30t', date: '2026-04-28', shift: 'afternoon', start: '13:00', end: '17:00', operator: 'Mohd Hafiz', rigger: 'Pravin Raj', desc: 'Steel structure delivery and offload.', price: 'RM 3,200', diesel: 'RM 210', remarks: '', status: 'Cancelled', urgency: 'normal' }, { id: 'BK-2026-00417', customer: 'Ace Engineering', contact: 'Lim Wei Ming', phone: '+60 12-345 6789', location: 'Pasir Gudang Industrial Park, Lot 14B', machine: 'PLC-016 Genie S-65', plate: '5936', category: 'Skylift', tonnage: '20m', date: '2026-04-28', shift: 'morning', start: '08:00', end: '12:00', operator: 'Razak Hassan', rigger: '—', desc: 'Façade inspection and bolt-tightening at height.', price: 'RM 1,400', diesel: 'RM 80', remarks: '', status: 'Job Completed', urgency: 'normal' }, // TODAY 2026-04-29 — these match the AppSheet view (multiple bookings, mixed categories) { id: 'BK-2026-00420', customer: 'Ace Engineering', contact: 'Lim Wei Ming', phone: '+60 12-345 6789', location: 'Pasir Gudang Industrial Park, Lot 14B', machine: 'PLC-005 Tadano GR-500EX', plate: '9744', category: 'Mobile Crane', tonnage: '50t', date: '2026-04-29', shift: 'custom', start: '08:00', end: '17:00', operator: 'Gopal Raju', rigger: 'Ahmad Faizal', desc: 'Lift and place 4× pre-cast columns onto foundation. Site has tight access via north gate.', price: 'RM 4,800', diesel: 'RM 320', remarks: 'Bring outrigger pads — soft ground', status: 'On the Way', urgency: 'normal' }, { id: 'BK-2026-00421', customer: 'Greenword Sdn Bhd', contact: 'Sarah Tan', phone: '+60 13-887 2210', location: 'Medini Iskandar, Plot J-7', machine: 'PLC-009 Liebherr LTM 1090', plate: '8569', category: 'Mobile Crane', tonnage: '90t', date: '2026-04-29', shift: 'custom', start: '07:00', end: '19:00', operator: 'Chong Kah Hoe', rigger: 'Subash Kumar', desc: 'Lift HVAC units to rooftop, 12 floors. JKR permit required.', price: 'RM 8,500', diesel: 'RM 540', remarks: 'JKR officer onsite from 9am', status: 'Job Started', urgency: 'urgent' }, { id: 'BK-2026-00422', customer: 'QRE Logistics', contact: 'David Ng', phone: '+60 17-223 4456', location: 'PTP Berth 8, container yard', machine: 'PLC-011 Grove GMK4100L', plate: '5114', category: 'Mobile Crane', tonnage: '100t', date: '2026-04-29', shift: 'afternoon', start: '13:00', end: '17:00', operator: 'Mohd Hafiz', rigger: 'Pravin Raj', desc: 'Container handling — 12 reefers from quay to staging.', price: 'RM 6,200', diesel: 'RM 420', remarks: 'Night work, lighting required', status: 'Assigned', urgency: 'normal' }, { id: 'BK-2026-00423', customer: 'KSB Builders', contact: 'Tan Chee Keong', phone: '+60 12-998 7766', location: 'Bukit Indah Phase 4, Block C', machine: 'PLC-014 Liebherr LTM 1200', plate: '239', category: 'Mobile Crane', tonnage: '200t', date: '2026-04-29', shift: 'morning', start: '08:00', end: '12:00', operator: 'Yong Ah Seng', rigger: 'Bala Krishnan', desc: 'Heavy lift — pre-cast bridge girder.', price: 'RM 12,000', diesel: 'RM 800', remarks: '', status: 'Accepted', urgency: 'normal' }, { id: 'BK-2026-00424', customer: 'Ace Engineering', contact: 'Lim Wei Ming', phone: '+60 12-345 6789', location: 'PGI Phase 2', machine: 'PLC-017 JLG 600S', plate: '9437', category: 'Skylift', tonnage: '20m', date: '2026-04-29', shift: 'afternoon', start: '13:00', end: '17:00', operator: 'Razak Hassan', rigger: '—', desc: 'High-bay lighting installation.', price: 'RM 1,200', diesel: 'RM 70', remarks: '', status: 'On the Way', urgency: 'normal' }, { id: 'BK-2026-00425', customer: 'Greenword Sdn Bhd', contact: 'Sarah Tan', phone: '+60 13-887 2210', location: 'Medini Iskandar, Plot J-7', machine: 'PLC-019 Aichi SK22A', plate: '2122', category: 'Skylift', tonnage: '22m', date: '2026-04-29', shift: 'custom', start: '09:00', end: '18:00', operator: 'Suresh', rigger: '—', desc: 'Internal ceiling fit-out.', price: 'RM 850', diesel: 'RM 40', remarks: '', status: 'Assigned', urgency: 'normal' }, { id: 'BK-2026-00426', customer: 'QRE Logistics', contact: 'David Ng', phone: '+60 17-223 4456', location: 'PTP Berth 8 Yard', machine: 'PLC-008 Kobelco RK700', plate: '8908', category: 'Mobile Crane', tonnage: '70t', date: '2026-04-29', shift: 'morning', start: '08:00', end: '12:00', operator: 'Mohd Hafiz', rigger: 'Pravin Raj', desc: 'Container fittings delivery.', price: 'RM 1,800', diesel: 'RM 120', remarks: '', status: 'Accepted', urgency: 'normal' }, { id: 'BK-2026-00433', customer: 'DYC Aviation', contact: 'Aminah Yusof', phone: '+60 19-554 8821', location: 'Senai Cargo Terminal 1', machine: 'PLC-001 Tadano GR-250N', plate: '8382', category: 'Mobile Crane', tonnage: '25t', date: '2026-04-29', shift: 'morning', start: '08:00', end: '12:00', operator: 'Razak Hassan', rigger: '—', desc: 'Small parcel lift — generator swap.', price: 'RM 2,200', diesel: 'RM 150', remarks: '', status: 'Job Started', urgency: 'normal' }, { id: 'BK-2026-00434', customer: 'JEC Industrial', contact: 'Vincent Lee', phone: '+60 14-552 2299', location: 'Kulai PLO 12, Lot 22', machine: 'PLC-006 Tadano GR-500EX', plate: '4758', category: 'Mobile Crane', tonnage: '50t', date: '2026-04-29', shift: 'afternoon', start: '13:00', end: '17:00', operator: 'Yong Ah Seng', rigger: 'Bala Krishnan', desc: 'Equipment relocation — 3 lifts.', price: 'RM 3,800', diesel: 'RM 240', remarks: '', status: 'Assigned', urgency: 'normal' }, // TOMORROW 2026-04-30 { id: 'BK-2026-00427', customer: 'DYC Aviation', contact: 'Aminah Yusof', phone: '+60 19-554 8821', location: 'Senai Airport Cargo Terminal 2', machine: 'PLC-001 Tadano GR-250N', plate: '8382', category: 'Mobile Crane', tonnage: '25t', date: '2026-04-30', shift: 'morning', start: '08:00', end: '12:00', operator: 'Razak Hassan', rigger: '—', desc: 'Generator placement on warehouse roof.', price: 'RM 2,400', diesel: 'RM 180', remarks: '', status: 'Accepted', urgency: 'normal' }, { id: 'BK-2026-00428', customer: 'MTC Petrochem', contact: 'Khairul Anwar', phone: '+60 13-445 9911', location: 'Tanjung Langsat Terminal Bay 3', machine: 'PLC-015 Liebherr LTM 1250', plate: '3135', category: 'Mobile Crane', tonnage: '250t', date: '2026-04-30', shift: 'custom', start: '05:00', end: '20:00', operator: 'Chong Kah Hoe', rigger: 'Subash Kumar', desc: 'Storage tank dome installation. Hazardous area — hot work permit.', price: 'RM 18,500', diesel: 'RM 1,200', remarks: 'Confined permits issued', status: 'Pending Issue', urgency: 'urgent' }, { id: 'BK-2026-00429', customer: 'Greenword Sdn Bhd', contact: 'Sarah Tan', phone: '+60 13-887 2210', location: 'Medini Iskandar, Plot K-2', machine: 'PLC-013 Tadano ATF 130G-5', plate: '284', category: 'Mobile Crane', tonnage: '130t', date: '2026-04-30', shift: 'morning', start: '08:00', end: '12:00', operator: 'Yong Ah Seng', rigger: 'Bala Krishnan', desc: 'Tower crane top-out support lift.', price: 'RM 9,400', diesel: 'RM 620', remarks: '', status: 'Assigned', urgency: 'normal' }, { id: 'BK-2026-00430', customer: 'KSB Builders', contact: 'Tan Chee Keong', phone: '+60 12-998 7766', location: 'Bukit Indah Phase 4, Block D', machine: 'PLC-018 Genie Z-80/60', plate: '328', category: 'Skylift', tonnage: '24m', date: '2026-04-30', shift: 'afternoon', start: '13:00', end: '17:00', operator: 'Suresh', rigger: '—', desc: 'External cladding inspection.', price: 'RM 1,400', diesel: 'RM 80', remarks: '', status: 'Assigned', urgency: 'normal' }, // DAY AFTER TOMORROW 2026-05-01 { id: 'BK-2026-00431', customer: 'Ace Engineering', contact: 'Lim Wei Ming', phone: '+60 12-345 6789', location: 'PGI Phase 3', machine: 'PLC-007 Tadano GR-500EX', plate: '9552', category: 'Mobile Crane', tonnage: '50t', date: '2026-05-01', shift: 'morning', start: '08:00', end: '12:00', operator: 'Mohd Hafiz', rigger: 'Pravin Raj', desc: 'Pre-fab beam erection.', price: 'RM 4,800', diesel: 'RM 320', remarks: '', status: 'Assigned', urgency: 'normal' }, { id: 'BK-2026-00432', customer: 'JEC Industrial', contact: 'Vincent Lee', phone: '+60 14-552 2299', location: 'Kulai PLO 12, Lot 90', machine: 'PLC-020 Snorkel TB42', plate: '9418', category: 'Skylift', tonnage: '14m', date: '2026-05-01', shift: 'custom', start: '07:00', end: '15:00', operator: 'Suresh', rigger: '—', desc: 'Building maintenance — sign installation.', price: 'RM 1,200', diesel: 'RM 80', remarks: '', status: 'Assigned', urgency: 'normal' }, // +3 DAYS 2026-05-02 { id: 'BK-2026-00435', customer: 'MTC Petrochem', contact: 'Khairul Anwar', phone: '+60 13-445 9911', location: 'Tanjung Langsat Terminal Bay 3', machine: 'PLC-003 Tadano GR-300EX', plate: '7838', category: 'Mobile Crane', tonnage: '120t', date: '2026-05-02', shift: 'custom', start: '07:00', end: '18:00', operator: 'Mohd Hafiz', rigger: 'Subash Kumar', desc: 'Pipe rack module lift — phased over the day.', price: 'RM 9,800', diesel: 'RM 640', remarks: 'Hot work permit pending', status: 'Assigned', urgency: 'normal' }, { id: 'BK-2026-00436', customer: 'Ace Engineering', contact: 'Lim Wei Ming', phone: '+60 12-345 6789', location: 'PGI Phase 2', machine: 'PLC-009 Liebherr LTM 1090', plate: '8569', category: 'Mobile Crane', tonnage: '90t', date: '2026-05-02', shift: 'morning', start: '08:00', end: '12:00', operator: 'Chong Kah Hoe', rigger: 'Bala Krishnan', desc: 'Chiller unit lift to rooftop plant room.', price: 'RM 7,200', diesel: 'RM 480', remarks: '', status: 'Accepted', urgency: 'normal' }, { id: 'BK-2026-00437', customer: 'KSB Builders', contact: 'Tan Chee Keong', phone: '+60 12-998 7766', location: 'Bukit Indah Phase 4, Block D', machine: 'PLC-016 Genie S-65', plate: '5936', category: 'Skylift', tonnage: '20m', date: '2026-05-02', shift: 'afternoon', start: '13:00', end: '17:00', operator: 'Razak Hassan', rigger: '—', desc: 'Façade glazing inspection at height.', price: 'RM 1,300', diesel: 'RM 80', remarks: '', status: 'Assigned', urgency: 'normal' }, // === Historical backfill (auto-generated for All Bookings demo) === {"id":"BK-2025-00500","customer":"Easyfast","contact":"Jenny Wong","phone":"+60 12-770 4455","location":"Sutera Utama","machine":"PLC-014 (see master)","plate":"239","category":"Mobile Crane","tonnage":"200t","date":"2025-01-01","dateFrom":"2025-01-01","dateTo":"2025-01-01","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Hanapi","rigger":"Bala Krishnan","desc":"Booking","price":"RM 658","diesel":"RM 496","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00501","customer":"JEC Industrial","contact":"Vincent Lee","phone":"+60 14-552 2299","location":"Tanjung Langsat Terminal Bay 3","machine":"PLC-006 (see master)","plate":"4758","category":"Mobile Crane","tonnage":"50t","date":"2025-01-03","dateFrom":"2025-01-03","dateTo":"2025-01-03","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Jembri","rigger":"Pravin Raj","desc":"Booking","price":"RM 4,106","diesel":"RM 349","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00502","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"Sutera Utama","machine":"PLC-002 (see master)","plate":"6382","category":"Mobile Crane","tonnage":"25t","date":"2025-01-14","dateFrom":"2025-01-14","dateTo":"2025-01-14","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Razak Hassan","rigger":"—","desc":"Booking","price":"RM 2,925","diesel":"RM 393","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00503","customer":"Egosky Steels sb","contact":"Aziz Mohamed","phone":"+60 13-661 3322","location":"Pmu Cahaya","machine":"PLC-005 (see master)","plate":"9744","category":"Mobile Crane","tonnage":"50t","date":"2025-01-01","dateFrom":"2025-01-01","dateTo":"2025-01-01","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Muthu","rigger":"Bala Krishnan","desc":"Booking","price":"RM 1,751","diesel":"RM 607","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00504","customer":"Easyfast","contact":"Jenny Wong","phone":"+60 12-770 4455","location":"Taman Johor","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-02-21","dateFrom":"2025-02-21","dateTo":"2025-02-21","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Mohd Hafiz","rigger":"—","desc":"Booking","price":"RM 6,346","diesel":"RM 362","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00505","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"PTP Berth 8 Yard","machine":"PLC-016 (see master)","plate":"5936","category":"Skylift","tonnage":"20m","date":"2025-02-11","dateFrom":"2025-02-11","dateTo":"2025-02-11","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Suresh","rigger":"—","desc":"Booking","price":"RM 7,469","diesel":"RM 155","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00506","customer":"JEC Industrial","contact":"Vincent Lee","phone":"+60 14-552 2299","location":"Desa Terbau","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-02-12","dateFrom":"2025-02-12","dateTo":"2025-02-12","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Richard","rigger":"—","desc":"Booking","price":"RM 3,646","diesel":"RM 549","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00507","customer":"Ame Const","contact":"Kana M","phone":"+60 17-883 1188","location":"silc lot 7","machine":"PLC-014 (see master)","plate":"239","category":"Mobile Crane","tonnage":"200t","date":"2025-02-15","dateFrom":"2025-02-15","dateTo":"2025-02-15","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Kanisan","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 5,799","diesel":"RM 117","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00508","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Desa Terbau","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2025-02-25","dateFrom":"2025-02-25","dateTo":"2025-02-27","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"—","desc":"Booking","price":"RM 3,827","diesel":"RM 515","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00508","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Desa Terbau","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2025-02-26","dateFrom":"2025-02-25","dateTo":"2025-02-27","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"—","desc":"Booking","price":"RM 3,827","diesel":"RM 515","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00508","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Desa Terbau","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2025-02-27","dateFrom":"2025-02-25","dateTo":"2025-02-27","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"—","desc":"Booking","price":"RM 3,827","diesel":"RM 515","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00509","customer":"JEC Industrial","contact":"Vincent Lee","phone":"+60 14-552 2299","location":"Tanjung Langsat","machine":"PLC-004 (see master)","plate":"1484","category":"Mobile Crane","tonnage":"30t","date":"2025-03-23","dateFrom":"2025-03-23","dateTo":"2025-03-23","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Mohd Hafiz","rigger":"Bala Krishnan","desc":"Booking","price":"RM 9,299","diesel":"RM 52","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00510","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Pmu Cahaya","machine":"PLC-008 (see master)","plate":"8908","category":"Mobile Crane","tonnage":"70t","date":"2025-03-01","dateFrom":"2025-03-01","dateTo":"2025-03-01","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yong Ah Seng","rigger":"Subash Kumar","desc":"Booking","price":"RM 8,427","diesel":"RM 160","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00511","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Seelong","machine":"PLC-015 (see master)","plate":"3135","category":"Mobile Crane","tonnage":"250t","date":"2025-03-19","dateFrom":"2025-03-19","dateTo":"2025-03-19","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yusof","rigger":"Subash Kumar","desc":"Booking","price":"RM 3,662","diesel":"RM 262","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00512","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"JB Bandar","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-03-12","dateFrom":"2025-03-12","dateTo":"2025-03-15","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"—","desc":"Booking","price":"RM 5,470","diesel":"RM 432","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00512","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"JB Bandar","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-03-13","dateFrom":"2025-03-12","dateTo":"2025-03-15","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"—","desc":"Booking","price":"RM 5,470","diesel":"RM 432","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00512","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"JB Bandar","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-03-14","dateFrom":"2025-03-12","dateTo":"2025-03-15","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"—","desc":"Booking","price":"RM 5,470","diesel":"RM 432","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00512","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"JB Bandar","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-03-15","dateFrom":"2025-03-12","dateTo":"2025-03-15","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"—","desc":"Booking","price":"RM 5,470","diesel":"RM 432","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00513","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Bukit Indah Phase 4","machine":"PLC-002 (see master)","plate":"6382","category":"Mobile Crane","tonnage":"25t","date":"2025-04-18","dateFrom":"2025-04-18","dateTo":"2025-04-18","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Hanapi","rigger":"—","desc":"Booking","price":"RM 1,189","diesel":"RM 574","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00514","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"silc lot 7","machine":"PLC-001 (see master)","plate":"8382","category":"Mobile Crane","tonnage":"25t","date":"2025-04-28","dateFrom":"2025-04-28","dateTo":"2025-04-30","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Kanisan","rigger":"—","desc":"Booking","price":"RM 416","diesel":"RM 248","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00514","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"silc lot 7","machine":"PLC-001 (see master)","plate":"8382","category":"Mobile Crane","tonnage":"25t","date":"2025-04-29","dateFrom":"2025-04-28","dateTo":"2025-04-30","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Kanisan","rigger":"—","desc":"Booking","price":"RM 416","diesel":"RM 248","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00514","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"silc lot 7","machine":"PLC-001 (see master)","plate":"8382","category":"Mobile Crane","tonnage":"25t","date":"2025-04-30","dateFrom":"2025-04-28","dateTo":"2025-04-30","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Kanisan","rigger":"—","desc":"Booking","price":"RM 416","diesel":"RM 248","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00515","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Pmu Cahaya","machine":"PLC-016 (see master)","plate":"5936","category":"Skylift","tonnage":"20m","date":"2025-04-12","dateFrom":"2025-04-12","dateTo":"2025-04-12","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Chong Kah Hoe","rigger":"—","desc":"Booking","price":"RM 981","diesel":"RM 213","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00516","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Kulai PLO 12, Lot 88","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-04-09","dateFrom":"2025-04-09","dateTo":"2025-04-09","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"Bala Krishnan","desc":"Booking","price":"RM 1,142","diesel":"RM 195","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00517","customer":"DYC Aviation","contact":"Aminah Yusof","phone":"+60 19-554 8821","location":"Pontian","machine":"PLC-009 (see master)","plate":"8569","category":"Mobile Crane","tonnage":"90t","date":"2025-04-27","dateFrom":"2025-04-27","dateTo":"2025-04-27","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Mohd Hafiz","rigger":"Bala Krishnan","desc":"Booking","price":"RM 7,998","diesel":"RM 237","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00518","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Senai","machine":"CR-005 Cross Rent 5","plate":"CR-5","category":"Cross Rent","tonnage":"150t","date":"2025-05-30","dateFrom":"2025-05-30","dateTo":"2025-06-02","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"","rigger":"—","desc":"Booking","price":"RM 3,797","diesel":"RM 550","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00518","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Senai","machine":"CR-005 Cross Rent 5","plate":"CR-5","category":"Cross Rent","tonnage":"150t","date":"2025-05-31","dateFrom":"2025-05-30","dateTo":"2025-06-02","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"","rigger":"—","desc":"Booking","price":"RM 3,797","diesel":"RM 550","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00518","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Senai","machine":"CR-005 Cross Rent 5","plate":"CR-5","category":"Cross Rent","tonnage":"150t","date":"2025-06-01","dateFrom":"2025-05-30","dateTo":"2025-06-02","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"","rigger":"—","desc":"Booking","price":"RM 3,797","diesel":"RM 550","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00518","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Senai","machine":"CR-005 Cross Rent 5","plate":"CR-5","category":"Cross Rent","tonnage":"150t","date":"2025-06-02","dateFrom":"2025-05-30","dateTo":"2025-06-02","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"","rigger":"—","desc":"Booking","price":"RM 3,797","diesel":"RM 550","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00519","customer":"Easyfast","contact":"Jenny Wong","phone":"+60 12-770 4455","location":"Taman Johor","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2025-05-26","dateFrom":"2025-05-26","dateTo":"2025-05-26","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Richard","rigger":"—","desc":"Booking","price":"RM 6,407","diesel":"RM 80","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00520","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"JB Bandar","machine":"PLC-014 (see master)","plate":"239","category":"Mobile Crane","tonnage":"200t","date":"2025-05-04","dateFrom":"2025-05-04","dateTo":"2025-05-04","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Kanisan","rigger":"Pravin Raj","desc":"Booking","price":"RM 1,919","diesel":"RM 389","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00521","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"Senai","machine":"PLC-011 (see master)","plate":"5114","category":"Mobile Crane","tonnage":"100t","date":"2025-05-11","dateFrom":"2025-05-11","dateTo":"2025-05-11","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Suresh","rigger":"Pravin Raj","desc":"Booking","price":"RM 6,828","diesel":"RM 138","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00522","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Tanjung Langsat Terminal Bay 3","machine":"PLC-003 (see master)","plate":"7838","category":"Mobile Crane","tonnage":"30t","date":"2025-05-12","dateFrom":"2025-05-12","dateTo":"2025-05-12","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Yong Ah Seng","rigger":"Subash Kumar","desc":"Booking","price":"RM 7,523","diesel":"RM 568","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00523","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Desa Terbau","machine":"CR-001 Cross Rent 1","plate":"CR-1","category":"Cross Rent","tonnage":"25t","date":"2025-06-27","dateFrom":"2025-06-27","dateTo":"2025-06-27","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"","rigger":"—","desc":"Booking","price":"RM 4,973","diesel":"RM 220","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00524","customer":"Ace Engineering","contact":"Lim Wei Ming","phone":"+60 12-345 6789","location":"Taman Johor","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-06-11","dateFrom":"2025-06-11","dateTo":"2025-06-11","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yusof","rigger":"Subash Kumar","desc":"Booking","price":"RM 2,120","diesel":"RM 515","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00525","customer":"Jay brother","contact":"Jay Lim","phone":"+60 12-554 6611","location":"silc lot 7","machine":"PLC-011 (see master)","plate":"5114","category":"Mobile Crane","tonnage":"100t","date":"2025-06-06","dateFrom":"2025-06-06","dateTo":"2025-06-06","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Kanisan","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 1,089","diesel":"RM 333","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00526","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Medini Iskandar, Plot J-7","machine":"PLC-013 (see master)","plate":"284","category":"Mobile Crane","tonnage":"130t","date":"2025-06-07","dateFrom":"2025-06-07","dateTo":"2025-06-07","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Kanisan","rigger":"Bala Krishnan","desc":"Booking","price":"RM 2,278","diesel":"RM 299","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00527","customer":"JEC Industrial","contact":"Vincent Lee","phone":"+60 14-552 2299","location":"Senai Cargo Terminal 1","machine":"CR-003 Cross Rent 3","plate":"CR-3","category":"Cross Rent","tonnage":"90t","date":"2025-07-27","dateFrom":"2025-07-27","dateTo":"2025-07-27","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"","rigger":"—","desc":"Booking","price":"RM 2,868","diesel":"RM 545","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00528","customer":"Jay brother","contact":"Jay Lim","phone":"+60 12-554 6611","location":"Senai Airport Cargo","machine":"PLC-020 (see master)","plate":"9418","category":"Skylift","tonnage":"14m","date":"2025-07-16","dateFrom":"2025-07-16","dateTo":"2025-07-16","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yusof","rigger":"—","desc":"Booking","price":"RM 4,368","diesel":"RM 564","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00529","customer":"Pamir","contact":"Liyana A","phone":"+60 16-227 5577","location":"Tanjung Langsat Terminal Bay 3","machine":"PLC-009 (see master)","plate":"8569","category":"Mobile Crane","tonnage":"90t","date":"2025-07-21","dateFrom":"2025-07-21","dateTo":"2025-07-21","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Razak Hassan","rigger":"Bala Krishnan","desc":"Booking","price":"RM 638","diesel":"RM 459","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00530","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Senai Airport Cargo","machine":"PLC-001 (see master)","plate":"8382","category":"Mobile Crane","tonnage":"25t","date":"2025-07-21","dateFrom":"2025-07-21","dateTo":"2025-07-21","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Hanapi","rigger":"—","desc":"Booking","price":"RM 6,173","diesel":"RM 85","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00531","customer":"DYC Aviation","contact":"Aminah Yusof","phone":"+60 19-554 8821","location":"Senai Cargo Terminal 1","machine":"PLC-015 (see master)","plate":"3135","category":"Mobile Crane","tonnage":"250t","date":"2025-07-06","dateFrom":"2025-07-06","dateTo":"2025-07-06","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Muthu","rigger":"Subash Kumar","desc":"Booking","price":"RM 7,345","diesel":"RM 330","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00532","customer":"Jay brother","contact":"Jay Lim","phone":"+60 12-554 6611","location":"PGI Phase 3","machine":"PLC-015 (see master)","plate":"3135","category":"Mobile Crane","tonnage":"250t","date":"2025-07-01","dateFrom":"2025-07-01","dateTo":"2025-07-01","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Hanapi","rigger":"Pravin Raj","desc":"Booking","price":"RM 2,744","diesel":"RM 478","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00533","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Bukit Indah Phase 4","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-08-28","dateFrom":"2025-08-28","dateTo":"2025-08-31","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Mohd Hafiz","rigger":"Pravin Raj","desc":"Booking","price":"RM 5,985","diesel":"RM 167","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00533","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Bukit Indah Phase 4","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-08-29","dateFrom":"2025-08-28","dateTo":"2025-08-31","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Mohd Hafiz","rigger":"Pravin Raj","desc":"Booking","price":"RM 5,985","diesel":"RM 167","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00533","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Bukit Indah Phase 4","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-08-30","dateFrom":"2025-08-28","dateTo":"2025-08-31","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Mohd Hafiz","rigger":"Pravin Raj","desc":"Booking","price":"RM 5,985","diesel":"RM 167","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00533","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Bukit Indah Phase 4","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-08-31","dateFrom":"2025-08-28","dateTo":"2025-08-31","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Mohd Hafiz","rigger":"Pravin Raj","desc":"Booking","price":"RM 5,985","diesel":"RM 167","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00534","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Senai Airport Cargo","machine":"PLC-006 (see master)","plate":"4758","category":"Mobile Crane","tonnage":"50t","date":"2025-08-12","dateFrom":"2025-08-12","dateTo":"2025-08-12","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Jembri","rigger":"Bala Krishnan","desc":"Booking","price":"RM 8,585","diesel":"RM 238","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00535","customer":"Egosky Steels sb","contact":"Aziz Mohamed","phone":"+60 13-661 3322","location":"Sutera Utama","machine":"PLC-015 (see master)","plate":"3135","category":"Mobile Crane","tonnage":"250t","date":"2025-08-08","dateFrom":"2025-08-08","dateTo":"2025-08-08","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Razak Hassan","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 5,932","diesel":"RM 216","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00536","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Pontian","machine":"CR-003 Cross Rent 3","plate":"CR-3","category":"Cross Rent","tonnage":"90t","date":"2025-08-14","dateFrom":"2025-08-14","dateTo":"2025-08-14","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"","rigger":"—","desc":"Booking","price":"RM 2,133","diesel":"RM 191","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00537","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"Tanjung Langsat","machine":"PLC-012 (see master)","plate":"8172","category":"Mobile Crane","tonnage":"100t","date":"2025-08-18","dateFrom":"2025-08-18","dateTo":"2025-08-18","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Muthu","rigger":"Pravin Raj","desc":"Booking","price":"RM 2,881","diesel":"RM 83","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00538","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Medini Iskandar, Plot J-7","machine":"PLC-010 (see master)","plate":"4368","category":"Mobile Crane","tonnage":"90t","date":"2025-09-23","dateFrom":"2025-09-23","dateTo":"2025-09-23","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yusof","rigger":"Subash Kumar","desc":"Booking","price":"RM 6,512","diesel":"RM 71","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00539","customer":"Egosky Steels sb","contact":"Aziz Mohamed","phone":"+60 13-661 3322","location":"PTP Berth 8 Yard","machine":"PLC-001 (see master)","plate":"8382","category":"Mobile Crane","tonnage":"25t","date":"2025-09-30","dateFrom":"2025-09-30","dateTo":"2025-10-03","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Kanisan","rigger":"—","desc":"Booking","price":"RM 7,514","diesel":"RM 492","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00539","customer":"Egosky Steels sb","contact":"Aziz Mohamed","phone":"+60 13-661 3322","location":"PTP Berth 8 Yard","machine":"PLC-001 (see master)","plate":"8382","category":"Mobile Crane","tonnage":"25t","date":"2025-10-01","dateFrom":"2025-09-30","dateTo":"2025-10-03","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Kanisan","rigger":"—","desc":"Booking","price":"RM 7,514","diesel":"RM 492","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00539","customer":"Egosky Steels sb","contact":"Aziz Mohamed","phone":"+60 13-661 3322","location":"PTP Berth 8 Yard","machine":"PLC-001 (see master)","plate":"8382","category":"Mobile Crane","tonnage":"25t","date":"2025-10-02","dateFrom":"2025-09-30","dateTo":"2025-10-03","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Kanisan","rigger":"—","desc":"Booking","price":"RM 7,514","diesel":"RM 492","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00539","customer":"Egosky Steels sb","contact":"Aziz Mohamed","phone":"+60 13-661 3322","location":"PTP Berth 8 Yard","machine":"PLC-001 (see master)","plate":"8382","category":"Mobile Crane","tonnage":"25t","date":"2025-10-03","dateFrom":"2025-09-30","dateTo":"2025-10-03","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Kanisan","rigger":"—","desc":"Booking","price":"RM 7,514","diesel":"RM 492","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00540","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Desa Terbau","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-09-03","dateFrom":"2025-09-03","dateTo":"2025-09-07","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 7,859","diesel":"RM 301","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00540","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Desa Terbau","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-09-04","dateFrom":"2025-09-03","dateTo":"2025-09-07","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 7,859","diesel":"RM 301","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00540","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Desa Terbau","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-09-05","dateFrom":"2025-09-03","dateTo":"2025-09-07","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 7,859","diesel":"RM 301","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00540","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Desa Terbau","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-09-06","dateFrom":"2025-09-03","dateTo":"2025-09-07","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 7,859","diesel":"RM 301","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00540","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Desa Terbau","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-09-07","dateFrom":"2025-09-03","dateTo":"2025-09-07","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 7,859","diesel":"RM 301","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00541","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Taman Johor","machine":"PLC-015 (see master)","plate":"3135","category":"Mobile Crane","tonnage":"250t","date":"2025-09-02","dateFrom":"2025-09-02","dateTo":"2025-09-02","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"Bala Krishnan","desc":"Booking","price":"RM 2,857","diesel":"RM 154","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00542","customer":"Easyfast","contact":"Jenny Wong","phone":"+60 12-770 4455","location":"Tanjung Langsat Terminal Bay 3","machine":"CR-002 Cross Rent 2","plate":"CR-2","category":"Cross Rent","tonnage":"50t","date":"2025-09-18","dateFrom":"2025-09-18","dateTo":"2025-09-18","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"","rigger":"—","desc":"Booking","price":"RM 1,344","diesel":"RM 486","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00543","customer":"Greenword Sdn Bhd","contact":"Sarah Tan","phone":"+60 13-887 2210","location":"PGI Phase 3","machine":"CR-003 Cross Rent 3","plate":"CR-3","category":"Cross Rent","tonnage":"90t","date":"2025-09-29","dateFrom":"2025-09-29","dateTo":"2025-09-29","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"","rigger":"—","desc":"Booking","price":"RM 6,140","diesel":"RM 556","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00544","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"PGI Phase 3","machine":"PLC-014 (see master)","plate":"239","category":"Mobile Crane","tonnage":"200t","date":"2025-09-06","dateFrom":"2025-09-06","dateTo":"2025-09-06","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Kanisan","rigger":"Pravin Raj","desc":"Booking","price":"RM 7,110","diesel":"RM 270","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00545","customer":"Ame Const","contact":"Kana M","phone":"+60 17-883 1188","location":"Seelong","machine":"PLC-012 (see master)","plate":"8172","category":"Mobile Crane","tonnage":"100t","date":"2025-10-28","dateFrom":"2025-10-28","dateTo":"2025-10-28","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Razak Hassan","rigger":"Bala Krishnan","desc":"Booking","price":"RM 7,291","diesel":"RM 555","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00546","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Senai","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2025-10-24","dateFrom":"2025-10-24","dateTo":"2025-10-24","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Jembri","rigger":"—","desc":"Booking","price":"RM 7,934","diesel":"RM 144","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00547","customer":"Jay brother","contact":"Jay Lim","phone":"+60 12-554 6611","location":"Seelong","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-10-29","dateFrom":"2025-10-29","dateTo":"2025-10-29","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Rajah","rigger":"—","desc":"Booking","price":"RM 3,138","diesel":"RM 442","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00548","customer":"Egosky Steels sb","contact":"Aziz Mohamed","phone":"+60 13-661 3322","location":"Tanjung Langsat","machine":"PLC-016 (see master)","plate":"5936","category":"Skylift","tonnage":"20m","date":"2025-10-15","dateFrom":"2025-10-15","dateTo":"2025-10-15","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Kanisan","rigger":"—","desc":"Booking","price":"RM 9,157","diesel":"RM 555","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00549","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"Desa Terbau","machine":"PLC-003 (see master)","plate":"7838","category":"Mobile Crane","tonnage":"30t","date":"2025-10-15","dateFrom":"2025-10-15","dateTo":"2025-10-15","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Rajah","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 8,127","diesel":"RM 142","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00550","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Senai Airport Cargo","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-10-27","dateFrom":"2025-10-27","dateTo":"2025-10-31","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Muthu","rigger":"—","desc":"Booking","price":"RM 2,886","diesel":"RM 405","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00550","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Senai Airport Cargo","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-10-28","dateFrom":"2025-10-27","dateTo":"2025-10-31","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Muthu","rigger":"—","desc":"Booking","price":"RM 2,886","diesel":"RM 405","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00550","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Senai Airport Cargo","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-10-29","dateFrom":"2025-10-27","dateTo":"2025-10-31","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Muthu","rigger":"—","desc":"Booking","price":"RM 2,886","diesel":"RM 405","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00550","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Senai Airport Cargo","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-10-30","dateFrom":"2025-10-27","dateTo":"2025-10-31","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Muthu","rigger":"—","desc":"Booking","price":"RM 2,886","diesel":"RM 405","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00550","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Senai Airport Cargo","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2025-10-31","dateFrom":"2025-10-27","dateTo":"2025-10-31","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Muthu","rigger":"—","desc":"Booking","price":"RM 2,886","diesel":"RM 405","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00551","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Senai Cargo Terminal 1","machine":"PLC-008 (see master)","plate":"8908","category":"Mobile Crane","tonnage":"70t","date":"2025-11-24","dateFrom":"2025-11-24","dateTo":"2025-11-24","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Richard","rigger":"Bala Krishnan","desc":"Booking","price":"RM 4,222","diesel":"RM 617","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00552","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"JB Bandar","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2025-11-03","dateFrom":"2025-11-03","dateTo":"2025-11-03","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yusof","rigger":"Pravin Raj","desc":"Booking","price":"RM 6,240","diesel":"RM 373","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00553","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Medini Iskandar, Plot J-7","machine":"PLC-003 (see master)","plate":"7838","category":"Mobile Crane","tonnage":"30t","date":"2025-11-21","dateFrom":"2025-11-21","dateTo":"2025-11-21","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"Subash Kumar","desc":"Booking","price":"RM 6,898","diesel":"RM 236","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00554","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Senai Airport Cargo","machine":"PLC-006 (see master)","plate":"4758","category":"Mobile Crane","tonnage":"50t","date":"2025-11-18","dateFrom":"2025-11-18","dateTo":"2025-11-18","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 1,532","diesel":"RM 484","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00555","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"JB Bandar","machine":"PLC-002 (see master)","plate":"6382","category":"Mobile Crane","tonnage":"25t","date":"2025-12-29","dateFrom":"2025-12-29","dateTo":"2025-12-29","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yong Ah Seng","rigger":"—","desc":"Booking","price":"RM 5,046","diesel":"RM 274","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00556","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Pontian","machine":"CR-006 Cross Rent 6","plate":"CR-6","category":"Cross Rent","tonnage":"20m","date":"2025-12-21","dateFrom":"2025-12-21","dateTo":"2025-12-23","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"","rigger":"—","desc":"Booking","price":"RM 6,266","diesel":"RM 476","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00556","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Pontian","machine":"CR-006 Cross Rent 6","plate":"CR-6","category":"Cross Rent","tonnage":"20m","date":"2025-12-22","dateFrom":"2025-12-21","dateTo":"2025-12-23","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"","rigger":"—","desc":"Booking","price":"RM 6,266","diesel":"RM 476","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00556","customer":"Turbopak","contact":"Tony Yusof","phone":"+60 11-553 4477","location":"Pontian","machine":"CR-006 Cross Rent 6","plate":"CR-6","category":"Cross Rent","tonnage":"20m","date":"2025-12-23","dateFrom":"2025-12-21","dateTo":"2025-12-23","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"","rigger":"—","desc":"Booking","price":"RM 6,266","diesel":"RM 476","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00557","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Taman Johor","machine":"PLC-020 (see master)","plate":"9418","category":"Skylift","tonnage":"14m","date":"2025-12-28","dateFrom":"2025-12-28","dateTo":"2025-12-28","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Yusof","rigger":"—","desc":"Booking","price":"RM 4,745","diesel":"RM 554","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00558","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Seelong","machine":"PLC-002 (see master)","plate":"6382","category":"Mobile Crane","tonnage":"25t","date":"2025-12-23","dateFrom":"2025-12-23","dateTo":"2025-12-23","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"—","desc":"Booking","price":"RM 1,762","diesel":"RM 438","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2025-00559","customer":"Ace Engineering","contact":"Lim Wei Ming","phone":"+60 12-345 6789","location":"Taman Johor","machine":"PLC-016 (see master)","plate":"5936","category":"Skylift","tonnage":"20m","date":"2025-12-19","dateFrom":"2025-12-19","dateTo":"2025-12-19","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yong Ah Seng","rigger":"—","desc":"Booking","price":"RM 6,934","diesel":"RM 507","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00560","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Senai","machine":"PLC-003 (see master)","plate":"7838","category":"Mobile Crane","tonnage":"30t","date":"2026-01-31","dateFrom":"2026-01-31","dateTo":"2026-02-02","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"Bala Krishnan","desc":"Booking","price":"RM 6,269","diesel":"RM 50","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00560","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Senai","machine":"PLC-003 (see master)","plate":"7838","category":"Mobile Crane","tonnage":"30t","date":"2026-02-01","dateFrom":"2026-01-31","dateTo":"2026-02-02","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"Bala Krishnan","desc":"Booking","price":"RM 6,269","diesel":"RM 50","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00560","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Senai","machine":"PLC-003 (see master)","plate":"7838","category":"Mobile Crane","tonnage":"30t","date":"2026-02-02","dateFrom":"2026-01-31","dateTo":"2026-02-02","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"Bala Krishnan","desc":"Booking","price":"RM 6,269","diesel":"RM 50","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00561","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Tanjung Langsat Terminal Bay 3","machine":"PLC-008 (see master)","plate":"8908","category":"Mobile Crane","tonnage":"70t","date":"2026-01-12","dateFrom":"2026-01-12","dateTo":"2026-01-12","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Suresh","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 1,983","diesel":"RM 161","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00562","customer":"Jay brother","contact":"Jay Lim","phone":"+60 12-554 6611","location":"Pmu Cahaya","machine":"PLC-010 (see master)","plate":"4368","category":"Mobile Crane","tonnage":"90t","date":"2026-01-28","dateFrom":"2026-01-28","dateTo":"2026-01-29","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Hanapi","rigger":"Subash Kumar","desc":"Booking","price":"RM 2,940","diesel":"RM 500","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00562","customer":"Jay brother","contact":"Jay Lim","phone":"+60 12-554 6611","location":"Pmu Cahaya","machine":"PLC-010 (see master)","plate":"4368","category":"Mobile Crane","tonnage":"90t","date":"2026-01-29","dateFrom":"2026-01-28","dateTo":"2026-01-29","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Hanapi","rigger":"Subash Kumar","desc":"Booking","price":"RM 2,940","diesel":"RM 500","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00563","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"PGI Phase 3","machine":"PLC-005 (see master)","plate":"9744","category":"Mobile Crane","tonnage":"50t","date":"2026-01-31","dateFrom":"2026-01-31","dateTo":"2026-01-31","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yusof","rigger":"Subash Kumar","desc":"Booking","price":"RM 8,313","diesel":"RM 613","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00564","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Bukit Indah Phase 4","machine":"PLC-003 (see master)","plate":"7838","category":"Mobile Crane","tonnage":"30t","date":"2026-01-18","dateFrom":"2026-01-18","dateTo":"2026-01-18","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yong Ah Seng","rigger":"Subash Kumar","desc":"Booking","price":"RM 7,785","diesel":"RM 226","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00565","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"Pontian","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2026-02-13","dateFrom":"2026-02-13","dateTo":"2026-02-16","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Muthu","rigger":"Bala Krishnan","desc":"Booking","price":"RM 5,399","diesel":"RM 513","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00565","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"Pontian","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2026-02-14","dateFrom":"2026-02-13","dateTo":"2026-02-16","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Muthu","rigger":"Bala Krishnan","desc":"Booking","price":"RM 5,399","diesel":"RM 513","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00565","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"Pontian","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2026-02-15","dateFrom":"2026-02-13","dateTo":"2026-02-16","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Muthu","rigger":"Bala Krishnan","desc":"Booking","price":"RM 5,399","diesel":"RM 513","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00565","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"Pontian","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2026-02-16","dateFrom":"2026-02-13","dateTo":"2026-02-16","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Muthu","rigger":"Bala Krishnan","desc":"Booking","price":"RM 5,399","diesel":"RM 513","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00566","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Tanjung Langsat","machine":"PLC-012 (see master)","plate":"8172","category":"Mobile Crane","tonnage":"100t","date":"2026-02-22","dateFrom":"2026-02-22","dateTo":"2026-02-25","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Yusof","rigger":"Pravin Raj","desc":"Booking","price":"RM 3,537","diesel":"RM 480","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00566","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Tanjung Langsat","machine":"PLC-012 (see master)","plate":"8172","category":"Mobile Crane","tonnage":"100t","date":"2026-02-23","dateFrom":"2026-02-22","dateTo":"2026-02-25","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Yusof","rigger":"Pravin Raj","desc":"Booking","price":"RM 3,537","diesel":"RM 480","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00566","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Tanjung Langsat","machine":"PLC-012 (see master)","plate":"8172","category":"Mobile Crane","tonnage":"100t","date":"2026-02-24","dateFrom":"2026-02-22","dateTo":"2026-02-25","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Yusof","rigger":"Pravin Raj","desc":"Booking","price":"RM 3,537","diesel":"RM 480","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00566","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Tanjung Langsat","machine":"PLC-012 (see master)","plate":"8172","category":"Mobile Crane","tonnage":"100t","date":"2026-02-25","dateFrom":"2026-02-22","dateTo":"2026-02-25","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Yusof","rigger":"Pravin Raj","desc":"Booking","price":"RM 3,537","diesel":"RM 480","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00567","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"JB Bandar","machine":"PLC-015 (see master)","plate":"3135","category":"Mobile Crane","tonnage":"250t","date":"2026-02-27","dateFrom":"2026-02-27","dateTo":"2026-02-27","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 526","diesel":"RM 478","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00568","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Tanjung Langsat Terminal Bay 3","machine":"CR-006 Cross Rent 6","plate":"CR-6","category":"Cross Rent","tonnage":"20m","date":"2026-02-08","dateFrom":"2026-02-08","dateTo":"2026-02-08","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"","rigger":"—","desc":"Booking","price":"RM 6,837","diesel":"RM 54","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00569","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"Senai Cargo Terminal 1","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2026-02-22","dateFrom":"2026-02-22","dateTo":"2026-02-22","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Yusof","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 1,499","diesel":"RM 210","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00570","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Tanjung Langsat Terminal Bay 3","machine":"PLC-014 (see master)","plate":"239","category":"Mobile Crane","tonnage":"200t","date":"2026-02-08","dateFrom":"2026-02-08","dateTo":"2026-02-09","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Razak Hassan","rigger":"Bala Krishnan","desc":"Booking","price":"RM 4,788","diesel":"RM 66","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00570","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"Tanjung Langsat Terminal Bay 3","machine":"PLC-014 (see master)","plate":"239","category":"Mobile Crane","tonnage":"200t","date":"2026-02-09","dateFrom":"2026-02-08","dateTo":"2026-02-09","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Razak Hassan","rigger":"Bala Krishnan","desc":"Booking","price":"RM 4,788","diesel":"RM 66","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00571","customer":"Jay brother","contact":"Jay Lim","phone":"+60 12-554 6611","location":"PTP Berth 8 Yard","machine":"PLC-003 (see master)","plate":"7838","category":"Mobile Crane","tonnage":"30t","date":"2026-02-21","dateFrom":"2026-02-21","dateTo":"2026-02-21","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Kanisan","rigger":"Bala Krishnan","desc":"Booking","price":"RM 4,566","diesel":"RM 60","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00572","customer":"JEC Industrial","contact":"Vincent Lee","phone":"+60 14-552 2299","location":"Sutera Utama","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2026-03-06","dateFrom":"2026-03-06","dateTo":"2026-03-06","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Razak Hassan","rigger":"—","desc":"Booking","price":"RM 2,888","diesel":"RM 385","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00573","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Pontian","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2026-03-29","dateFrom":"2026-03-29","dateTo":"2026-04-02","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Jembri","rigger":"—","desc":"Booking","price":"RM 2,077","diesel":"RM 480","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00573","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Pontian","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2026-03-30","dateFrom":"2026-03-29","dateTo":"2026-04-02","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Jembri","rigger":"—","desc":"Booking","price":"RM 2,077","diesel":"RM 480","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00573","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Pontian","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2026-03-31","dateFrom":"2026-03-29","dateTo":"2026-04-02","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Jembri","rigger":"—","desc":"Booking","price":"RM 2,077","diesel":"RM 480","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00573","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Pontian","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2026-04-01","dateFrom":"2026-03-29","dateTo":"2026-04-02","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Jembri","rigger":"—","desc":"Booking","price":"RM 2,077","diesel":"RM 480","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00573","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Pontian","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2026-04-02","dateFrom":"2026-03-29","dateTo":"2026-04-02","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Jembri","rigger":"—","desc":"Booking","price":"RM 2,077","diesel":"RM 480","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00574","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Seelong","machine":"PLC-019 (see master)","plate":"2122","category":"Skylift","tonnage":"22m","date":"2026-03-10","dateFrom":"2026-03-10","dateTo":"2026-03-10","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Jembri","rigger":"—","desc":"Booking","price":"RM 823","diesel":"RM 356","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00575","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"JB Bandar","machine":"PLC-004 (see master)","plate":"1484","category":"Mobile Crane","tonnage":"30t","date":"2026-03-28","dateFrom":"2026-03-28","dateTo":"2026-03-28","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Richard","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 1,354","diesel":"RM 349","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00576","customer":"MTC Petrochem","contact":"Khairul Anwar","phone":"+60 13-445 9911","location":"PGI Phase 3","machine":"PLC-011 (see master)","plate":"5114","category":"Mobile Crane","tonnage":"100t","date":"2026-03-12","dateFrom":"2026-03-12","dateTo":"2026-03-12","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Hanapi","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 3,516","diesel":"RM 391","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00577","customer":"Jay brother","contact":"Jay Lim","phone":"+60 12-554 6611","location":"Senai Cargo Terminal 1","machine":"PLC-020 (see master)","plate":"9418","category":"Skylift","tonnage":"14m","date":"2026-04-14","dateFrom":"2026-04-14","dateTo":"2026-04-14","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Kanisan","rigger":"—","desc":"Booking","price":"RM 3,997","diesel":"RM 165","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00578","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Medini Iskandar, Plot J-7","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2026-04-02","dateFrom":"2026-04-02","dateTo":"2026-04-05","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Suresh","rigger":"—","desc":"Booking","price":"RM 6,498","diesel":"RM 235","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00578","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Medini Iskandar, Plot J-7","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2026-04-03","dateFrom":"2026-04-02","dateTo":"2026-04-05","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Suresh","rigger":"—","desc":"Booking","price":"RM 6,498","diesel":"RM 235","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00578","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Medini Iskandar, Plot J-7","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2026-04-04","dateFrom":"2026-04-02","dateTo":"2026-04-05","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Suresh","rigger":"—","desc":"Booking","price":"RM 6,498","diesel":"RM 235","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00578","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Medini Iskandar, Plot J-7","machine":"PLC-018 (see master)","plate":"328","category":"Skylift","tonnage":"24m","date":"2026-04-05","dateFrom":"2026-04-02","dateTo":"2026-04-05","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Suresh","rigger":"—","desc":"Booking","price":"RM 6,498","diesel":"RM 235","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00579","customer":"Pamir","contact":"Liyana A","phone":"+60 16-227 5577","location":"Medini Iskandar, Plot J-7","machine":"PLC-012 (see master)","plate":"8172","category":"Mobile Crane","tonnage":"100t","date":"2026-04-28","dateFrom":"2026-04-28","dateTo":"2026-04-28","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Chong Kah Hoe","rigger":"Subash Kumar","desc":"Booking","price":"RM 4,837","diesel":"RM 165","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00580","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Bukit Indah Phase 4","machine":"PLC-014 (see master)","plate":"239","category":"Mobile Crane","tonnage":"200t","date":"2026-04-23","dateFrom":"2026-04-23","dateTo":"2026-04-25","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Kanisan","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 531","diesel":"RM 389","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00580","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Bukit Indah Phase 4","machine":"PLC-014 (see master)","plate":"239","category":"Mobile Crane","tonnage":"200t","date":"2026-04-24","dateFrom":"2026-04-23","dateTo":"2026-04-25","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Kanisan","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 531","diesel":"RM 389","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00580","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Bukit Indah Phase 4","machine":"PLC-014 (see master)","plate":"239","category":"Mobile Crane","tonnage":"200t","date":"2026-04-25","dateFrom":"2026-04-23","dateTo":"2026-04-25","multi":true,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Kanisan","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 531","diesel":"RM 389","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00581","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Tanjung Langsat","machine":"CR-006 Cross Rent 6","plate":"CR-6","category":"Cross Rent","tonnage":"20m","date":"2026-04-10","dateFrom":"2026-04-10","dateTo":"2026-04-10","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"","rigger":"—","desc":"Booking","price":"RM 3,812","diesel":"RM 190","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00582","customer":"Egosky Steels sb","contact":"Aziz Mohamed","phone":"+60 13-661 3322","location":"Tanjung Langsat Terminal Bay 3","machine":"PLC-016 (see master)","plate":"5936","category":"Skylift","tonnage":"20m","date":"2026-04-13","dateFrom":"2026-04-13","dateTo":"2026-04-13","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Razak Hassan","rigger":"—","desc":"Booking","price":"RM 868","diesel":"RM 266","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00583","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Medini Iskandar, Plot J-7","machine":"PLC-009 (see master)","plate":"8569","category":"Mobile Crane","tonnage":"90t","date":"2026-04-09","dateFrom":"2026-04-09","dateTo":"2026-04-09","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yusof","rigger":"Pravin Raj","desc":"Booking","price":"RM 5,377","diesel":"RM 288","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00584","customer":"Easyfast","contact":"Jenny Wong","phone":"+60 12-770 4455","location":"JB Bandar","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2026-05-15","dateFrom":"2026-05-15","dateTo":"2026-05-15","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Richard","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 3,924","diesel":"RM 99","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00585","customer":"Pamir","contact":"Liyana A","phone":"+60 16-227 5577","location":"JB Bandar","machine":"PLC-004 (see master)","plate":"1484","category":"Mobile Crane","tonnage":"30t","date":"2026-05-01","dateFrom":"2026-05-01","dateTo":"2026-05-01","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Kanisan","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 8,158","diesel":"RM 463","remarks":"Bring outrigger pads","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00586","customer":"LKS Green","contact":"Wei Lim","phone":"+60 18-225 9911","location":"Pontian","machine":"PLC-008 (see master)","plate":"8908","category":"Mobile Crane","tonnage":"70t","date":"2026-05-08","dateFrom":"2026-05-08","dateTo":"2026-05-08","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Yusof","rigger":"Bala Krishnan","desc":"Booking","price":"RM 3,139","diesel":"RM 309","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00587","customer":"JEC Industrial","contact":"Vincent Lee","phone":"+60 14-552 2299","location":"JB Bandar","machine":"PLC-015 (see master)","plate":"3135","category":"Mobile Crane","tonnage":"250t","date":"2026-05-31","dateFrom":"2026-05-31","dateTo":"2026-06-01","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Hanapi","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 4,395","diesel":"RM 176","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00587","customer":"JEC Industrial","contact":"Vincent Lee","phone":"+60 14-552 2299","location":"JB Bandar","machine":"PLC-015 (see master)","plate":"3135","category":"Mobile Crane","tonnage":"250t","date":"2026-06-01","dateFrom":"2026-05-31","dateTo":"2026-06-01","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Hanapi","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 4,395","diesel":"RM 176","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00588","customer":"DYC Aviation","contact":"Aminah Yusof","phone":"+60 19-554 8821","location":"Tanjung Langsat Terminal Bay 3","machine":"PLC-004 (see master)","plate":"1484","category":"Mobile Crane","tonnage":"30t","date":"2026-05-21","dateFrom":"2026-05-21","dateTo":"2026-05-21","multi":false,"shift":"morning","start":"08:00","end":"12:00","operator":"Jembri","rigger":"Bala Krishnan","desc":"Booking","price":"RM 2,569","diesel":"RM 243","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00589","customer":"Transgreen","contact":"Sara Choo","phone":"+60 19-445 8821","location":"Pmu Cahaya","machine":"PLC-009 (see master)","plate":"8569","category":"Mobile Crane","tonnage":"90t","date":"2026-05-26","dateFrom":"2026-05-26","dateTo":"2026-05-26","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Kanisan","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 1,841","diesel":"RM 87","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00590","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"silc lot 7","machine":"PLC-008 (see master)","plate":"8908","category":"Mobile Crane","tonnage":"70t","date":"2026-05-10","dateFrom":"2026-05-10","dateTo":"2026-05-12","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 2,190","diesel":"RM 96","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00590","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"silc lot 7","machine":"PLC-008 (see master)","plate":"8908","category":"Mobile Crane","tonnage":"70t","date":"2026-05-11","dateFrom":"2026-05-10","dateTo":"2026-05-12","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 2,190","diesel":"RM 96","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00590","customer":"KSB Builders","contact":"Tan Chee Keong","phone":"+60 12-998 7766","location":"silc lot 7","machine":"PLC-008 (see master)","plate":"8908","category":"Mobile Crane","tonnage":"70t","date":"2026-05-12","dateFrom":"2026-05-10","dateTo":"2026-05-12","multi":true,"shift":"custom","start":"07:00","end":"18:00","operator":"Yong Ah Seng","rigger":"Pravin Raj","desc":"Booking","price":"RM 2,190","diesel":"RM 96","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00591","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Seelong","machine":"PLC-008 (see master)","plate":"8908","category":"Mobile Crane","tonnage":"70t","date":"2026-06-21","dateFrom":"2026-06-21","dateTo":"2026-06-22","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Muthu","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 9,097","diesel":"RM 57","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00591","customer":"QRE Logistics","contact":"David Ng","phone":"+60 17-223 4456","location":"Seelong","machine":"PLC-008 (see master)","plate":"8908","category":"Mobile Crane","tonnage":"70t","date":"2026-06-22","dateFrom":"2026-06-21","dateTo":"2026-06-22","multi":true,"shift":"morning","start":"08:00","end":"12:00","operator":"Muthu","rigger":"Ahmad Faizal","desc":"Booking","price":"RM 9,097","diesel":"RM 57","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00592","customer":"QUANTUM RENEWABLE ENERGY","contact":"Mr Tan","phone":"+60 19-991 2233","location":"Kulai PLO 12, Lot 88","machine":"PLC-016 (see master)","plate":"5936","category":"Skylift","tonnage":"20m","date":"2026-06-08","dateFrom":"2026-06-08","dateTo":"2026-06-08","multi":false,"shift":"afternoon","start":"13:00","end":"17:00","operator":"Mohd Hafiz","rigger":"—","desc":"Booking","price":"RM 4,636","diesel":"RM 282","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00593","customer":"Ace Engineering","contact":"Lim Wei Ming","phone":"+60 12-345 6789","location":"Pontian","machine":"CR-002 Cross Rent 2","plate":"CR-2","category":"Cross Rent","tonnage":"50t","date":"2026-06-15","dateFrom":"2026-06-15","dateTo":"2026-06-15","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"","rigger":"—","desc":"Booking","price":"RM 8,542","diesel":"RM 101","remarks":"","status":"Job Completed","urgency":"normal"}, {"id":"BK-2026-00594","customer":"Easyfast","contact":"Jenny Wong","phone":"+60 12-770 4455","location":"Pontian","machine":"PLC-007 (see master)","plate":"9552","category":"Mobile Crane","tonnage":"50t","date":"2026-06-18","dateFrom":"2026-06-18","dateTo":"2026-06-18","multi":false,"shift":"custom","start":"07:00","end":"18:00","operator":"Hanapi","rigger":"Subash Kumar","desc":"Booking","price":"RM 5,164","diesel":"RM 509","remarks":"","status":"Job Completed","urgency":"normal"}, ]; // Roll every booking date forward to the live calendar so the demo's // yesterday/today/tomorrow buckets always align with the real Malaysia date. if (DATE_SHIFT !== 0) { BOOKINGS.forEach(b => { b.date = addDaysISO(b.date, DATE_SHIFT); if (b.dateFrom) b.dateFrom = addDaysISO(b.dateFrom, DATE_SHIFT); if (b.dateTo) b.dateTo = addDaysISO(b.dateTo, DATE_SHIFT); }); } // Backwards compat for existing pages still reading WORK_ORDERS const WORK_ORDERS = BOOKINGS.map(b => ({ ...b, crane: b.machine, duration: b.shift === 'custom' ? 'Custom' : (b.shift === 'morning' ? 'Half Day AM' : 'Half Day PM') })); const STATUS_MAP = { 'Assigned': { color: 'gray', label: 'Assigned' }, 'Accepted': { color: 'blue', label: 'Accepted' }, 'On the Way': { color: 'purple', label: 'On the Way' }, 'Arrived Site': { color: 'yellow', label: 'Arrived Site' }, 'Job Started': { color: 'orange', label: 'Job Started' }, 'Job Completed': { color: 'green', label: 'Completed' }, 'Pending Issue': { color: 'red', label: 'Pending Issue' }, 'Cancelled': { color: 'gray', label: 'Cancelled' }, }; // === Daily ops notes (Admin + Operation only) ======================== // Freeform per-day standup log — direct port from AppSheet "Notes" const DAILY_NOTES = [ { date: '2026-04-29', author: 'Sarah Tan', text: 'Ahmad Shafiq absence — back at 9.30am. Irwan to ride 6382 with Razak. JKR officer arriving 9am Medini site.' }, { date: '2026-04-28', author: 'Sarah Tan', text: 'Heavy rain forecast PM — Bukit Indah job moved to morning shift only. Cancelled Kulai job at 11am — chargeable per terms.' }, { date: '2026-04-27', author: 'Wei Ming Lim', text: 'PLC-006 returned from workshop — back in fleet. PLC-013 still in for boom inspection until Friday.' }, { date: '2026-04-26', author: 'Sarah Tan', text: 'New customer onboarded — DYC Aviation, contact Aminah. Rate card sent.' }, { date: '2026-04-25', author: 'Wei Ming Lim', text: 'Diesel surcharge updated to RM 0.45/L effective today (was RM 0.40/L). All quotes after 25/4 use new rate.' }, ].map(n => ({ ...n, date: addDaysISO(n.date, DATE_SHIFT) })); const NOTIFICATIONS = [ { id: 1, type: 'job', title: 'Tomorrow\'s Schedule Released', msg: 'Your jobs for 30 April are now available. 1 booking — 8:00 AM at Senai Airport with Rigger Ahmad Faizal.', time: '7:00 PM', unread: true, kind: 'info' }, { id: 2, type: 'urgent', title: 'Tomorrow\'s Job Changed', msg: 'BK-2026-00427 — start time moved from 6:00 AM to 8:00 AM. Customer rescheduled after 7pm cut-off. Please confirm.', time: '9 min ago', unread: true, kind: 'urgent' }, { id: 3, type: 'change', title: 'Job Location Changed', msg: 'BK-2026-00422 — new gate access via Berth 7, not Berth 8. Re-route operator.', time: '1 hr ago', unread: true, kind: 'info' }, { id: 4, type: 'job', title: 'New Booking Assigned', msg: '50 Ton Crane, Pasir Gudang, 29 April 2026, 8:00 AM. Customer: Ace Engineering.', time: '3 hr ago', unread: false, kind: 'info' }, { id: 5, type: 'mechanic', title: 'Repair Ticket Assigned', msg: 'Liebherr LTM 1090 (PLC-003) — hydraulic leak. Mechanic Awei assigned, priority high.', time: 'Yesterday', unread: false, kind: 'urgent' }, { id: 6, type: 'approval', title: 'Approval Request', msg: 'Quote for MTC Petrochem (RM 18,500) awaiting management sign-off.', time: 'Yesterday', unread: false, kind: 'info' }, { id: 7, type: 'cancel', title: 'Job Cancelled', msg: 'BK-2026-00419 — JEC Industrial cancelled by customer. Diesel + travel still chargeable.', time: '2 days ago', unread: false, kind: 'success' }, ]; // === R&M ============================================================ // Repair = unscheduled fault tickets; Maintenance = recurring schedule. // Maintenance days_left can be negative (overdue). const REPAIR_TICKETS = [ { id: 'RT-0142', machine: 'JFR 4368 (20T)', issue: 'Hydraulic line leak — boom cylinder', priority: 'High', mechanic: 'Awei', parts: 'Hydraulic seal kit, 2L ATF', supplier: 'Hydratek JB', cost: 'RM 1,840', status: 'In Progress', remarks: '', opened: '2026-04-27' }, { id: 'RT-0141', machine: 'JGA 9744 (20T)', issue: 'Slew gear noise on left rotation', priority: 'Medium', mechanic: 'Sathya', parts: 'Slew bearing grease, gasket', supplier: 'Komatsu JB', cost: 'RM 620', status: 'Awaiting Parts', remarks: 'Gear inspection clear — lubrication issue', opened: '2026-04-26' }, { id: 'RT-0140', machine: 'JEM 5114 (20T)', issue: 'Outrigger jack drift on rear-left', priority: 'High', mechanic: 'Awei', parts: 'Check valve, hydraulic hose', supplier: 'Grove SEA', cost: 'RM 2,200', status: 'Completed', remarks: 'Replaced check valve, system pressure-tested OK.', opened: '2026-04-22' }, { id: 'RT-0139', machine: 'JSB 8382 (50T)', issue: 'Engine warning light — DEF system', priority: 'Low', mechanic: 'Melon', parts: 'DEF fluid 10L', supplier: 'Tadano SC', cost: 'RM 95', status: 'Completed', remarks: 'Topped up, sensor reset.', opened: '2026-04-19' }, { id: 'RT-0138', machine: 'BRS 3135 (7T)', issue: 'Boom inspection annual — pending parts', priority: 'Medium', mechanic: 'Sathya', parts: 'Inspection seal kit', supplier: 'Liebherr SEA', cost: 'RM 1,250', status: 'In Progress', remarks: 'Annual NIOSH inspection in progress', opened: '2026-04-21' }, ]; // === Regular maintenance: FIXED service catalog ===================== // Each recurring item has a FIXED countdown period, expressed in MONTHS. // These are the standard service intervals applied to every mobile crane. // Editing here changes the interval everywhere the item is scheduled. const SERVICE_ITEMS = [ { item: 'Engine Oil', months: 3 }, { item: 'Gear Oil', months: 6 }, { item: 'Steering Oil', months: 6 }, { item: 'Back Gear Oil', months: 12 }, { item: 'Swing Oil', months: 6 }, { item: 'Hydraulic Filter (2 units)', months: 6 }, { item: 'Hydraulic Oil (M)', months: 60 }, { item: 'Oberon Grease', months: 12 }, { item: 'Chain Sling 1', months: 36 }, { item: 'Chain Sling 2', months: 36 }, ]; // Quick lookup: service item name -> fixed interval in months const SERVICE_INTERVAL_MONTHS = SERVICE_ITEMS.reduce((acc, s) => { acc[s.item] = s.months; return acc; }, {}); // Workshop dropdown sources for R&M (new ticket / add schedule) const MECHANICS = ['Awei', 'Sathya', 'Melon']; const SUPPLIERS = [ 'Hydratek JB', 'Komatsu JB', 'Grove SEA', 'Tadano SC', 'Liebherr SEA', 'Hap Seng Trucks', 'JB Hydraulics & Oil', 'Southern Parts Supply', ]; // === Supplier directory (Master Data › Supplier) ===================== // Richer records than the SUPPLIERS dropdown list above — these drive the // Supplier master table. `name` matches the dropdown strings so R&M tickets // and these records reconcile. const SUPPLIER_DIRECTORY = [ { id: 'SUP-01', name: 'Hydratek JB', category: 'Hydraulics', contact: 'Mr. Tan C.K.', phone: '+60 7-238 4471', email: 'sales@hydratek.com.my', terms: '30 days', status: 'Active' }, { id: 'SUP-02', name: 'Komatsu JB', category: 'OEM Parts', contact: 'Ms. Faridah', phone: '+60 7-557 9920', email: 'parts@komatsu-jb.com', terms: '45 days', status: 'Active' }, { id: 'SUP-03', name: 'Grove SEA', category: 'OEM Parts', contact: 'David Lim', phone: '+65 6863 2200', email: 'support@grovesea.com', terms: '60 days', status: 'Active' }, { id: 'SUP-04', name: 'Tadano SC', category: 'OEM Parts', contact: 'Ken Yamada', phone: '+65 6265 1188', email: 'parts@tadano.com.sg', terms: '60 days', status: 'Active' }, { id: 'SUP-05', name: 'Liebherr SEA', category: 'OEM Parts', contact: 'Anna Wahid', phone: '+65 6418 1000', email: 'service@liebherr.sg', terms: '60 days', status: 'Active' }, { id: 'SUP-06', name: 'Hap Seng Trucks', category: 'Tyres & Trucks', contact: 'Mr. Goh', phone: '+60 7-861 2233', email: 'jb@hapsengtrucks.com', terms: '30 days', status: 'Active' }, { id: 'SUP-07', name: 'JB Hydraulics & Oil', category: 'Lubricants', contact: 'Rahman Aziz', phone: '+60 7-334 8810', email: 'order@jbhydoil.my', terms: '14 days', status: 'Active' }, { id: 'SUP-08', name: 'Southern Parts Supply', category: 'Consumables', contact: 'Lim Siew Hong', phone: '+60 7-552 1047', email: 'sps@southernparts.my', terms: '30 days', status: 'On hold' }, ]; // === Parts & consumables inventory (Master Data › Stocks) ============ // Workshop store stock. `qty` vs `reorder` drives the low-stock flag. const STOCKS = [ { id: 'STK-001', item: 'Hydraulic seal kit (boom cylinder)', sku: 'HSK-20T', category: 'Hydraulics', qty: 6, unit: 'kit', reorder: 4, location: 'Rack A-2', supplier: 'Hydratek JB' }, { id: 'STK-002', item: 'ATF hydraulic oil', sku: 'ATF-208L', category: 'Lubricants', qty: 3, unit: 'drum', reorder: 2, location: 'Bay B', supplier: 'JB Hydraulics & Oil' }, { id: 'STK-003', item: 'Slew bearing grease', sku: 'GRS-EP2', category: 'Lubricants', qty: 18, unit: 'tube', reorder: 10, location: 'Rack A-1', supplier: 'JB Hydraulics & Oil' }, { id: 'STK-004', item: 'Engine oil filter', sku: 'FLT-OIL', category: 'Filters', qty: 2, unit: 'pc', reorder: 6, location: 'Rack C-3', supplier: 'Komatsu JB' }, { id: 'STK-005', item: 'Fuel filter element', sku: 'FLT-FUEL', category: 'Filters', qty: 9, unit: 'pc', reorder: 6, location: 'Rack C-3', supplier: 'Komatsu JB' }, { id: 'STK-006', item: 'DEF fluid (AdBlue)', sku: 'DEF-10L', category: 'Consumables', qty: 12, unit: 'jug', reorder: 8, location: 'Bay B', supplier: 'Tadano SC' }, { id: 'STK-007', item: 'Wire rope 16mm', sku: 'WR-16', category: 'Rigging', qty: 120, unit: 'm', reorder: 60, location: 'Yard', supplier: 'Southern Parts Supply' }, { id: 'STK-008', item: 'Bow shackle 8.5T', sku: 'SHK-85', category: 'Rigging', qty: 5, unit: 'pc', reorder: 12, location: 'Rack D-1', supplier: 'Southern Parts Supply' }, { id: 'STK-009', item: 'Webbing sling 5T x 4m', sku: 'SLG-5T4', category: 'Rigging', qty: 22, unit: 'pc', reorder: 10, location: 'Rack D-2', supplier: 'Southern Parts Supply' }, { id: 'STK-010', item: 'Outrigger check valve', sku: 'CV-OR', category: 'Hydraulics', qty: 1, unit: 'pc', reorder: 3, location: 'Rack A-2', supplier: 'Grove SEA' }, { id: 'STK-011', item: 'Brake pad set', sku: 'BRK-PAD', category: 'Consumables', qty: 7, unit: 'set', reorder: 4, location: 'Rack C-1', supplier: 'Hap Seng Trucks' }, { id: 'STK-012', item: 'Tyre 14.00-24 (rough terrain)', sku: 'TYR-1424', category: 'Tyres', qty: 4, unit: 'pc', reorder: 4, location: 'Yard', supplier: 'Hap Seng Trucks' }, ]; // === Maintenance schedule (generated from the fixed catalog) ========= // Each tracked crane carries the full service checklist above. last/next are // derived from the fixed interval; days_left counts down to next service. const MAINTENANCE = (function buildMaintenance() { const TODAY_D = new Date(TODAY + 'T00:00:00'); const DAY = 86400000; // Deterministic pseudo-random so the demo spread is stable across reloads. let seed = 1337; const rnd = () => { seed = (seed * 1103515245 + 12345) & 0x7fffffff; return seed / 0x7fffffff; }; const addMonths = (d, m) => { const x = new Date(d); x.setMonth(x.getMonth() + m); return x; }; const fmt = (d) => isoFromLocal(d); // Tracked cranes — use the real fleet labels from MACHINES. const trackedIds = ['PLC-001', 'PLC-003', 'PLC-005', 'PLC-007', 'PLC-009', 'PLC-011']; const label = (id) => { const m = MACHINES.find(x => x.id === id); return m ? machineLabel(m) : id; }; const rows = []; let n = 1; trackedIds.forEach((id) => { SERVICE_ITEMS.forEach((s) => { const intervalDays = Math.round(s.months * 30.44); // Where in its cycle is this item? Short-interval items (engine/oils) are // allowed to slip overdue; long-interval items (chain slings, hyd oil M) // sit comfortably mid-cycle. const lo = s.months <= 6 ? -0.22 : 0.05; const frac = lo + rnd() * (1 - lo); const daysLeft = Math.round(frac * intervalDays); const next = new Date(TODAY_D.getTime() + daysLeft * DAY); const last = addMonths(next, -s.months); rows.push({ id: 'MT-' + String(n++).padStart(3, '0'), machine: label(id), type: s.item, months: s.months, interval_days: intervalDays, days_left: daysLeft, last: fmt(last), next: fmt(next), }); }); }); return rows; })(); const ROLES = ['Admin', 'Operation', 'Operator', 'Rigger', 'Mechanic', 'Finance', 'Management']; // === Role-Based Access Control ====================================== // 'view' = read-only · 'edit' = view + create/edit · 'none' = hidden // Special rules layered on top in pages: // - Bookings: only Admin can CREATE; only Management can DELETE // - Customers: only Admin can ADD/EDIT // - Notes: only Admin + Operation can VIEW const PERMISSIONS = { dashboard: { Admin: 'edit', Operation: 'view', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'view', Management: 'view' }, allbookings: { Admin: 'edit', Operation: 'edit', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'view', Management: 'edit' }, bookings: { Admin: 'edit', Operation: 'edit', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'view', Management: 'edit' }, // Mgmt edit = delete authority create: { Admin: 'edit', Operation: 'none', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'none', Management: 'none' }, // Admin ONLY notes: { Admin: 'edit', Operation: 'edit', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'none', Management: 'none' }, // Admin + Op only mobile: { Admin: 'view', Operation: 'view', Operator: 'edit', Rigger: 'edit', Mechanic: 'none', Finance: 'none', Management: 'none' }, completion: { Admin: 'view', Operation: 'view', Operator: 'edit', Rigger: 'view', Mechanic: 'none', Finance: 'view', Management: 'view' }, notifications: { Admin: 'edit', Operation: 'edit', Operator: 'view', Rigger: 'view', Mechanic: 'view', Finance: 'view', Management: 'view' }, rm: { Admin: 'edit', Operation: 'view', Operator: 'none', Rigger: 'none', Mechanic: 'edit', Finance: 'none', Management: 'view' }, rmitems: { Admin: 'edit', Operation: 'view', Operator: 'none', Rigger: 'none', Mechanic: 'view', Finance: 'view', Management: 'view' }, // Master Data — only Admin can add/edit analytics: { Admin: 'edit', Operation: 'none', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'view', Management: 'edit' }, export: { Admin: 'edit', Operation: 'none', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'edit', Management: 'view' }, pricelist: { Admin: 'edit', Operation: 'view', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'edit', Management: 'view' }, // Master Data › Customer masterdata: { Admin: 'edit', Operation: 'view', Operator: 'none', Rigger: 'none', Mechanic: 'view', Finance: 'view', Management: 'view' }, // Machinery — only Admin can add/edit employees: { Admin: 'edit', Operation: 'view', Operator: 'none', Rigger: 'none', Mechanic: 'view', Finance: 'view', Management: 'view' }, stocks: { Admin: 'edit', Operation: 'view', Operator: 'none', Rigger: 'none', Mechanic: 'edit', Finance: 'view', Management: 'view' }, suppliers: { Admin: 'edit', Operation: 'view', Operator: 'none', Rigger: 'none', Mechanic: 'view', Finance: 'edit', Management: 'view' }, tools: { Admin: 'edit', Operation: 'view', Operator: 'view', Rigger: 'view', Mechanic: 'view', Finance: 'none', Management: 'view' }, users: { Admin: 'edit', Operation: 'none', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'none', Management: 'none' }, settings: { Admin: 'edit', Operation: 'none', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'none', Management: 'none' }, permissions: { Admin: 'view', Operation: 'none', Operator: 'none', Rigger: 'none', Mechanic: 'none', Finance: 'none', Management: 'none' }, }; const can = (role, page) => (PERMISSIONS[page] && PERMISSIONS[page][role]) || 'none'; const canView = (role, page) => can(role, page) !== 'none'; const canEdit = (role, page) => can(role, page) === 'edit'; // Special-case action gates (layered on top of page perms) const canCreateBooking = (role) => role === 'Admin'; const canDeleteBooking = (role) => role === 'Management'; const canEditMasterData = (role) => role === 'Admin'; const ROLE_LANDING = { Admin: 'dashboard', Operation: 'bookings', // lands on Today's bookings Operator: 'mobile', Rigger: 'mobile', Mechanic: 'rm', Finance: 'export', Management: 'analytics', }; // === Display categories for the User Management roster ================= // Roles drive permissions (above); these tidy categories drive how the // User Management table is grouped & labelled. One category can fold in // more than one underlying role. const USER_CATEGORIES = ['Super Admin', 'Management', 'Account and Finance', 'Dispatch', 'Mechanic', 'Operator', 'Rigger']; const ROLE_CATEGORY = { Admin: 'Super Admin', Operation: 'Account and Finance', Operator: 'Operator', Rigger: 'Rigger', Mechanic: 'Mechanic', Finance: 'Account and Finance', Management: 'Management', }; const userCategory = (u) => u.category || ROLE_CATEGORY[u.role] || 'Operator'; const USERS = [ // ---- Super Admin ---- { id: 1, name: 'Teon Lee', role: 'Admin', email: 'admin@powleecrane.com', phone: '+60 12-345 6789', status: 'Active', last: '2 min ago' }, // ---- Account ---- { id: 2, name: 'Lee Mei Yee', role: 'Operation', email: 'dispatch@powleecrane.com', phone: '+60 13-887 2210', status: 'Active', last: '5 min ago' }, // ---- Dispatch ---- { id: 3, name: 'Miss Wong', role: 'Operation', category: 'Dispatch', email: 'dispatch2@powleecrane.com', phone: '+60 12-553 8841', status: 'Active', last: '8 min ago' }, { id: 4, name: 'Lim Kok Wai', role: 'Operation', category: 'Dispatch', email: 'dispatch3@powleecrane.com', phone: '+60 16-998 4420', status: 'Active', last: '32 min ago' }, // ---- Operators ---- { id: 10, name: 'Hisham', role: 'Operator', email: 'hisham@powleecrane.com', phone: '+60 16-789 7008', status: 'On Job', last: 'On site' }, { id: 11, name: 'Muthu', role: 'Operator', email: 'muthu@powleecrane.com', phone: '+60 16-374 3994', status: 'On Job', last: 'On site' }, { id: 12, name: 'Ganis', role: 'Operator', email: 'ganis@powleecrane.com', phone: '+60 16-721 5848', status: 'On Job', last: 'On site' }, { id: 13, name: 'Selva', role: 'Operator', email: 'selva@powleecrane.com', phone: '+60 16-986 7369', status: 'Active', last: '1 hr ago' }, { id: 14, name: 'Rohezal', role: 'Operator', email: 'rohezal@powleecrane.com', phone: '+60 13-660 5328', status: 'On Job', last: 'On site' }, { id: 15, name: 'Hairul', role: 'Operator', email: 'hairul@powleecrane.com', phone: '+60 19-430 5896', status: 'Active', last: '3 hr ago' }, { id: 16, name: 'Kanisan', role: 'Operator', email: 'kanisan@powleecrane.com', phone: '+60 16-797 3375', status: 'On Job', last: 'On site' }, { id: 17, name: 'Rajah', role: 'Operator', email: 'rajah@powleecrane.com', phone: '+60 16-770 3342', status: 'On Job', last: 'On site' }, { id: 18, name: 'Zorkapli', role: 'Operator', email: 'zorkapli@powleecrane.com', phone: '+60 13-734 4312', status: 'Active', last: '2 hr ago' }, { id: 19, name: 'Zul30ton', role: 'Operator', email: 'zul@powleecrane.com', phone: '+60 12-748 7354', status: 'On Job', last: 'On site' }, { id: 20, name: 'Yusof', role: 'Operator', email: 'yusof@powleecrane.com', phone: '+60 18-375 4589', status: 'Active', last: '4 hr ago' }, { id: 21, name: 'Izzul', role: 'Operator', email: 'izzul@powleecrane.com', phone: '+60 10-251 7763', status: 'On Job', last: 'On site' }, { id: 22, name: 'Radzi', role: 'Operator', email: 'radzi@powleecrane.com', phone: '+60 18-288 0809', status: 'On Job', last: 'On site' }, { id: 23, name: 'Ahmad', role: 'Operator', email: 'ahmad@powleecrane.com', phone: '+60 11-2867 5289', status: 'Active', last: '1 hr ago' }, { id: 24, name: 'Hanapi', role: 'Operator', email: 'hanapi@powleecrane.com', phone: '+60 11-2943 2457', status: 'On Job', last: 'On site' }, { id: 25, name: 'Jembri', role: 'Operator', email: 'jembri@powleecrane.com', phone: '+60 11-1487 3758', status: 'Active', last: '2 hr ago' }, { id: 26, name: 'Azizi', role: 'Operator', email: 'azizi@powleecrane.com', phone: '+60 18-781 1640', status: 'On Job', last: 'On site' }, { id: 27, name: 'Ah Chuan', role: 'Operator', email: 'ahchuan@powleecrane.com', phone: '+60 18-255 5868', status: 'Active', last: '5 hr ago' }, { id: 28, name: 'N/A', role: 'Operator', email: '—', phone: '—', status: 'Standby', last: 'Vacant slot' }, { id: 29, name: 'Shafiq', role: 'Operator', email: 'shafiq@powleecrane.com', phone: '+60 11-2132 0705', status: 'On Job', last: 'On site' }, { id: 30, name: 'Ah Hau (ganti)', role: 'Operator', email: 'ahhau@powleecrane.com', phone: '—', status: 'Standby', last: 'Relief / substitute' }, { id: 31, name: 'Richard', role: 'Operator', email: 'richard@powleecrane.com', phone: '+60 12-847 0029', status: 'On Job', last: 'On site' }, { id: 32, name: 'Teon', role: 'Operator', email: 'teon@powleecrane.com', phone: '+60 16-713 6382', status: 'Active', last: '3 hr ago' }, // ---- Riggers ---- { id: 33, name: 'A. Shafik', role: 'Rigger', email: 'ashafik@powleecrane.com', phone: '+60 13-278 7576', status: 'On Job', last: 'On site' }, { id: 34, name: 'Shyami', role: 'Rigger', email: 'shyami@powleecrane.com', phone: '+60 16-552 9087', status: 'On Job', last: 'On site' }, { id: 35, name: 'Irwan', role: 'Rigger', email: 'irwan@powleecrane.com', phone: '+60 13-901 4478', status: 'Active', last: '1 hr ago' }, // ---- Mechanics ---- { id: 40, name: 'Awei', role: 'Mechanic', email: 'workshop@powleecrane.com', phone: '+60 16-223 4456', status: 'Active', last: '20 min ago' }, { id: 41, name: 'Sathya', role: 'Mechanic', email: 'sathya@powleecrane.com', phone: '+60 11-887 9911', status: 'Active', last: '1 day ago' }, { id: 42, name: 'Melon', role: 'Mechanic', email: 'melon@powleecrane.com', phone: '+60 18-664 2031', status: 'Active', last: '3 hr ago' }, // ---- Finance & Management ---- { id: 50, name: 'Miss Lim', role: 'Finance', email: 'finance@powleecrane.com', phone: '+60 19-554 8821', status: 'Active', last: 'Yesterday' }, { id: 51, name: 'Pang Sek Chin', role: 'Management', email: 'mgmt@powleecrane.com', phone: '+60 17-223 4456', status: 'Active', last: '4 hr ago' }, ]; // Today reference date — see klTodayISO()/TODAY defined above (Malaysia GMT+8). // === Booking overlap detection ====================================== // Two time ranges overlap iff start1 < end2 AND start2 < end1. // Returns the FIRST conflicting booking on the same plate + date, or null. function findBookingOverlap({ plate, date, start, end, excludeId }) { if (!plate || !date || !start || !end) return null; return BOOKINGS.find(b => b.id !== excludeId && b.plate === plate && b.date === date && start < b.end && b.start < end ) || null; } // Returns the FIRST conflicting booking where the same operator is already // scheduled within the requested time window, or null. function findOperatorOverlap({ operator, date, start, end, excludeId }) { if (!operator || operator === '—' || !date || !start || !end) return null; return BOOKINGS.find(b => b.id !== excludeId && b.operator === operator && b.date === date && start < b.end && b.start < end ) || null; } // Returns the FIRST conflicting booking where the same rigger is already // scheduled within the requested time window, or null. Riggers of '—' are skipped. function findRiggerOverlap({ rigger, date, start, end, excludeId }) { if (!rigger || rigger === '—' || !date || !start || !end) return null; return BOOKINGS.find(b => b.id !== excludeId && b.rigger === rigger && b.date === date && start < b.end && b.start < end ) || null; } Object.assign(window, { CATEGORIES, MACHINES, CUSTOMERS, LOCATIONS, OPERATORS, RIGGERS, SHIFT_OPTIONS, TOOLS, CERT_LEGEND, CERT_COLOR, CERT_LABEL, CERT_TODAY, CERT_RENEW_WINDOW_DAYS, certDaysLeft, certState, activeCerts, fmtCertDate, certReminders, machineLabel, bookingMachineLabel, BOOKINGS, WORK_ORDERS, STATUS_MAP, DAILY_NOTES, NOTIFICATIONS, REPAIR_TICKETS, MAINTENANCE, SERVICE_ITEMS, SERVICE_INTERVAL_MONTHS, MECHANICS, SUPPLIERS, SUPPLIER_DIRECTORY, STOCKS, ROLES, PERMISSIONS, can, canView, canEdit, canCreateBooking, canDeleteBooking, canEditMasterData, ROLE_LANDING, USERS, USER_CATEGORIES, ROLE_CATEGORY, userCategory, TODAY, addDaysISO, daysBetweenISO, klTodayISO, findBookingOverlap, findOperatorOverlap, findRiggerOverlap, });