141 lines
4.3 KiB
Dart
141 lines
4.3 KiB
Dart
import 'package:equatable/equatable.dart';
|
|
|
|
import 'package:uto_manager/domain/entities/authorized_rank.dart';
|
|
import 'package:uto_manager/domain/value_objects/duty_mos.dart';
|
|
|
|
/// Represents the readiness state of a soldier.
|
|
enum ReadinessState {
|
|
/// Fully mission-capable; no limiting factors.
|
|
fullyMissionCapable,
|
|
|
|
/// Partially mission-capable; some limiting factors present.
|
|
partiallyMissionCapable,
|
|
|
|
/// Not mission-capable; significant limiting factors.
|
|
notMissionCapable,
|
|
|
|
/// Status unknown or not yet assessed.
|
|
unknown;
|
|
|
|
/// Returns a human-readable display name.
|
|
String get displayName {
|
|
switch (this) {
|
|
case ReadinessState.fullyMissionCapable:
|
|
return 'FMC';
|
|
case ReadinessState.partiallyMissionCapable:
|
|
return 'PMC';
|
|
case ReadinessState.notMissionCapable:
|
|
return 'NMC';
|
|
case ReadinessState.unknown:
|
|
return 'Unknown';
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Represents a soldier's personnel record in the UTO system.
|
|
///
|
|
/// Contains identifying information, MOS qualifications, pay grade,
|
|
/// and current readiness state.
|
|
///
|
|
/// [name] is optional. When omitted the soldier is identified by
|
|
/// [positionTitle] (e.g. "Team Leader", "Rifleman").
|
|
class PersonnelRecord extends Equatable {
|
|
const PersonnelRecord({
|
|
required this.soldierId,
|
|
required this.primaryMos,
|
|
required this.payGrade,
|
|
required this.readinessState,
|
|
this.name,
|
|
this.positionTitle,
|
|
this.qualifications = const [],
|
|
this.assignedSlotId,
|
|
});
|
|
|
|
/// Unique identifier for this soldier (UUID v4).
|
|
final String soldierId;
|
|
|
|
/// The soldier's full name (Last, First MI format), or null if unnamed.
|
|
final String? name;
|
|
|
|
/// The soldier's duty position title (e.g. "Team Leader", "Rifleman").
|
|
///
|
|
/// Used as the display label when [name] is null.
|
|
final String? positionTitle;
|
|
|
|
/// The soldier's primary Military Occupational Specialty.
|
|
final DutyMos primaryMos;
|
|
|
|
/// The soldier's current pay grade.
|
|
final AuthorizedRank payGrade;
|
|
|
|
/// Additional MOS qualifications and special skills.
|
|
final List<String> qualifications;
|
|
|
|
/// The current readiness state of this soldier.
|
|
final ReadinessState readinessState;
|
|
|
|
/// The ID of the position slot this soldier is assigned to, or null.
|
|
final String? assignedSlotId;
|
|
|
|
/// Returns the best available display label for this soldier.
|
|
///
|
|
/// Prefers [name]; falls back to [positionTitle]; then a generic label.
|
|
String get displayLabel {
|
|
if (name != null && name!.isNotEmpty) return name!;
|
|
if (positionTitle != null && positionTitle!.isNotEmpty) return positionTitle!;
|
|
return '(Unnamed Soldier)';
|
|
}
|
|
|
|
/// Returns true if this soldier is currently assigned to a position.
|
|
bool get isAssigned => assignedSlotId != null;
|
|
|
|
/// Returns true if this soldier is available for assignment.
|
|
bool get isUnassigned => assignedSlotId == null;
|
|
|
|
/// Returns true if this soldier is fully mission capable.
|
|
bool get isFmc => readinessState == ReadinessState.fullyMissionCapable;
|
|
|
|
/// Returns a copy of this [PersonnelRecord] with the given fields replaced.
|
|
PersonnelRecord copyWith({
|
|
String? soldierId,
|
|
String? name,
|
|
bool clearName = false,
|
|
String? positionTitle,
|
|
bool clearPositionTitle = false,
|
|
DutyMos? primaryMos,
|
|
AuthorizedRank? payGrade,
|
|
List<String>? qualifications,
|
|
ReadinessState? readinessState,
|
|
String? assignedSlotId,
|
|
bool clearAssignment = false,
|
|
}) {
|
|
return PersonnelRecord(
|
|
soldierId: soldierId ?? this.soldierId,
|
|
name: clearName ? null : (name ?? this.name),
|
|
positionTitle: clearPositionTitle ? null : (positionTitle ?? this.positionTitle),
|
|
primaryMos: primaryMos ?? this.primaryMos,
|
|
payGrade: payGrade ?? this.payGrade,
|
|
qualifications: qualifications ?? this.qualifications,
|
|
readinessState: readinessState ?? this.readinessState,
|
|
assignedSlotId: clearAssignment ? null : (assignedSlotId ?? this.assignedSlotId),
|
|
);
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
soldierId,
|
|
name,
|
|
positionTitle,
|
|
primaryMos,
|
|
payGrade,
|
|
qualifications,
|
|
readinessState,
|
|
assignedSlotId,
|
|
];
|
|
|
|
@override
|
|
String toString() => 'PersonnelRecord(id: $soldierId, label: $displayLabel, '
|
|
'mos: ${primaryMos.code}, grade: ${payGrade.payGrade}, '
|
|
'readiness: ${readinessState.displayName})';
|
|
}
|