feat: Adresszusatz (Ortsteil/Etage/Hinweis) anzeigen, Land nur im Ausland
- Address.addition aus dem Backend (ERP-Freitext, praktisch Ortsteil, Etage oder Hinweis); API-Client neu generiert. - Listen (Sortieren, Beladen, Liefer-Übersicht): Adresse mit Zusatz in Klammern, z. B. „… 41472 Neuss (Holzheim)". - Lieferdetails: „Zusatz: …" unter der Anschrift von Empfänger und Besteller; Land nur außerhalb Deutschlands. - Maps-Suche weiter ohne Zusatz (sonst stört „3 Etage" die Suche). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@ -31,6 +31,7 @@ extension ApiAddressMapper on api.Address {
|
||||
postalCode: postalCode,
|
||||
city: city,
|
||||
country: country,
|
||||
addition: addition,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -535,6 +535,7 @@ class TourRepositoryImpl implements TourRepository {
|
||||
postalCode: snap['postalCode'] as String,
|
||||
city: snap['city'] as String,
|
||||
country: snap['country'] as String,
|
||||
addition: snap['addition'] as String?,
|
||||
),
|
||||
erpBelegartId: (j['erpBelegartId'] as num).toInt(),
|
||||
erpBelegnummer: j['erpBelegnummer'] as String,
|
||||
|
||||
@ -12,17 +12,44 @@ class Address {
|
||||
required this.postalCode,
|
||||
required this.city,
|
||||
required this.country,
|
||||
this.addition,
|
||||
});
|
||||
|
||||
final String street;
|
||||
final String houseNumber;
|
||||
final String postalCode;
|
||||
final String city;
|
||||
/// Land laut ERP-Länderstamm (z. B. „Deutschland"), leer wenn unbekannt.
|
||||
final String country;
|
||||
|
||||
/// Einzeilige Darstellung für Listen/Header.
|
||||
String get oneLine =>
|
||||
'$street $houseNumber, $postalCode $city';
|
||||
/// Freier Adresszusatz aus dem ERP — praktisch Ortsteil, Etage oder
|
||||
/// Hinweis („Holzheim", „3 Etage", „Parterre"). `null`, wenn leer.
|
||||
final String? addition;
|
||||
|
||||
static const Set<String> _germany = {
|
||||
'd', 'de', 'deu', 'deutschland', 'germany', 'brd',
|
||||
};
|
||||
|
||||
/// Land für die Anzeige — nur außerhalb Deutschlands, sonst `null`.
|
||||
String? get foreignCountry {
|
||||
final c = country.trim();
|
||||
if (c.isEmpty || _germany.contains(c.toLowerCase())) return null;
|
||||
return c;
|
||||
}
|
||||
|
||||
/// Einzeilige Anschrift „Straße Nr, PLZ Ort" (+ Land, falls Ausland).
|
||||
/// Ohne Zusatz — so auch als Such-Query für Maps geeignet.
|
||||
String get oneLine => [
|
||||
'$street $houseNumber, $postalCode $city',
|
||||
if (foreignCountry case final c?) c,
|
||||
].join(', ');
|
||||
|
||||
/// Wie [oneLine], mit Adresszusatz in Klammern — für Listen, damit der
|
||||
/// Fahrer Ortsteil/Etage auf einen Blick sieht.
|
||||
String get oneLineWithAddition {
|
||||
final a = addition?.trim();
|
||||
return a == null || a.isEmpty ? oneLine : '$oneLine ($a)';
|
||||
}
|
||||
|
||||
Address copyWith({
|
||||
String? street,
|
||||
@ -30,6 +57,7 @@ class Address {
|
||||
String? postalCode,
|
||||
String? city,
|
||||
String? country,
|
||||
String? addition,
|
||||
}) {
|
||||
return Address(
|
||||
street: street ?? this.street,
|
||||
@ -37,6 +65,7 @@ class Address {
|
||||
postalCode: postalCode ?? this.postalCode,
|
||||
city: city ?? this.city,
|
||||
country: country ?? this.country,
|
||||
addition: addition ?? this.addition,
|
||||
);
|
||||
}
|
||||
|
||||
@ -48,8 +77,10 @@ class Address {
|
||||
other.houseNumber == houseNumber &&
|
||||
other.postalCode == postalCode &&
|
||||
other.city == city &&
|
||||
other.country == country;
|
||||
other.country == country &&
|
||||
other.addition == addition;
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(street, houseNumber, postalCode, city, country);
|
||||
int get hashCode =>
|
||||
Object.hash(street, houseNumber, postalCode, city, country, addition);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import 'package:hl_lieferservice/domain/entity/address.dart';
|
||||
import 'package:hl_lieferservice/domain/entity/contact_source.dart';
|
||||
import 'package:hl_lieferservice/domain/entity/customer.dart';
|
||||
import 'package:hl_lieferservice/domain/entity/delivery.dart';
|
||||
@ -116,6 +117,23 @@ class _SectionHeader extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Adresse ────────────────────────────────────────────────────────────
|
||||
|
||||
/// Zeilen unter „PLZ Ort": Land (nur Ausland) und Adresszusatz aus dem ERP
|
||||
/// (Ortsteil, Etage, Hinweis — für den Fahrer vor Ort wichtig).
|
||||
List<Widget> _addressExtras(Address address, {required double fontSize}) {
|
||||
final addition = address.addition?.trim();
|
||||
return [
|
||||
if (address.foreignCountry case final country?)
|
||||
Text(country, style: TextStyle(fontSize: fontSize)),
|
||||
if (addition != null && addition.isNotEmpty)
|
||||
Text(
|
||||
'Zusatz: $addition',
|
||||
style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.w700),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
// ─── Abweichender Empfänger ─────────────────────────────────────────────
|
||||
|
||||
/// Hervorgehobene Karte, wenn Lieferadresse oder Empfänger vom Besteller
|
||||
@ -210,6 +228,7 @@ class _DifferentRecipientCard extends StatelessWidget {
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
..._addressExtras(address, fontSize: 15),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -701,6 +720,7 @@ class _CustomerCard extends StatelessWidget {
|
||||
'${c.address.postalCode} ${c.address.city}',
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
..._addressExtras(c.address, fontSize: 14),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -439,7 +439,7 @@ class _NextDeliveryCard extends StatelessWidget {
|
||||
const SizedBox(height: 10),
|
||||
_InfoRow(
|
||||
icon: Icons.location_on_outlined,
|
||||
text: recipient.address.oneLine,
|
||||
text: recipient.address.oneLineWithAddition,
|
||||
emphasized: true,
|
||||
),
|
||||
if (recipient.differsFromOrderer)
|
||||
@ -846,7 +846,7 @@ class _DeliveryTile extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
recipient.address.oneLine,
|
||||
recipient.address.oneLineWithAddition,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
|
||||
@ -637,7 +637,7 @@ class _CustomerBody extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
recipient.address.oneLine,
|
||||
recipient.address.oneLineWithAddition,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
if (recipient.differsFromOrderer)
|
||||
|
||||
@ -556,7 +556,7 @@ class _OverviewTile extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
recipient.address.oneLine,
|
||||
recipient.address.oneLineWithAddition,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
|
||||
@ -60,7 +60,7 @@ class RecipientSubtitle extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(recipient.address.oneLine, style: addressStyle),
|
||||
Text(recipient.address.oneLineWithAddition, style: addressStyle),
|
||||
if (recipient.differsFromOrderer)
|
||||
OrdererHint(ordererName: ordererName),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user