Files
ignis_app/lib/features/schedules/schedule_form_logic.dart
2026-05-01 09:47:08 +07:00

148 lines
3.8 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class ScheduleWeekdayOption {
final int backendValue;
final String shortLabel;
final String fullLabel;
const ScheduleWeekdayOption({
required this.backendValue,
required this.shortLabel,
required this.fullLabel,
});
}
const scheduleWeekdayOptions = <ScheduleWeekdayOption>[
ScheduleWeekdayOption(
backendValue: 1,
shortLabel: 'Пн',
fullLabel: 'понедельник',
),
ScheduleWeekdayOption(
backendValue: 2,
shortLabel: 'Вт',
fullLabel: 'вторник',
),
ScheduleWeekdayOption(backendValue: 3, shortLabel: 'Ср', fullLabel: 'среда'),
ScheduleWeekdayOption(
backendValue: 4,
shortLabel: 'Чт',
fullLabel: 'четверг',
),
ScheduleWeekdayOption(
backendValue: 5,
shortLabel: 'Пт',
fullLabel: 'пятница',
),
ScheduleWeekdayOption(
backendValue: 6,
shortLabel: 'Сб',
fullLabel: 'суббота',
),
ScheduleWeekdayOption(
backendValue: 0,
shortLabel: 'Вс',
fullLabel: 'воскресенье',
),
];
DateTime defaultOnceScheduleTime({DateTime? now}) {
final base = now ?? DateTime.now();
final candidate = base.add(const Duration(hours: 4));
final roundedMinute = ((candidate.minute + 4) ~/ 5) * 5;
final normalized = DateTime(
candidate.year,
candidate.month,
candidate.day,
candidate.hour,
roundedMinute,
);
return normalized.isAfter(base)
? normalized
: normalized.add(const Duration(minutes: 5));
}
String? validateOnceSchedule(DateTime? scheduledAt, {DateTime? now}) {
if (scheduledAt == null) {
return 'Выберите дату и время';
}
final threshold = (now ?? DateTime.now()).add(const Duration(minutes: 1));
if (!scheduledAt.isAfter(threshold)) {
return 'Нужна дата хотя бы на минуту вперёд';
}
return null;
}
String? validateCronSchedule({
required int? hour,
required int? minute,
required Set<int> weekdays,
}) {
if (hour == null || hour < 0 || hour > 23) {
return 'Час должен быть от 0 до 23';
}
if (minute == null || minute < 0 || minute > 59) {
return 'Минута должна быть от 0 до 59';
}
if (weekdays.isEmpty) {
return 'Выберите хотя бы один день недели';
}
return null;
}
String serializeCronWeekdays(Set<int> weekdays) {
if (weekdays.length == scheduleWeekdayOptions.length) {
return '*';
}
final sorted = weekdays.toList()..sort();
return sorted.join(',');
}
String describeCronWeekdays(Set<int> weekdays) {
if (weekdays.isEmpty) {
return 'дни не выбраны';
}
if (weekdays.length == scheduleWeekdayOptions.length) {
return 'каждый день';
}
final weekdaySet = weekdays.toSet();
final selected = scheduleWeekdayOptions
.where((option) => weekdaySet.contains(option.backendValue))
.map((option) => option.shortLabel)
.toList();
return selected.join(', ');
}
String describeCronWeekdaysExpression(String? value) {
if (value == null || value.isEmpty || value == '*') {
return 'каждый день';
}
final weekdays = value
.split(',')
.map((item) => int.tryParse(item.trim()))
.whereType<int>()
.toSet();
if (weekdays.isEmpty) {
return value;
}
return describeCronWeekdays(weekdays);
}
String formatLocalScheduleDateTime(DateTime value) {
String pad(int number) => number.toString().padLeft(2, '0');
return '${pad(value.day)}.${pad(value.month)}.${value.year} ${pad(value.hour)}:${pad(value.minute)}';
}
String formatRunAtLabel(String? value) {
if (value == null || value.isEmpty) {
return 'время не указано';
}
final parsed = DateTime.tryParse(value);
if (parsed == null) {
return value;
}
return formatLocalScheduleDateTime(parsed.toLocal());
}