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,158 @@
/// Address Model
///
/// Hive model for caching address data from ERPNext API.
library;
import 'package:hive_ce/hive.dart';
import 'package:worker/core/constants/storage_constants.dart';
import 'package:worker/features/account/domain/entities/address.dart';
part 'address_model.g.dart';
/// Address Model
///
/// Hive model for storing address data with ERPNext API compatibility.
@HiveType(typeId: HiveTypeIds.addressModel)
class AddressModel extends HiveObject {
/// Address name (ID in ERPNext)
@HiveField(0)
String name;
/// Display title for the address
@HiveField(1)
String addressTitle;
/// Address line 1 (street, number, etc.)
@HiveField(2)
String addressLine1;
/// Phone number
@HiveField(3)
String phone;
/// Email address
@HiveField(4)
String? email;
/// Fax number (optional)
@HiveField(5)
String? fax;
/// Tax code/ID
@HiveField(6)
String? taxCode;
/// City code (from ERPNext location master)
@HiveField(7)
String cityCode;
/// Ward code (from ERPNext location master)
@HiveField(8)
String wardCode;
/// Whether this is the default address
@HiveField(9)
bool isDefault;
/// City name (for display)
@HiveField(10)
String? cityName;
/// Ward name (for display)
@HiveField(11)
String? wardName;
AddressModel({
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,
});
/// Create from JSON (API response)
factory AddressModel.fromJson(Map<String, dynamic> json) {
return AddressModel(
name: json['name'] as String? ?? '',
addressTitle: json['address_title'] as String? ?? '',
addressLine1: json['address_line1'] as String? ?? '',
phone: json['phone'] as String? ?? '',
email: json['email'] as String?,
fax: json['fax'] as String?,
taxCode: json['tax_code'] as String?,
cityCode: json['city_code'] as String? ?? '',
wardCode: json['ward_code'] as String? ?? '',
isDefault: json['is_default'] == 1 || json['is_default'] == true,
cityName: json['city_name'] as String?,
wardName: json['ward_name'] as String?,
);
}
/// Convert to JSON (API request)
Map<String, dynamic> toJson() {
return {
// If name is empty, send null to indicate new address creation
'name': name.isEmpty ? null : name,
'address_title': addressTitle,
'address_line1': addressLine1,
'phone': phone,
if (email != null && email!.isNotEmpty) 'email': email,
if (fax != null && fax!.isNotEmpty) 'fax': fax,
if (taxCode != null && taxCode!.isNotEmpty) 'tax_code': taxCode,
'city_code': cityCode,
'ward_code': wardCode,
'is_default': isDefault,
if (cityName != null && cityName!.isNotEmpty) 'city_name': cityName,
if (wardName != null && wardName!.isNotEmpty) 'ward_name': wardName,
};
}
/// Convert to domain entity
Address toEntity() {
return Address(
name: name,
addressTitle: addressTitle,
addressLine1: addressLine1,
phone: phone,
email: email,
fax: fax,
taxCode: taxCode,
cityCode: cityCode,
wardCode: wardCode,
isDefault: isDefault,
cityName: cityName,
wardName: wardName,
);
}
/// Create from domain entity
factory AddressModel.fromEntity(Address entity) {
return AddressModel(
name: entity.name,
addressTitle: entity.addressTitle,
addressLine1: entity.addressLine1,
phone: entity.phone,
email: entity.email,
fax: entity.fax,
taxCode: entity.taxCode,
cityCode: entity.cityCode,
wardCode: entity.wardCode,
isDefault: entity.isDefault,
cityName: entity.cityName,
wardName: entity.wardName,
);
}
@override
String toString() {
return 'AddressModel(name: $name, addressTitle: $addressTitle, '
'addressLine1: $addressLine1, phone: $phone, isDefault: $isDefault)';
}
}

View File

