false, 'ERROR' => 'unauthorized', 'MESSAGE' => 'Authentication required']); } try { $data = readJsonBody(); $line1 = trim($data['Line1'] ?? ''); $city = trim($data['City'] ?? ''); $stateId = (int) ($data['StateID'] ?? 0); $zipCode = trim($data['ZIPCode'] ?? ''); $line2 = trim($data['Line2'] ?? ''); $label = trim($data['Label'] ?? ''); $setAsDefault = (bool) ($data['SetAsDefault'] ?? false); $typeId = 2; // delivery if ($line1 === '' || $city === '' || $stateId <= 0 || $zipCode === '') { apiAbort(['OK' => false, 'ERROR' => 'missing_fields', 'MESSAGE' => 'Line1, City, StateID, and ZIPCode are required']); } if ($setAsDefault) { queryTimed(" UPDATE Addresses SET IsDefaultDelivery = 0 WHERE UserID = ? AND (BusinessID = 0 OR BusinessID IS NULL) AND AddressTypeID = ? ", [$userId, $typeId]); } // Get next AddressID $qNext = queryOne("SELECT IFNULL(MAX(ID), 0) + 1 AS NextID FROM Addresses", []); $newAddressId = (int) $qNext['NextID']; queryTimed(" INSERT INTO Addresses (ID, UserID, BusinessID, AddressTypeID, Label, IsDefaultDelivery, Line1, Line2, City, StateID, ZIPCode, IsDeleted, AddedOn) VALUES (?, ?, 0, ?, ?, ?, ?, ?, ?, ?, ?, 0, NOW()) ", [ $newAddressId, $userId, $typeId, $label, $setAsDefault ? 1 : 0, $line1, $line2, $city, $stateId, $zipCode, ]); $qState = queryOne("SELECT Abbreviation, Name FROM tt_States WHERE ID = ?", [$stateId]); $stateAbbr = $qState['Abbreviation'] ?? ''; $displayText = $line1 . ($line2 !== '' ? ', ' . $line2 : '') . ', ' . $city . ', ' . $stateAbbr . ' ' . $zipCode; jsonResponse([ 'OK' => true, 'ADDRESS' => [ 'AddressID' => $newAddressId, 'TypeID' => $typeId, 'Label' => $label !== '' ? $label : 'Address', 'IsDefault' => $setAsDefault, 'Line1' => $line1, 'Line2' => $line2, 'City' => $city, 'StateID' => $stateId, 'StateAbbr' => $stateAbbr, 'StateName' => $qState['Name'] ?? '', 'ZIPCode' => $zipCode, 'DisplayText' => $displayText, ], ]); } catch (Exception $e) { jsonResponse(['OK' => false, 'ERROR' => 'server_error', 'MESSAGE' => $e->getMessage()]); }