update address

This commit is contained in:
Phuoc Nguyen
2025-11-18 17:04:00 +07:00
parent a5eb95fa64
commit 0dda402246
33 changed files with 4250 additions and 232 deletions

View File

@@ -0,0 +1,105 @@
/// Address Entity
///
/// Represents a delivery/billing address for the user.
/// Corresponds to Frappe ERPNext Address doctype.
library;
import 'package:equatable/equatable.dart';
/// Address Entity
///
/// Domain entity representing a user's delivery or billing address.
class Address extends Equatable {
final String name;
final String addressTitle;
final String addressLine1;
final String phone;
final String? email;
final String? fax;
final String? taxCode;
final String cityCode;
final String wardCode;
final bool isDefault;
final String? cityName;
final String? wardName;
const Address({
required this.name,
required this.addressTitle,
required this.addressLine1,
required this.phone,
this.email,
this.fax,
this.taxCode,
required this.cityCode,
required this.wardCode,
this.isDefault = false,
this.cityName,
this.wardName,
});
@override
List<Object?> get props => [
name,
addressTitle,
addressLine1,
phone,
email,
fax,
taxCode,
cityCode,
wardCode,
isDefault,
cityName,
wardName,
];
/// Get full address display string
String get fullAddress {
final parts = <String>[];
parts.add(addressLine1);
if (wardName != null && wardName!.isNotEmpty) {
parts.add(wardName!);
}
if (cityName != null && cityName!.isNotEmpty) {
parts.add(cityName!);
}
return parts.join(', ');
}
/// Create a copy with modified fields
Address copyWith({
String? name,
String? addressTitle,
String? addressLine1,
String? phone,
String? email,
String? fax,
String? taxCode,
String? cityCode,
String? wardCode,
bool? isDefault,
String? cityName,
String? wardName,
}) {
return Address(
name: name ?? this.name,
addressTitle: addressTitle ?? this.addressTitle,
addressLine1: addressLine1 ?? this.addressLine1,
phone: phone ?? this.phone,
email: email ?? this.email,
fax: fax ?? this.fax,
taxCode: taxCode ?? this.taxCode,
cityCode: cityCode ?? this.cityCode,
wardCode: wardCode ?? this.wardCode,
isDefault: isDefault ?? this.isDefault,
cityName: cityName ?? this.cityName,
wardName: wardName ?? this.wardName,
);
}
@override
String toString() {
return 'Address(name: $name, addressTitle: $addressTitle, addressLine1: $addressLine1, phone: $phone, isDefault: $isDefault)';
}
}

View File

@@ -0,0 +1,27 @@
/// City Entity
///
/// Represents a city/province in Vietnam.
library;
import 'package:equatable/equatable.dart';
/// City Entity
///
/// Domain entity representing a city or province.
class City extends Equatable {
final String name; // Frappe ERPNext name/ID
final String cityName; // Display name
final String code; // City code
const City({
required this.name,
required this.cityName,
required this.code,
});
@override
List<Object?> get props => [name, cityName, code];
@override
String toString() => 'City(name: $name, cityName: $cityName, code: $code)';
}

View File

@@ -0,0 +1,27 @@
/// Ward Entity
///
/// Represents a ward/district in a city.
library;
import 'package:equatable/equatable.dart';
/// Ward Entity
///
/// Domain entity representing a ward or district within a city.
class Ward extends Equatable {
final String name; // Frappe ERPNext name/ID
final String wardName; // Display name
final String code; // Ward code
const Ward({
required this.name,
required this.wardName,
required this.code,
});
@override
List<Object?> get props => [name, wardName, code];
@override
String toString() => 'Ward(name: $name, wardName: $wardName, code: $code)';
}

View File

@@ -0,0 +1,38 @@
/// Address Repository Interface
///
/// Defines contract for address data operations.
library;
import 'package:worker/features/account/domain/entities/address.dart';
/// Address Repository
///
/// Repository interface for managing user addresses.
/// Online-only approach - all operations go directly to API.
abstract class AddressRepository {
/// Get list of addresses
///
/// Fetches all addresses for the authenticated user.
/// Optionally filter by default address status.
Future<List<Address>> getAddresses({bool? isDefault});
/// Create new address
///
/// Creates a new address and returns the created address with ID.
Future<Address> createAddress(Address address);
/// Update existing address
///
/// Updates an existing address identified by its name (ID).
Future<Address> updateAddress(Address address);
/// Delete address
///
/// Deletes an address by its name (ID).
Future<void> deleteAddress(String name);
/// Set address as default
///
/// Marks the specified address as default and unmarks others.
Future<void> setDefaultAddress(String name);
}

View File

@@ -0,0 +1,21 @@
/// Location Repository Interface
///
/// Contract for location (city/ward) data operations.
library;
import 'package:worker/features/account/domain/entities/city.dart';
import 'package:worker/features/account/domain/entities/ward.dart';
/// Location Repository
///
/// Defines methods for accessing city and ward data.
abstract class LocationRepository {
/// Get all cities (offline-first: cache → API)
Future<List<City>> getCities({bool forceRefresh = false});
/// Get wards for a specific city code
Future<List<Ward>> getWards(String cityCode, {bool forceRefresh = false});
/// Clear all cached location data
Future<void> clearCache();
}