@@ -0,0 +1,74 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'address_model.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class AddressModelAdapter extends TypeAdapter<AddressModel> {
@override
final typeId = 30;
@override
AddressModel read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return AddressModel(
name: fields[0] as String,
addressTitle: fields[1] as String,
addressLine1: fields[2] as String,
phone: fields[3] as String,
email: fields[4] as String?,
fax: fields[5] as String?,
taxCode: fields[6] as String?,
cityCode: fields[7] as String,
wardCode: fields[8] as String,
isDefault: fields[9] == null ? false : fields[9] as bool,
cityName: fields[10] as String?,
wardName: fields[11] as String?,
);
}
@override
void write(BinaryWriter writer, AddressModel obj) {
writer
..writeByte(12)
..writeByte(0)
..write(obj.name)
..writeByte(1)
..write(obj.addressTitle)
..writeByte(2)
..write(obj.addressLine1)
..writeByte(3)
..write(obj.phone)
..writeByte(4)
..write(obj.email)
..writeByte(5)
..write(obj.fax)
..writeByte(6)
..write(obj.taxCode)
..writeByte(7)
..write(obj.cityCode)
..writeByte(8)
..write(obj.wardCode)
..writeByte(9)
..write(obj.isDefault)
..writeByte(10)
..write(obj.cityName)
..writeByte(11)
..write(obj.wardName);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AddressModelAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@@ -0,0 +1,73 @@
/// City Model
///
/// Hive model for caching city/province data.
library;
import 'package:hive_ce/hive.dart';
import 'package:worker/core/constants/storage_constants.dart';
import 'package:worker/features/account/domain/entities/city.dart';
part 'city_model.g.dart';
/// City Model
///
/// Hive model for storing city/province data with offline support.
@HiveType(typeId: HiveTypeIds.cityModel)
class CityModel extends HiveObject {
/// Frappe ERPNext name/ID
@HiveField(0)
String name;
/// Display name (city_name)
@HiveField(1)
String cityName;
/// City code
@HiveField(2)
String code;
CityModel({
required this.name,
required this.cityName,
required this.code,
});
/// Create from JSON (API response)
factory CityModel.fromJson(Map<String, dynamic> json) {
return CityModel(
name: json['name'] as String? ?? '',
cityName: json['city_name'] as String? ?? '',
code: json['code'] as String? ?? '',
);
}
/// Convert to JSON (API request)
Map<String, dynamic> toJson() {
return {
'name': name,
'city_name': cityName,
'code': code,
};
}
/// Convert to domain entity
City toEntity() {
return City(
name: name,
cityName: cityName,
code: code,
);
}
/// Create from domain entity
factory CityModel.fromEntity(City entity) {
return CityModel(
name: entity.name,
cityName: entity.cityName,
code: entity.code,
);
}
@override
String toString() => 'CityModel(name: $name, cityName: $cityName, code: $code)';
}

View File

@@ -0,0 +1,47 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'city_model.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class CityModelAdapter extends TypeAdapter<CityModel> {
@override
final typeId = 31;
@override
CityModel read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return CityModel(
name: fields[0] as String,
cityName: fields[1] as String,
code: fields[2] as String,
);
}
@override
void write(BinaryWriter writer, CityModel obj) {
writer
..writeByte(3)
..writeByte(0)
..write(obj.name)
..writeByte(1)
..write(obj.cityName)
..writeByte(2)
..write(obj.code);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is CityModelAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@@ -0,0 +1,73 @@
/// Ward Model
///
/// Hive model for caching ward/district data.
library;
import 'package:hive_ce/hive.dart';
import 'package:worker/core/constants/storage_constants.dart';
import 'package:worker/features/account/domain/entities/ward.dart';
part 'ward_model.g.dart';
/// Ward Model
///
/// Hive model for storing ward/district data with offline support.
@HiveType(typeId: HiveTypeIds.wardModel)
class WardModel extends HiveObject {
/// Frappe ERPNext name/ID
@HiveField(0)
String name;
/// Display name (ward_name)
@HiveField(1)
String wardName;
/// Ward code
@HiveField(2)
String code;
WardModel({
required this.name,
required this.wardName,
required this.code,
});
/// Create from JSON (API response)
factory WardModel.fromJson(Map<String, dynamic> json) {
return WardModel(
name: json['name'] as String? ?? '',
wardName: json['ward_name'] as String? ?? '',
code: json['code'] as String? ?? '',
);
}
/// Convert to JSON (API request)
Map<String, dynamic> toJson() {
return {
'name': name,
'ward_name': wardName,
'code': code,
};
}
/// Convert to domain entity
Ward toEntity() {
return Ward(
name: name,
wardName: wardName,
code: code,
);
}
/// Create from domain entity
factory WardModel.fromEntity(Ward entity) {
return WardModel(
name: entity.name,
wardName: entity.wardName,
code: entity.code,
);
}
@override
String toString() => 'WardModel(name: $name, wardName: $wardName, code: $code)';
}

View File

@@ -0,0 +1,47 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'ward_model.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class WardModelAdapter extends TypeAdapter<WardModel> {
@override
final typeId = 32;
@override
WardModel read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return WardModel(
name: fields[0] as String,
wardName: fields[1] as String,
code: fields[2] as String,
);
}
@override
void write(BinaryWriter writer, WardModel obj) {
writer
..writeByte(3)
..writeByte(0)
..write(obj.name)
..writeByte(1)
..write(obj.wardName)
..writeByte(2)
..write(obj.code);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is WardModelAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}