class MemberComment { final int id; final String comment; final String createdAt; const MemberComment({ required this.id, required this.comment, required this.createdAt, }); factory MemberComment.fromJson(Map json) => MemberComment( id: json['id'] ?? 0, comment: json['comment'] ?? '', createdAt: json['created_at'] ?? '', ); } class Person { final int memberId; final int family; final String firstName; final String lastName; final String dni; final String birthDate; final String phone; final String email; final bool lopd; final bool newsletter; final bool? bHealth; final bool authorized; final bool authorized2; final String? photoPath; const Person({ required this.memberId, required this.family, required this.firstName, required this.lastName, required this.dni, required this.birthDate, required this.phone, required this.email, required this.lopd, required this.newsletter, this.bHealth, required this.authorized, required this.authorized2, this.photoPath, }); factory Person.fromJson(Map json) => Person( memberId: json['fk_i_member_id'] ?? 0, family: json['i_family'] ?? 0, firstName: json['s_first_name'] ?? '', lastName: json['s_last_name'] ?? '', dni: json['s_dni'] ?? '', birthDate: json['d_birth_date'] ?? '', phone: json['s_phone'] ?? '', email: json['s_email'] ?? '', lopd: (json['b_lopd'] ?? 0) == 1, newsletter: (json['b_newsletter'] ?? 0) == 1, bHealth: json['b_health'] != null ? (json['b_health'] as int) == 1 : null, authorized: (json['b_authorized'] ?? 0) == 1, authorized2: (json['b_authorized2'] ?? 0) == 1, photoPath: json['s_photo_path'], ); String get fullName => '$firstName $lastName'.trim(); String get initials { final parts = fullName.split(' '); if (parts.length >= 2) return '${parts[0][0]}${parts[1][0]}'.toUpperCase(); if (parts.isNotEmpty && parts[0].isNotEmpty) return parts[0][0].toUpperCase(); return '?'; } } class Member { final int id; final String regDate; final String address; final String city; final String zip; final String email; final String phone; final String bank; final String bankOffice; final String bankSecCode; final String bankAccount; final String bankName; final String mandate; final String type; final String comment; final String comment2; final bool paid; final bool remSpecial; final bool retenido; final String? unregDate; final String unregReason; final double? fee; final List people; final List comments; final Map> monthlyFees; const Member({ required this.id, required this.regDate, required this.address, required this.city, required this.zip, required this.email, required this.phone, required this.bank, required this.bankOffice, required this.bankSecCode, required this.bankAccount, required this.bankName, required this.mandate, required this.type, required this.comment, required this.comment2, required this.paid, required this.remSpecial, required this.retenido, required this.unregDate, required this.unregReason, this.fee, required this.people, required this.comments, required this.monthlyFees, }); factory Member.fromJson(Map json) => Member( id: json['pk_i_id'] ?? 0, regDate: json['d_reg_date'] ?? '', address: json['s_address'] ?? '', city: json['s_city'] ?? '', zip: json['s_zip'] ?? '', email: json['s_email'] ?? '', phone: json['s_phone'] ?? '', bank: json['s_bank'] ?? '', bankOffice: json['s_bank_office'] ?? '', bankSecCode: json['s_bank_sec_code'] ?? '', bankAccount: json['s_bank_account'] ?? '', bankName: json['s_bank_name'] ?? '', mandate: json['s_mandate'] ?? '', type: json['s_type'] ?? '', comment: json['s_comment'] ?? '', comment2: json['s_comment2'] ?? '', paid: (json['b_paid'] ?? 0) == 1, remSpecial: (json['b_rem_special'] ?? 0) == 1, retenido: (json['b_retenido'] ?? 0) == 1, unregDate: json['d_unreg_date'], unregReason: json['s_unreg_reason'] ?? '', fee: (json['f_fee'] as num?)?.toDouble(), people: (json['people'] as List? ?? []) .map((p) => Person.fromJson(p as Map)) .toList(), comments: (json['comments'] as List? ?? []) .map((c) => MemberComment.fromJson(c as Map)) .toList(), monthlyFees: (json['monthly_fees'] as Map? ?? {}).map( (year, months) => MapEntry( int.parse(year), (months as List).map((v) => (v as num).toInt()).toList(), ), ), ); String get formattedId => id.toString().padLeft(5, '0'); bool get isActive => unregDate == null; }