command->error("CSV file not found at {$file}"); return; } $handle = fopen($file, 'r'); $headers = fgetcsv($handle); // Manual header mapping to correct column names $headerMap = [ 'Sale ID' => 'sale_id', 'Sale Name' => 'sale_name', 'Record Type' => 'record_type', 'Status' => 'status', 'Comp Source' => 'comp_source', 'Date Last Verified' => 'date_last_verified', 'Property Name' => 'property_name', 'Comp ID' => 'comp_id', 'Street' => 'street', 'City' => 'city', 'State/Province' => 'state_province', 'Zip/Postal Code' => 'zip_postal_code', 'Market' => 'market', 'Property County' => 'property_county', 'Sub-Market' => 'sub_market', 'Property Sub Type' => 'property_sub_type', '# of Units' => 'num_units', 'Building Size (SF)' => 'building_size_sf', 'Year Built' => 'year_built', 'Listing Date' => 'listing_date', 'DOM (Cumulative)' => 'dom_cumulative', 'Original Listing Price' => 'original_listing_price', 'Listing Price' => 'listing_price', 'Adv - AGI' => 'adv_agi', 'X - AGI' => 'x_agi', 'Adv - NOI' => 'adv_noi', 'X - NOI' => 'x_noi', 'Asking Price (Unit)' => 'asking_price_unit', 'Asking Price (SF)' => 'asking_price_sf', 'Asking GRM' => 'asking_grm', 'Asking Cap' => 'asking_cap', 'CAN/EXP/WTH Date' => 'can_exp_wth_date', 'DOM (Can/Exp)' => 'dom_can_exp', 'Pending Date' => 'pending_date', 'DOM (Pending)' => 'dom_pending', 'Sale Date' => 'sale_date', 'DOM (Sold)' => 'dom_sold', 'Length of Escrow' => 'length_of_escrow', 'Sale Price' => 'sale_price', 'Sold Price (Unit)' => 'sold_price_unit', 'Sold Price Delivered' => 'sold_price_delivered', 'Sold Price (SF)' => 'sold_price_sf', 'Sales Terms' => 'sales_terms', 'Sold GRM' => 'sold_grm', 'Sold Cap' => 'sold_cap', 'Loan Amount' => 'loan_amount', '% Down Payment' => 'percent_down_payment', 'Owner Occ Purchase' => 'owner_occ_purchase', 'Land Area (Acre)' => 'land_area_acre', ]; // Map headers to DB columns $columns = array_map(fn($h) => $headerMap[$h] ?? null, $headers); // List of date columns in your schema $dateColumns = [ 'date_last_verified', 'listing_date', 'can_exp_wth_date', 'pending_date', 'sale_date', ]; while (($row = fgetcsv($handle)) !== false) { $data = []; foreach ($columns as $index => $column) { if ($column) { $data[$column] = $row[$index]; } } // used in a moment if ($data["market"]) { $market = Market::firstOrCreate(["name" => $data["market"]]); if ($data["sub_market"]) { $subMarket = SubMarket::firstOrCreate(["name" => $data["market"], "market_id" => $market->id]); } } else { $market = ""; $subMarket = ""; } $data["market_id"] = $market ? $market->id : ""; $data["sub_market_id"] = $subMarket ? $subMarket->id : ""; unset($data["market"]); unset($data["sub_market"]); foreach ($dateColumns as $column) { if (!empty($data[$column])) { try { // Normalize date from M/D/YY → Y-m-d $data[$column] = Carbon::createFromFormat('n/j/y', $data[$column])->format('Y-m-d'); } catch (\Exception $e) { // You can log or handle formatting errors if needed $data[$column] = null; } } else { $data[$column] = null; } } foreach ($data as $col => $val) { if (trim($val) === "") { $data[$col] = null; } if ($val === "#Error!") { $data[$col] = -1; } } Sale::create($data); } fclose($handle); $this->command->info('✅ Sales imported successfully.'); } }