refs #2645. Fixed bug schedule datetime
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
parent
1c91b97e31
commit
570af1ed2b
|
@ -8,7 +8,7 @@
|
||||||
<mat-form-field appearance="fill" class="w-full">
|
<mat-form-field appearance="fill" class="w-full">
|
||||||
<mat-label>Repetición</mat-label>
|
<mat-label>Repetición</mat-label>
|
||||||
<mat-select formControlName="recurrenceType">
|
<mat-select formControlName="recurrenceType">
|
||||||
<mat-option *ngFor="let type of recurrenceTypes" [value]="type">{{ type | titlecase }}</mat-option>
|
<mat-option *ngFor="let opt of recurrenceTypes" [value]="opt.value">{{ opt.label }}</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,10 @@ export class CreateTaskScheduleComponent implements OnInit{
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
apiUrl: 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'];
|
weekDays: string[] = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
|
||||||
isSingleDateSelected: boolean = true;
|
isSingleDateSelected: boolean = true;
|
||||||
monthsList: string[] = [
|
monthsList: string[] = [
|
||||||
|
@ -108,12 +111,27 @@ export class CreateTaskScheduleComponent implements OnInit{
|
||||||
}
|
}
|
||||||
|
|
||||||
formatExecutionTime(time: string | Date): string {
|
formatExecutionTime(time: string | Date): string {
|
||||||
const date = (time instanceof Date) ? time : new Date(time);
|
if (typeof time === 'string') {
|
||||||
if (isNaN(date.getTime())) {
|
const hhmmMatch = time.match(/^\d{2}:\d{2}/);
|
||||||
console.error('Invalid execution time:', time);
|
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 '';
|
||||||
}
|
}
|
||||||
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 {
|
convertDateToLocalISO(date: Date): string {
|
||||||
|
@ -200,31 +218,102 @@ export class CreateTaskScheduleComponent implements OnInit{
|
||||||
this.nextExecutionDate.setHours(parseInt(hours), parseInt(minutes), 0, 0);
|
this.nextExecutionDate.setHours(parseInt(hours), parseInt(minutes), 0, 0);
|
||||||
this.executionCount = 1;
|
this.executionCount = 1;
|
||||||
}
|
}
|
||||||
} else {
|
return;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private calculateExecutionCount(startDate: Date, endDate: Date, daysCount: number, monthsCount: number): number {
|
const startDateValue = this.form.get('recurrenceDetails.initDate')?.value;
|
||||||
const start = new Date(startDate);
|
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<number>(selectedDayNames.map(name => this.getDayIndexFromName(name)));
|
||||||
|
const selectedMonthIndices = new Set<number>(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 calculateExecutionCountExact(startDate: Date, endDate: Date, selectedDays: Set<number>, selectedMonths: Set<number>): number {
|
||||||
|
const cursor = new Date(startDate);
|
||||||
|
cursor.setHours(0, 0, 0, 0);
|
||||||
const end = new Date(endDate);
|
const end = new Date(endDate);
|
||||||
const daysDiff = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
|
end.setHours(23, 59, 59, 999);
|
||||||
|
|
||||||
// Aproximación: días seleccionados por semana * semanas * meses activos
|
let count = 0;
|
||||||
return Math.ceil((daysCount / 7) * (daysDiff / 7) * (monthsCount / 12));
|
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<number>, selectedMonths: Set<number>): 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 {
|
formatDate(date: string | Date): string {
|
||||||
|
|
Loading…
Reference in New Issue