feat(alarm): add musical alarm foundation
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import '../modelos/alarma_musical.dart';
|
||||
|
||||
class ServicioProgramacionAlarmas {
|
||||
DateTime? calcularProxima({
|
||||
required AlarmaMusical alarma,
|
||||
required DateTime desde,
|
||||
List<RangoVacaciones> vacaciones = const [],
|
||||
List<ExcepcionAlarma> excepciones = const [],
|
||||
}) {
|
||||
if (!alarma.activa) return null;
|
||||
|
||||
final inicio = DateTime(
|
||||
desde.year,
|
||||
desde.month,
|
||||
desde.day,
|
||||
alarma.hora,
|
||||
alarma.minuto,
|
||||
);
|
||||
final primerCandidato =
|
||||
inicio.isAfter(desde) ? inicio : inicio.add(const Duration(days: 1));
|
||||
|
||||
return switch (alarma.tipoProgramacion) {
|
||||
TipoProgramacionAlarma.unica =>
|
||||
_esValida(alarma, primerCandidato, vacaciones, excepciones)
|
||||
? primerCandidato
|
||||
: null,
|
||||
TipoProgramacionAlarma.diaria => _buscarDiaria(
|
||||
alarma,
|
||||
primerCandidato,
|
||||
vacaciones,
|
||||
excepciones,
|
||||
),
|
||||
TipoProgramacionAlarma.diasSemana => _buscarPorDiasSemana(
|
||||
alarma,
|
||||
primerCandidato,
|
||||
vacaciones,
|
||||
excepciones,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
DateTime calcularSnooze(DateTime desde, int minutos) {
|
||||
final seguro = minutos == 3 || minutos == 5 || minutos == 10 ? minutos : 5;
|
||||
return desde.add(Duration(minutes: seguro));
|
||||
}
|
||||
|
||||
bool estaEnVacaciones(DateTime fecha, List<RangoVacaciones> vacaciones) =>
|
||||
vacaciones.any((rango) => rango.contiene(fecha));
|
||||
|
||||
DateTime? _buscarDiaria(
|
||||
AlarmaMusical alarma,
|
||||
DateTime candidato,
|
||||
List<RangoVacaciones> vacaciones,
|
||||
List<ExcepcionAlarma> excepciones,
|
||||
) {
|
||||
var actual = candidato;
|
||||
for (var i = 0; i < 370; i++) {
|
||||
if (_esValida(alarma, actual, vacaciones, excepciones)) return actual;
|
||||
actual = actual.add(const Duration(days: 1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
DateTime? _buscarPorDiasSemana(
|
||||
AlarmaMusical alarma,
|
||||
DateTime candidato,
|
||||
List<RangoVacaciones> vacaciones,
|
||||
List<ExcepcionAlarma> excepciones,
|
||||
) {
|
||||
if (alarma.diasSemana.isEmpty) return null;
|
||||
var actual = candidato;
|
||||
for (var i = 0; i < 370; i++) {
|
||||
if (alarma.diasSemana.contains(actual.weekday) &&
|
||||
_esValida(alarma, actual, vacaciones, excepciones)) {
|
||||
return actual;
|
||||
}
|
||||
actual = actual.add(const Duration(days: 1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool _esValida(
|
||||
AlarmaMusical alarma,
|
||||
DateTime candidato,
|
||||
List<RangoVacaciones> vacaciones,
|
||||
List<ExcepcionAlarma> excepciones,
|
||||
) {
|
||||
if (!alarma.sonarEnVacaciones && estaEnVacaciones(candidato, vacaciones)) {
|
||||
return false;
|
||||
}
|
||||
return !excepciones.any(
|
||||
(excepcion) =>
|
||||
excepcion.alarmaId == alarma.id &&
|
||||
_mismaEjecucion(excepcion.ejecucion, candidato),
|
||||
);
|
||||
}
|
||||
|
||||
bool _mismaEjecucion(DateTime a, DateTime b) =>
|
||||
a.year == b.year &&
|
||||
a.month == b.month &&
|
||||
a.day == b.day &&
|
||||
a.hour == b.hour &&
|
||||
a.minute == b.minute;
|
||||
}
|
||||
Reference in New Issue
Block a user