em = $om; $this->loadBatteryModels(); $this->loadBatterySizes(); $this->loadVehicleManufacturers(); $this->loadVehicles(); $this->loadBatteries(); $this->jo_hash = []; parent::__construct(); } protected function configure() { $this->setName('legacy:import_jo') ->setDescription('Import a CSV file with legacy job orders.') ->setHelp('Updates job order, plate number and warranty database from imported CSV entries.') ->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.'); } protected function execute(InputInterface $input, OutputInterface $output) { $csv_file = $input->getArgument('file'); $output->writeln("parsing $csv_file...\n"); /* CSV column order: 0 - Internal ID 1 - Type 2 - Transaction Number 3 - Primary Information : Date of Transaction 4 - Primary Information : Job Order Number 5 - Primary Information : MEH : Transaction Type 6 - Primary Information : Reference JO Number 7 - Primary Information : Type of Service 8 - Primary Information : Warranty Status 9 - Primary Information : Transaction Origin 10 - Primary Information : Existing Battery 11 - Primary Information : Existing Battery Type 12 - Primary Information : Recommended Battery 13 - Primary Infromation : Alternative Battery 14 - Primary Information : Vehicle Plate Number 15 - Primary Information : Brand 16 - Primary Information : Make 17 - Primary Information : Model 18 - Primary Information : Vehicle Color 19 - Primary Information : Caller Name 20 - First Name 21 - Middle Name 22 - Last Name 23 - Primary Information : Caller Contact 24 - Primary Information : Caller Mobile No. 25 - Primary Information : Caller Landline No. 26 - Primary Information : Invoice / Company Name 27 - Primary Information : New Name? 28 - Primary Information : New Invoice / Company Name 29 - Primary Information : Delivery Instructions 30 - Primary Information : Agent Notes - Tier 1 31 - Primary Information : Delivery Date 32 - Primary Information : Delivery Time 33 - Primary Information : Advance Order 34 - Primary Information : Stages 35 - Primary Information : Reason for Cancellation 36 - Primary Information : Specify the Reason for Cancellation 37 - Primary Information : Payment Method 38 - Primary Information : Change for: 39 - Primary Information : Prepared by 40 - Current Battery Details : Serial No.: 41 - Current Battery Details : DR No.: 42 - Current Battery Details : Date of Replacement 43 - Current Battery Details : Battery Brand 44 - Current Battery Details : Type 45 - Current Battery Details : Issued By: 46 - Current Battery Details : Issued By Direct 47 - Original Battery Details : Serial No. 48 - Original Battery Details : OR No.: 49 - Original Battery Details : Date of Purchase 50 - Original Battery Details : Battery Brand: 51 - Original Battery Details : Battery Type: 52 - Original Battery Details : Purchased From: 53 - Original Battery Details : Purchase from Direct 54 - Original Battery Details : Current Warranty Expiration Date 55 - Original Battery Details : Trade-In Battery 56 - Dispatching : Agent Notes : Tier 2 57 - Dispatching : Notes (Customer Classification) 58 - Dispatching : Pending 59 - Dispatching : Pending - Awaiting Stocks 60 - Dispatching : Date started from Awaiting Stock 61 - Dispatching : 4TH Due 62 - Dispatching : 8TH Due 63 - Dispatching : 12TH Due 64 - Dispatching : 14TH Due 65 - Dispatching : Currently Assigned Enrollee 66 - Dispatching : Non-HUB? 67 - Dispatching : HUB Catered? 68 - Dispatching : Thru Annex? 69 - Dispatching : HUB List 70 - Dispatching : Annex List 71 - Dispatching : Exempted to 6% 72 - Dispatching : Rider Name List 73 - Dispatching : Rider Name 74 - Dispatching : Rider Contact Information 75 - DIspatching : Dispatch Time 76 - Dispatching : Dispatch Date 77 - Dispatching : Dispatched By 78 - Dispatching : Time of Arrival 79 - Dispatching : Time Job Completed 80 - Dispatching : For Line Up? 81 - DIspatching : Order 82 - Vehicle Location : Address 83 - Vehicle Location : Landmark 84 - Customer Service Record : Purchase Date 85 - Customer Service Record : Battery / Item 86 - Customer Service Record : Battery / Item Warranty in Months 87 - Customer Service Record : Warranty Inquiry (Expiration Date) 88 - JO : Amount 89 - JO : TAX 90 - JO : Discount 91 - JO : Final Amount 92 - Line Details : Item 93 - Line Details : Quantity 94 - Line Details : Item Rate 95 - Line Details : Price Level 96 - Line Details : Item Base Price 97 - Line Details : Price Level Amount Deductions 98 - Line Details : Final Amount 99 - Line Details : No Trade-In 100 - Line Details : Reason for No Trade-In 101 - Line Details : Battery Class 102 - Line Details : Discount Items 103 - Line Details : Discount Code 104 - Line Details : Percentage 105 - Line Details : Converted Rate 106 - Line Details : Discount Amount 107 - Line Details : Warranty Classification 108 - Line Details : Warranty in Months 109 - Line Details : Warranty Expiration Date 110 - Line Details : Serial Number 111 - Line Details : Invoice/DR Number 112 - Line Details : Repalcement 113 - Line Details : Employee / Card No. / Referred by 114 - Line Details : Amount 115 - Line Details : Gross Amount 116 - Line Details : Gross Amount 117 - Time Stamp : Date / Time (JO Open) 118 - Time Stamp : Date / Time JO Saved 119 - Time Stamp : Ticket Handle TIme (in mins) 120 - Time Stamp : Idle Time 121 - Time Stamp : Date and Time (Dispatched By) 122 - Time Stamp : In-Transit Date and Time 123 - TIme Stamp : Completion Date and TIme 124 - TIme Stamp : Dispatch By to In-Transit Time (Time difference in Mins) 125 - Time Stamp : In-Transit to Completed (Time difference in Mins) 126 - Time Stamp : Raw Ticket Handle TIme (Decimal) 127 - Time Stamp : Raw Idle Time (Decimal) 128 - Account 129 - Status 130 - Tracking Numbers 131 - Memo 132 - Posting 133 - Notes 134 - Originally Assigned Enrollee 135 - Remarks 136 - Follow Up Transactions 137 - CARD TYPE 138 - CARD NO. 139 - Ongoing Editing 140 - Current User 141 - Cancellation Date 142 - Cancellation Time 143 - Ticket Completion Date 144 - Ticket Completion Time 145 - Date Created 146 - Time Created 147 - PREVIOUS STAGE 148 - DISPATCHED BY EDITED? 149 - Previous Dispatched By 150 - POST SERVICE 151 - Pending (2) 152 - COMPLETED MANUALLY 153 - THRU HUB NOTE 154 - CURRENTLY ASSIGNED ENROLLEE (free-form) 155 - IN-TRANSIT ALLOWANCE 156 - COPY FROM JO # 157 - NO. OF POSSIBLE DUPLICATE 158 - Call Status 159 - DISTRIBUTOR OUTLETS 160 - CURRENTLY ASSIGNED ENROLLEE (free-form) 161 - HUB LIST 162 - HUB LIST 2 163 - Enrollee 164 - Currently Assigned Enrollee 165 - Payment: */ // attempt to open file try { $fh = fopen($csv_file, "r"); } catch (Exception $e) { throw new Exception('The file "' . $csv_file . '" could be read.'); } // get entity manager $em = $this->em; $trans_types = []; $service_types = []; $no_sizes = []; // files $plate_outfile = fopen('/tmp/plate_numbers.csv', 'a'); $warr_outfile = fopen('/tmp/warranty.csv', 'a'); $jo_outfile = fopen('/tmp/legacy_jo.csv', 'a'); $jorow_outfile = fopen('/tmp/legacy_jo_row.csv', 'a'); $this->initializeMaxFieldCounters(); // loop through rows $save_plates = []; $row_num = 0; while (($fields = fgetcsv($fh)) !== false) { $row_num++; // $output->writeln("Parsing row " . $row_num . "..."); // ignore first 5 rows if ($row_num <= 5) continue; // check column count if (count($fields) != 166) { echo "*** wrong field count on row $row_num\n"; print_r($fields); exit; } $this->processLegacyTransaction($fields); // skip taxes if ($fields[14] == 'Bureau of Internal Revenue') { // $output->writeln('Skipping BIR line'); continue; } // clean plate numbers $id = $fields[0]; $plate_num = Warranty::cleanPlateNumber($fields[14]); if (!$plate_num) { // $output->writeln('Invalid plate number - ' . $fields[14]); $this->jo_hash[$id]['data']['plate_number'] = null; continue; } else $this->jo_hash[$id]['data']['plate_number'] = $plate_num; // let's track purchases first if ($fields[5] != 'PURCHASE') continue; // check if battery is found $found_battery = $this->findBattery($fields[92], $batt_model, $batt_size, $sap_code); if (!$found_battery) { // $output->writeln('battery not found - ' . $fields[92]); continue; } // find matching vehicle $found_vehicle = $this->findVehicle($fields[15], $fields[16], $fields[17], $vehicle); if (!$found_vehicle) { // $output->writeln('vehicle not found - ' . $fields[15] . ' - ' . $fields[16]); continue; } // consolidate transaction and service types $trans_types[$fields[5]] = 1; $service_types[$fields[7]] = $fields[5]; fwrite($plate_outfile, $plate_num . ',' . $vehicle['id'] . "\n"); if (isset($fields[107])) { // echo 'warranty class - ' . $fields[107] . "\n"; $warr_class = WarrantyClass::convertFromLegacy($fields[107]); if ($warr_class) { $batt_model_id = $batt_model; $batt_size_id = $batt_size; // model and size $line = $batt_model_id . ',' . $batt_size_id . ','; // echo 'wclass - ' . $warr_class . "\n"; // echo 'serial - ' . $fields[110] . "\n"; // echo 'expiry - ' . $fields[109] . "\n"; // serial if (isset($fields[110]) && strlen(trim($fields[110])) > 0) $line .= $fields[110] . ','; else $line .= '\N,'; // warranty class $line .= $warr_class . ','; // plate number $line .= $plate_num . ','; $date_today = new DateTime(); // status // check if expired if (isset($fields[109]) && strlen(trim($fields[109])) > 0) { $ex_date = DateTime::createFromFormat('m/d/Y', $fields[109]); $ex_tstamp = $ex_date->getTimestamp(); $today_tstamp = $date_today->getTimestamp(); if ($today_tstamp > $ex_tstamp) $status = WarrantyStatus::EXPIRED; else $status = WarrantyStatus::ACTIVE; } $line .= $status . ','; // date create $line .= $date_today->format('Ymd') . ','; // date purchase if (isset($fields[84]) && strlen(trim($fields[84])) > 0) { $pur_date = DateTime::createFromFormat('m/d/Y', $fields[84]); $line .= $pur_date->format('Ymd') . ','; } else $line .= '\N,'; // date expire if (isset($fields[109]) && strlen(trim($fields[109])) > 0) $line .= $ex_date->format('Ymd') . ','; else $line .= '\N,'; // date claim $line .= '\N,'; // claim id $line .= '\N,'; // sap battery id if (isset($sap_code)) $line .= $sap_code . ','; else $line .= '\N,'; // first name if (isset($fields[20]) && strlen(trim($fields[20])) > 0) $line .= $fields[20] . ','; else $line .= '\N,'; // last name if (isset($fields[22]) && strlen(trim($fields[22])) > 0) $line .= $fields[22] . ','; else $line .= '\N,'; // mobile number if (isset($fields[24]) && strlen(trim($fields[24])) > 0) $line .= $fields[24] . ','; else $line .= '\N'; fwrite($warr_outfile, $line . "\n"); } } /* // check if we marked it already if (isset($save_plates[$plate_num])) continue; // check if already there $find_plate = $em->getRepository(PlateNumber::class)->find($plate_num); if ($find_plate) { continue; } // save to db $o_plate = new PlateNumber(); $o_plate->setID($plate_num) ->setVehicle($vehicle['object']); $em->persist($o_plate); $save_plates[$plate_num] = true; */ /* // plate echo '14 - ' . $fields[14] . "\n"; // transaction echo '5 - ' . $fields[5] . "\n"; echo '7 - ' . $fields[7] . "\n"; // name echo '22 - ' . $fields[22] . "\n"; echo '20 - ' . $fields[20] . "\n"; echo '21 - ' . $fields[21] . "\n"; // number echo '23 - ' . $fields[23] . "\n"; echo '24 - ' . $fields[24] . "\n"; echo '25 - ' . $fields[25] . "\n"; // vehicle echo '15 - ' . $fields[15] . "\n"; echo '16 - ' . $fields[16] . "\n"; echo '17 - ' . $fields[17] . "\n"; echo '18 - ' . $fields[18] . "\n"; // battery echo '10 - ' . $fields[10] . "\n"; echo '11 - ' . $fields[11] . "\n"; echo '50 - ' . $fields[50] . "\n"; echo '51 - ' . $fields[51] . "\n"; echo '40 - ' . $fields[40] . "\n"; echo '43 - ' . $fields[43] . "\n"; echo '44 - ' . $fields[44] . "\n"; echo '47 - ' . $fields[47] . "\n"; echo '54 - ' . $fields[54] . "\n"; // customer service record echo '84 - ' . $fields[84] . "\n"; echo '85 - ' . $fields[85] . "\n"; echo '86 - ' . $fields[86] . "\n"; echo '87 - ' . $fields[87] . "\n"; */ // echo '92 - ' . $fields[92] . "\n"; /* echo '110 - ' . $fields[110] . "\n"; */ } // print_r($this->jo_hash); // $em->flush(); // print_r($trans_types); // print_r($service_types); // print_r($no_sizes); // print_r($b_models); // print_r($batteries); // save to db // print_r($batteries); // print_r($this->vehicle_hash); // print_r($no_makes); /* print_r($this->data_max_field_size); print_r($this->row_max_field_size); */ // save job order foreach ($this->jo_hash as $jo) { $id = $jo['data']['id']; $line = $this->exportJOData($jo['data']); fwrite($jo_outfile, $line . "\n"); foreach ($jo['rows'] as $jo_row) fputcsv($jorow_outfile, $jo_row); } fclose($plate_outfile); fclose($warr_outfile); fclose($jo_outfile); fclose($jorow_outfile); } protected function initializeMaxFieldCounters() { $this->data_fields = [ 'trans_type', 'origin', 'car_brand', 'car_make', 'car_model', 'car_color', 'cust_name', 'cust_first_name', 'cust_middle_name', 'cust_last_name', 'cust_contact', 'cust_mobile', 'cust_landline', 'delivery_instructions', 'agent_notes_1', 'delivery_date', 'delivery_time', 'advance_order', 'stage', 'cancel_reason', 'cancel_reason_specify', 'payment_method', 'prepared_by', 'dispatch_time', 'dispatch_date', 'dispatched_by', 'address', 'landmark', 'date_purchase', ]; $this->row_fields = [ 'item', 'qty', 'price', 'price_level', 'status', 'account', 'enrollee', ]; // initialize max field size counter $this->data_max_field_size = [ 'trans_type' => 0, 'origin' => 0, 'car_brand' => 0, 'car_make' => 0, 'car_model' => 0, 'car_color' => 0, 'cust_name' => 0, 'cust_first_name' => 0, 'cust_middle_name' => 0, 'cust_last_name' => 0, 'cust_contact' => 0, 'cust_mobile' => 0, 'cust_landline' => 0, 'delivery_instructions' => 0, 'agent_notes_1' => 0, 'delivery_date' => 0, 'delivery_time' => 0, 'advance_order' => 0, 'stage' => 0, 'cancel_reason' => 0, 'cancel_reason_specify' => 0, 'payment_method' => 0, 'prepared_by' => 0, 'dispatch_time' => 0, 'dispatch_date' => 0, 'dispatched_by' => 0, 'address' => 0, 'landmark' => 0, 'date_purchase' => 0, ]; $this->row_max_field_size = [ 'item' => 0, 'qty' => 0, 'price' => 0, 'price_level' => 0, 'status' => 0, 'account' => 0, 'enrollee' => 0, ]; } protected function processLegacyTransaction($fields) { // echo "trans type - " . $fields[5] . "\n"; // echo "origin - " . $fields[9] . "\n"; // echo "stage - " . $fields[34] . "\n"; // echo "payment method - " . $fields[37] . "\n"; // echo "price level - " . $fields[95] . "\n"; $id = $fields[0]; $trans_type = LegacyTransactionType::translate($fields[5]); $origin = LegacyOrigin::translate($fields[9]); // consolidate based on jo id if (!isset($this->jo_hash[$id])) { $this->jo_hash[$id] = [ // 'raw' => [], 'data' => [], 'rows' => [], ]; $date_trans = DateTime::createFromFormat('m/d/Y', $fields[3]); // labelled data $this->jo_hash[$id]['data'] = [ 'id' => $id, 'date_trans' => $date_trans->format('Ymd'), 'trans_type' => $trans_type, 'origin' => $fields[9], 'car_brand' => $fields[15], 'car_make' => $fields[16], 'car_model' => $fields[17], 'car_color' => $fields[18], 'cust_name' => $fields[19], 'cust_first_name' => $fields[20], 'cust_middle_name' => $fields[21], 'cust_last_name' => $fields[22], 'cust_contact' => $fields[23], 'cust_mobile' => $fields[24], 'cust_landline' => $fields[25], 'delivery_instructions' => $fields[29], 'agent_notes_1' => $fields[30], 'delivery_date' => $fields[31], 'delivery_time' => $fields[32], 'advance_order' => $fields[33], 'stage' => $fields[34], 'cancel_reason' => $fields[35], 'cancel_reason_specify' => $fields[36], 'payment_method' => $fields[37], 'prepared_by' => $fields[39], 'dispatch_time' => $fields[75], 'dispatch_date' => $fields[76], 'dispatched_by' => $fields[77], 'address' => $fields[82], 'landmark' => $fields[83], 'date_purchase' => $fields[84], ]; // max field size foreach ($this->data_fields as $data_field) { $len = strlen($this->jo_hash[$id]['data'][$data_field]); // echo "$data_field - $len vs " . $this->data_max_field_size[$data_field] . "\n"; if ($len > $this->data_max_field_size[$data_field]) $this->data_max_field_size[$data_field] = $len; } /* // raw for ($x = 0; $x < 88; $x++) $this->jo_hash[$id]['raw'][$x] = $fields[$x]; */ } $row = []; /* for ($x = 88; $x <= 165; $x++) $row[$x - 88] = $fields[$x]; */ $row = [ 'id' => $id, 'item' => $fields[92], 'qty' => $fields[93], 'price' => $fields[114], 'price_level' => $fields[95], 'status' => $fields[129], 'account' => $fields[128], 'enrollee' => $fields[134], ]; $this->jo_hash[$id]['rows'][] = $row; // max row field size foreach ($this->row_fields as $row_field) { $len = strlen($row[$row_field]); if ($len > $this->row_max_field_size[$row_field]) $this->row_max_field_size[$row_field] = $len; } } protected function exportJOData($data) { $line_data = []; foreach ($data as $field => $value) { $enc_value = str_replace('\\', '\\\\', $value); $line_data[] = str_replace('|', '\\|', $enc_value); } return implode('|', $line_data); } protected function loadBatteryModels() { $this->bmodel_hash = []; $models = $this->em->getRepository(BatteryModel::class)->findAll(); foreach ($models as $model) { // clean name // $name = strtoupper(trim(str_replace(' ', '', $model->getName()))); $name = $this->simplifyName($model->getName()); $this->bmodel_hash[$name] = $model->getID(); } } protected function loadBatterySizes() { $this->bsize_hash = []; $sizes = $this->em->getRepository(BatterySize::class)->findAll(); foreach ($sizes as $size) { // clean name // $name = strtoupper(trim(str_replace(' ', '', $size->getName()))); $name = $this->simplifyName($size->getName()); $this->bsize_hash[$name] = $size->getID(); } } protected function loadBatteries() { $this->batt_hash = []; $batts = $this->em->getRepository(Battery::class)->findAll(); foreach ($batts as $batt) { if (($batt->getModel() == null) or ($batt->getSize() == null) or ($batt->getSAPCode() == null)) { continue; } $model_id = $batt->getModel()->getID(); $size_id = $batt->getSize()->getID(); $this->batt_hash[$model_id][$size_id] = $batt->getSAPCode(); } } protected function loadVehicleManufacturers() { $this->vmfg_hash = []; $mfgs = $this->em->getRepository(VehicleManufacturer::class)->findAll(); foreach ($mfgs as $mfg) { $name = $this->simplifyName($mfg->getName(), false); $this->vmfg_hash[$name] = $mfg->getID(); } } protected function loadVehicles() { $this->vehicle_hash = []; $vs = $this->em->getRepository(Vehicle::class)->findAll(); foreach ($vs as $v) { $make = $this->simplifyName($v->getMake(), false); $mfg_id = $v->getManufacturer()->getID(); if (!isset($this->vehicle_hash[$mfg_id])) $this->vehicle_hash[$mfg_id] = []; if (!isset($this->vehicle_hash[$mfg_id][$make])) $this->vehicle_hash[$mfg_id][$make] = []; $this->vehicle_hash[$mfg_id][$make][] = [ 'id' => $v->getID(), 'year_from' => $v->getModelYearFrom(), 'year_to' => $v->getModelYearTo(), 'object' => $v, ]; } } protected function simplifyName($text, $replace_spaces = true) { if ($replace_spaces) $clean_text = strtoupper(trim(str_replace(' ', '', $text))); else $clean_text = strtoupper(trim($text)); return $clean_text; } protected function findBattery($batt_field, &$batt_model, &$batt_size, &$sap_code) { // split battery into model and size // echo "trying match - " . $batt_field . "\n"; $res = preg_match("/^(.+)(GOLD|EXCEL|ENDURO|\(Trade-In\))/", $batt_field, $matches); if (!$res) { //echo "no match - " . $fields[92] . "\n"; return false; } if ($matches[2] == '(Trade-In)') return false; $batt_model = $this->bmodel_hash[$matches[2]]; // $batt_model = $matches[2]; // TODO: what to do about (Trade-In) // check if we have the size $found_size = $this->simplifyName($matches[1]); if (!isset($this->bsize_hash[$found_size])) { // try legacy battery lookup $legacy_size = LegacyBattery::translate($found_size); if ($legacy_size == null) { // echo "no size - $found_size\n"; if (isset($no_sizes[$found_size])) $no_sizes[$found_size]++; else $no_sizes[$found_size] = 1; return false; } $found_size = $legacy_size; } $batt_size = $this->bsize_hash[$found_size]; // $batt_size = $found_size; //get battery using ids of batt_model and batt_size if (!isset($this->batt_hash[$batt_model][$batt_size])) return false; $sap_code = $this->batt_hash[$batt_model][$batt_size]; return true; } protected function findVehicle($vmfg_field, $vmake_field, $vmodel_field, &$vehicle) { // debug vehicles with no matching makes $no_makes = []; // vehicle manufacturers $found_vmfg = $this->simplifyName($vmfg_field, false); if (!isset($this->vmfg_hash[$found_vmfg])) { $legacy_vmfg = LegacyVehicleManufacturer::translate($found_vmfg); if ($legacy_vmfg == null) { // echo "vmfg not found - $vmfg_field\n"; return false; } $found_vmfg = $legacy_vmfg; } $vmfg_id = $this->vmfg_hash[$found_vmfg]; // vehicle make $found_make = $this->simplifyName($vmake_field, false); if (!isset($this->vehicle_hash[$vmfg_id][$found_make])) { $legacy_make = LegacyVehicle::translate($found_vmfg, $found_make); if ($legacy_make == null) { $no_makes[$found_make] = $found_vmfg . ' - ' . $found_make; // echo "vmake not found - $vmfg_field - $vmake_field\n"; return false; } $found_make = $legacy_make; // need to do this again because translate could change vmfg $vmfg_id = $this->vmfg_hash[$found_vmfg]; } $make_list = $this->vehicle_hash[$vmfg_id][$found_make]; // check if there's only one in the make list if (count($make_list) == 1) { $vehicle = $make_list[0]; return true; } // see which model matches $clean_model = trim(strtoupper($vmodel_field)); // no model specified, take first one $model_length = strlen($clean_model); if ($model_length == 0 || $clean_model == 'NONE') { $vehicle = $make_list[0]; return true; } // one year or range specified // we only take the first $cut_model = substr($clean_model, 0, 4); foreach ($make_list as $make) { // no year if ($make['year_from'] == 0 && $make['year_to'] == 0) { $vehicle = $make; return true; } // no year from if ($make['year_from'] == 0) { if ($make['year_to'] >= $cut_model) { $vehicle = $make; return true; } } // no year to if ($make['year_to'] == 0) { if ($make['year_from'] <= $cut_model) { $vehicle = $make; return true; } } // has year from and to if ($make['year_from'] <= $cut_model && $make['year_to'] >= $cut_model) { $vehicle = $make; return true; } } // echo "model search - $vmfg_id - $found_vmfg - $found_make - $vmodel_field\n"; // we get the first one, because we have no idea where it falls under $vehicle = $make_list[0]; return true; } }