fix: no exigir dirección cuando profesional solo atiende en consultorio

- _requestService: omite validación de dirección si locationPreferences=office
- Usa la dirección y coordenadas del consultorio del profesional en ese caso
- Botón y warnings de ciudad deshabilitados solo en modo domicilio/ambos
- Tarjeta inferior muestra dirección del consultorio cuando es office-only
- location_preference del servicio refleja correctamente office vs delivery

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-21 21:04:18 -05:00
co-authored by Claude Sonnet 4.6
parent c0fce73d41
commit 495502cfc1
+93 -38
View File
@@ -270,10 +270,6 @@ class _DashboardViewState extends State<DashboardView> {
} }
Future<void> _requestService() async { Future<void> _requestService() async {
if (_currentAddress.isEmpty) {
NotificationsService.showSnackBarError('Mueve el mapa para seleccionar tu dirección');
return;
}
if (_professional == null) { if (_professional == null) {
NotificationsService.showSnackBarError('Selecciona un profesional'); NotificationsService.showSnackBarError('Selecciona un profesional');
return; return;
@@ -282,6 +278,20 @@ class _DashboardViewState extends State<DashboardView> {
NotificationsService.showSnackBarError('Selecciona fecha y hora'); NotificationsService.showSnackBarError('Selecciona fecha y hora');
return; return;
} }
final profPrefs = _professional!.professionalInfo.locationPreferences;
final isOfficeOnly = profPrefs == LocationPreferences.office;
// Dirección solo requerida cuando el profesional hace domicilios
if (!isOfficeOnly && _currentAddress.isEmpty) {
NotificationsService.showSnackBarError('Mueve el mapa para seleccionar tu dirección');
return;
}
final serviceLocation = isOfficeOnly
? ServiceLocationPreferences.office
: ServiceLocationPreferences.delivery;
setState(() => _requesting = true); setState(() => _requesting = true);
try { try {
final service = Service( final service = Service(
@@ -290,10 +300,10 @@ class _DashboardViewState extends State<DashboardView> {
professionalScored: false, professionalScored: false,
userId: user!.id, userId: user!.id,
userScored: false, userScored: false,
address: _currentAddress, address: isOfficeOnly ? _professional!.professionalInfo.address : _currentAddress,
aditionalAddress: '', aditionalAddress: '',
latitude: _mapCenter.latitude, latitude: isOfficeOnly ? _professional!.professionalInfo.latitude : _mapCenter.latitude,
longitude: _mapCenter.longitude, longitude: isOfficeOnly ? _professional!.professionalInfo.longitude : _mapCenter.longitude,
day: _selectedDay.toString(), day: _selectedDay.toString(),
createdAt: DateTime.now().toIso8601String(), createdAt: DateTime.now().toIso8601String(),
description: '', description: '',
@@ -301,7 +311,7 @@ class _DashboardViewState extends State<DashboardView> {
range1Hour2: _selectedHour!.add(hour: 2), range1Hour2: _selectedHour!.add(hour: 2),
rate: '', rate: '',
status: ServiceStatus.pending, status: ServiceStatus.pending,
location: ServiceLocationPreferences.delivery, location: serviceLocation,
); );
await ApiService.instance.post('/services', service.toDocument()); await ApiService.instance.post('/services', service.toDocument());
NotificationsService.showSnackbar('Servicio solicitado exitosamente'); NotificationsService.showSnackbar('Servicio solicitado exitosamente');
@@ -559,33 +569,72 @@ class _DashboardViewState extends State<DashboardView> {
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
// Dirección actual // Dirección: solo relevante cuando el profesional hace domicilios
if (_currentAddress.isNotEmpty) Builder(builder: (context) {
Container( final prefs = _professional?.professionalInfo.locationPreferences;
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), final isOffice = prefs == LocationPreferences.office;
margin: const EdgeInsets.only(bottom: 10), if (isOffice) {
decoration: BoxDecoration( // Mostrar dirección del consultorio del profesional
color: isDark final profAddress = _professional?.professionalInfo.address ?? '';
? const Color(0xFF42A4EF).withOpacity(0.12) if (profAddress.isNotEmpty) {
: const Color(0xFFF0F8FF), return Container(
borderRadius: BorderRadius.circular(8), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
border: Border.all(color: const Color(0xFF42A4EF).withOpacity(0.35)), margin: const EdgeInsets.only(bottom: 10),
), decoration: BoxDecoration(
child: Row( color: isDark
children: [ ? const Color(0xFF42A4EF).withOpacity(0.08)
const Icon(Icons.location_on, size: 16, color: Color(0xFF42A4EF)), : const Color(0xFFF0F8FF),
const SizedBox(width: 8), borderRadius: BorderRadius.circular(8),
Expanded( border: Border.all(color: const Color(0xFF42A4EF).withOpacity(0.25)),
child: Text(
_currentAddress,
style: TextStyle(fontSize: 12, color: textColor),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
), ),
], child: Row(
), children: [
), const Icon(Icons.store_outlined, size: 16, color: Color(0xFF42A4EF)),
const SizedBox(width: 8),
Expanded(
child: Text(
'Consultorio: $profAddress',
style: TextStyle(fontSize: 12, color: textColor),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
return const SizedBox.shrink();
}
// Domicilio o ambos: mostrar dirección del cliente
if (_currentAddress.isNotEmpty) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
margin: const EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: isDark
? const Color(0xFF42A4EF).withOpacity(0.12)
: const Color(0xFFF0F8FF),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: const Color(0xFF42A4EF).withOpacity(0.35)),
),
child: Row(
children: [
const Icon(Icons.location_on, size: 16, color: Color(0xFF42A4EF)),
const SizedBox(width: 8),
Expanded(
child: Text(
_currentAddress,
style: TextStyle(fontSize: 12, color: textColor),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
return const SizedBox.shrink();
}),
// Profesional // Profesional
GestureDetector( GestureDetector(
@@ -670,7 +719,8 @@ class _DashboardViewState extends State<DashboardView> {
const SizedBox(height: 12), const SizedBox(height: 12),
// Aviso ciudad no disponible // Aviso ciudad no disponible
if (!_cityAvailable && _detectedCity.isNotEmpty) if (!_cityAvailable && _detectedCity.isNotEmpty &&
_professional?.professionalInfo.locationPreferences != LocationPreferences.office)
Container( Container(
width: double.infinity, width: double.infinity,
margin: const EdgeInsets.only(bottom: 10), margin: const EdgeInsets.only(bottom: 10),
@@ -707,8 +757,9 @@ class _DashboardViewState extends State<DashboardView> {
), ),
), ),
// Warning: dirección fuera de la ciudad del usuario // Warning: dirección fuera de la ciudad del usuario (solo en modo domicilio)
if (_cityMismatch && _detectedCity.isNotEmpty) if (_cityMismatch && _detectedCity.isNotEmpty &&
_professional?.professionalInfo.locationPreferences != LocationPreferences.office)
Container( Container(
width: double.infinity, width: double.infinity,
margin: const EdgeInsets.only(bottom: 10), margin: const EdgeInsets.only(bottom: 10),
@@ -748,7 +799,11 @@ class _DashboardViewState extends State<DashboardView> {
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: ElevatedButton( child: ElevatedButton(
onPressed: (_requesting || !_cityAvailable || _cityMismatch) ? null : _requestService, onPressed: _requesting
? null
: (_professional?.professionalInfo.locationPreferences == LocationPreferences.office
? _requestService
: (!_cityAvailable || _cityMismatch ? null : _requestService)),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF42A4EF), backgroundColor: const Color(0xFF42A4EF),
foregroundColor: Colors.white, foregroundColor: Colors.white,