diff --git a/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.html b/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.html
index 186ff83..ac8f63f 100644
--- a/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.html
+++ b/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.html
@@ -8,7 +8,7 @@
Repetición
- {{ type | titlecase }}
+ {{ opt.label }}
diff --git a/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.ts b/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.ts
index 5822467..afdedf8 100644
--- a/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.ts
+++ b/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.ts
@@ -14,7 +14,10 @@ export class CreateTaskScheduleComponent implements OnInit{
form: FormGroup;
baseUrl: string;
apiUrl: string;
- recurrenceTypes = ['none', 'custom'];
+ recurrenceTypes = [
+ { value: 'none', label: 'Sin repetición' },
+ { value: 'custom', label: 'Repetición personalizada' }
+ ];
weekDays: string[] = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
isSingleDateSelected: boolean = true;
monthsList: string[] = [
@@ -108,12 +111,27 @@ export class CreateTaskScheduleComponent implements OnInit{
}
formatExecutionTime(time: string | Date): string {
- const date = (time instanceof Date) ? time : new Date(time);
- if (isNaN(date.getTime())) {
- console.error('Invalid execution time:', time);
+ if (typeof time === 'string') {
+ const hhmmMatch = time.match(/^\d{2}:\d{2}/);
+ if (hhmmMatch) {
+ return hhmmMatch[0];
+ }
+ const parsed = new Date(time);
+ if (!isNaN(parsed.getTime())) {
+ const hours = String(parsed.getHours()).padStart(2, '0');
+ const minutes = String(parsed.getMinutes()).padStart(2, '0');
+ return `${hours}:${minutes}`;
+ }
return '';
}
- return date.toISOString().substring(11, 16);
+
+ if (time instanceof Date && !isNaN(time.getTime())) {
+ const hours = String(time.getHours()).padStart(2, '0');
+ const minutes = String(time.getMinutes()).padStart(2, '0');
+ return `${hours}:${minutes}`;
+ }
+
+ return '';
}
convertDateToLocalISO(date: Date): string {
@@ -191,7 +209,7 @@ export class CreateTaskScheduleComponent implements OnInit{
private calculateNextExecutionAndCount(): void {
const recurrence = this.form.get('recurrenceType')?.value;
const time = this.form.get('executionTime')?.value;
-
+
if (recurrence === 'none') {
const execDate = this.form.get('executionDate')?.value;
if (execDate && time) {
@@ -200,31 +218,102 @@ export class CreateTaskScheduleComponent implements OnInit{
this.nextExecutionDate.setHours(parseInt(hours), parseInt(minutes), 0, 0);
this.executionCount = 1;
}
- } else {
- const startDate = this.form.get('recurrenceDetails.initDate')?.value;
- const endDate = this.form.get('recurrenceDetails.endDate')?.value;
- const days = Object.keys(this.selectedDays).filter(day => this.selectedDays[day]);
- const months = Object.keys(this.selectedMonths).filter(month => this.selectedMonths[month]);
-
- if (startDate && endDate && days.length > 0 && months.length > 0) {
- // Calcular próxima ejecución (simplificado)
- this.nextExecutionDate = new Date(startDate);
- const [hours, minutes] = time.split(':');
- this.nextExecutionDate.setHours(parseInt(hours), parseInt(minutes), 0, 0);
-
- // Calcular número aproximado de ejecuciones
- this.executionCount = this.calculateExecutionCount(startDate, endDate, days.length, months.length);
- }
+ return;
}
+
+ const startDateValue = this.form.get('recurrenceDetails.initDate')?.value;
+ const endDateValue = this.form.get('recurrenceDetails.endDate')?.value;
+
+ const selectedDayNames = Object.keys(this.selectedDays).filter(day => this.selectedDays[day]);
+ const selectedMonthNames = Object.keys(this.selectedMonths).filter(month => this.selectedMonths[month]);
+
+ if (!startDateValue || !endDateValue || selectedDayNames.length === 0 || selectedMonthNames.length === 0) {
+ this.nextExecutionDate = null;
+ this.executionCount = 0;
+ return;
+ }
+
+ const startDate = new Date(startDateValue);
+ const endDate = new Date(endDateValue);
+
+ const selectedDayIndices = new Set(selectedDayNames.map(name => this.getDayIndexFromName(name)));
+ const selectedMonthIndices = new Set(selectedMonthNames.map(name => this.getMonthIndexFromName(name)));
+
+ // Conteo exacto de ejecuciones en el rango [startDate, endDate]
+ this.executionCount = this.calculateExecutionCountExact(startDate, endDate, selectedDayIndices, selectedMonthIndices);
+
+ // Próxima ejecución >= ahora dentro del rango y criterios
+ this.nextExecutionDate = this.findNextExecutionDate(startDate, endDate, time, selectedDayIndices, selectedMonthIndices);
}
- private calculateExecutionCount(startDate: Date, endDate: Date, daysCount: number, monthsCount: number): number {
- const start = new Date(startDate);
+ private calculateExecutionCountExact(startDate: Date, endDate: Date, selectedDays: Set, selectedMonths: Set): number {
+ const cursor = new Date(startDate);
+ cursor.setHours(0, 0, 0, 0);
const end = new Date(endDate);
- const daysDiff = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
-
- // Aproximación: días seleccionados por semana * semanas * meses activos
- return Math.ceil((daysCount / 7) * (daysDiff / 7) * (monthsCount / 12));
+ end.setHours(23, 59, 59, 999);
+
+ let count = 0;
+ while (cursor <= end) {
+ if (selectedMonths.has(cursor.getMonth()) && selectedDays.has(cursor.getDay())) {
+ count += 1;
+ }
+ cursor.setDate(cursor.getDate() + 1);
+ }
+ return count;
+ }
+
+ private findNextExecutionDate(startDate: Date, endDate: Date, time: string, selectedDays: Set, selectedMonths: Set): Date | null {
+ const now = new Date();
+
+ const startCandidate = new Date(Math.max(new Date(startDate).setHours(0, 0, 0, 0), new Date(now).setHours(0, 0, 0, 0)));
+ const endLimit = new Date(endDate);
+ endLimit.setHours(23, 59, 59, 999);
+
+ const [hours, minutes] = (time || '00:00').split(':');
+
+ const candidate = new Date(startCandidate);
+ while (candidate <= endLimit) {
+ if (selectedMonths.has(candidate.getMonth()) && selectedDays.has(candidate.getDay())) {
+ const candidateDateTime = new Date(candidate);
+ candidateDateTime.setHours(parseInt(hours), parseInt(minutes), 0, 0);
+ if (candidateDateTime >= now) {
+ return candidateDateTime;
+ }
+ }
+ candidate.setDate(candidate.getDate() + 1);
+ }
+ return null;
+ }
+
+ private getDayIndexFromName(dayName: string): number {
+ const mapping: { [key: string]: number } = {
+ sunday: 0,
+ monday: 1,
+ tuesday: 2,
+ wednesday: 3,
+ thursday: 4,
+ friday: 5,
+ saturday: 6
+ };
+ return mapping[dayName.toLowerCase()] ?? -1;
+ }
+
+ private getMonthIndexFromName(monthName: string): number {
+ const mapping: { [key: string]: number } = {
+ january: 0,
+ february: 1,
+ march: 2,
+ april: 3,
+ may: 4,
+ june: 5,
+ july: 6,
+ august: 7,
+ september: 8,
+ october: 9,
+ november: 10,
+ december: 11
+ };
+ return mapping[monthName.toLowerCase()] ?? -1;
}
formatDate(date: string | Date): string {