mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-31 12:19:47 +02:00
Fix calendar rec events (#9755)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
@@ -161,4 +161,40 @@ describe('generateRecurringValues', () => {
|
||||
}
|
||||
expect(() => generateRecurringValues(rule as any, baseDate, from, to)).toThrow('Invalid recurring rule frequency')
|
||||
})
|
||||
|
||||
it('generates simple monthly recurring values (no specific rules)', () => {
|
||||
const rule: RecurringRule = {
|
||||
freq: 'MONTHLY',
|
||||
interval: 1
|
||||
}
|
||||
const startDate = new Date('2024-01-15T10:00:00Z').getTime() // 15th of month
|
||||
const from = new Date('2024-01-01T00:00:00Z').getTime()
|
||||
const to = new Date('2024-04-30T23:59:59Z').getTime()
|
||||
const result = generateRecurringValues(rule, startDate, from, to)
|
||||
|
||||
// Should generate events on 15th of each month: Jan, Feb, Mar, Apr
|
||||
expect(result.length).toBe(4)
|
||||
expect(new Date(result[0]).toISOString().slice(0, 10)).toBe('2024-01-15')
|
||||
expect(new Date(result[1]).toISOString().slice(0, 10)).toBe('2024-02-15')
|
||||
expect(new Date(result[2]).toISOString().slice(0, 10)).toBe('2024-03-15')
|
||||
expect(new Date(result[3]).toISOString().slice(0, 10)).toBe('2024-04-15')
|
||||
})
|
||||
|
||||
it('generates simple yearly recurring values (no specific rules)', () => {
|
||||
const rule: RecurringRule = {
|
||||
freq: 'YEARLY',
|
||||
interval: 1
|
||||
}
|
||||
const startDate = new Date('2024-03-10T10:00:00Z').getTime() // March 10th
|
||||
const from = new Date('2024-01-01T00:00:00Z').getTime()
|
||||
const to = new Date('2027-12-31T23:59:59Z').getTime()
|
||||
const result = generateRecurringValues(rule, startDate, from, to)
|
||||
|
||||
// Should generate events on March 10th of each year: 2024, 2025, 2026, 2027
|
||||
expect(result.length).toBe(4)
|
||||
expect(new Date(result[0]).toISOString().slice(0, 10)).toBe('2024-03-10')
|
||||
expect(new Date(result[1]).toISOString().slice(0, 10)).toBe('2025-03-10')
|
||||
expect(new Date(result[2]).toISOString().slice(0, 10)).toBe('2026-03-10')
|
||||
expect(new Date(result[3]).toISOString().slice(0, 10)).toBe('2027-03-10')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -154,11 +154,37 @@ function generateMonthlyValues (rule: RecurringRule, currentDate: Date, from: Ti
|
||||
const end = new Date(new Date(currentDate).setMonth(currentDate.getMonth() + 1, 1))
|
||||
let date = currentDate
|
||||
const candidates: Date[] = []
|
||||
while (date < end) {
|
||||
if ((byDay == null || matchesByDay(date, byDay)) && (byMonthDay == null || byMonthDay.includes(date.getDate()))) {
|
||||
candidates.push(new Date(date))
|
||||
|
||||
// If no specific rules are set except byMonthDay (simple monthly recurrence)
|
||||
if (byDay == null && bySetPos == null && byMonthDay != null) {
|
||||
for (const day of byMonthDay) {
|
||||
const originalDate = new Date(currentDate.getTime())
|
||||
const sameDate = new Date(
|
||||
Date.UTC(
|
||||
currentDate.getUTCFullYear(),
|
||||
currentDate.getUTCMonth(),
|
||||
day,
|
||||
originalDate.getUTCHours(),
|
||||
originalDate.getUTCMinutes(),
|
||||
originalDate.getUTCSeconds(),
|
||||
originalDate.getUTCMilliseconds()
|
||||
)
|
||||
)
|
||||
if (sameDate.getUTCMonth() === currentDate.getUTCMonth()) {
|
||||
// Valid day for this month
|
||||
candidates.push(sameDate)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (date < end) {
|
||||
if (
|
||||
(byDay == null || matchesByDay(date, byDay)) &&
|
||||
(byMonthDay == null || byMonthDay.includes(date.getDate()))
|
||||
) {
|
||||
candidates.push(new Date(date))
|
||||
}
|
||||
date = new Date(date.setDate(date.getDate() + 1))
|
||||
}
|
||||
date = new Date(date.setDate(date.getDate() + 1))
|
||||
}
|
||||
|
||||
let filtered: Date[] = candidates
|
||||
@@ -197,21 +223,46 @@ function generateYearlyValues (rule: RecurringRule, currentDate: Date, from: Tim
|
||||
const end = new Date(new Date(currentDate).setFullYear(currentDate.getFullYear() + 1, 0, 1))
|
||||
let date = currentDate
|
||||
const candidates: Date[] = []
|
||||
while (date < end) {
|
||||
if (
|
||||
(byDay == null || matchesByDay(date, byDay)) &&
|
||||
(byMonthDay == null || byMonthDay.includes(date.getDate())) &&
|
||||
(byYearDay == null || byYearDay.includes(getYearDay(date))) &&
|
||||
(byWeekNo == null || byWeekNo.includes(getWeekNumber(date))) &&
|
||||
(byMonth == null || byMonth.includes(date.getMonth()))
|
||||
) {
|
||||
const res = date.getTime()
|
||||
if (res >= from && res <= to) {
|
||||
candidates.push(new Date(res))
|
||||
|
||||
// If no specific rules are set, only generate an event for the same month/day each year
|
||||
if (
|
||||
byDay == null &&
|
||||
byMonthDay == null &&
|
||||
byYearDay == null &&
|
||||
byWeekNo == null &&
|
||||
byMonth == null &&
|
||||
bySetPos == null
|
||||
) {
|
||||
const originalDate = new Date(currentDate.getTime())
|
||||
const sameDate = new Date(
|
||||
Date.UTC(
|
||||
currentDate.getUTCFullYear(),
|
||||
originalDate.getUTCMonth(),
|
||||
originalDate.getUTCDate(),
|
||||
originalDate.getUTCHours(),
|
||||
originalDate.getUTCMinutes(),
|
||||
originalDate.getUTCSeconds(),
|
||||
originalDate.getUTCMilliseconds()
|
||||
)
|
||||
)
|
||||
candidates.push(sameDate)
|
||||
} else {
|
||||
while (date < end) {
|
||||
if (
|
||||
(byDay == null || matchesByDay(date, byDay)) &&
|
||||
(byMonthDay == null || byMonthDay.includes(date.getDate())) &&
|
||||
(byYearDay == null || byYearDay.includes(getYearDay(date))) &&
|
||||
(byWeekNo == null || byWeekNo.includes(getWeekNumber(date))) &&
|
||||
(byMonth == null || byMonth.includes(date.getMonth()))
|
||||
) {
|
||||
const res = date.getTime()
|
||||
if (res >= from && res <= to) {
|
||||
candidates.push(new Date(res))
|
||||
}
|
||||
i++
|
||||
}
|
||||
i++
|
||||
date = new Date(date.setDate(date.getDate() + 1))
|
||||
}
|
||||
date = new Date(date.setDate(date.getDate() + 1))
|
||||
}
|
||||
|
||||
let filtered: Date[] = candidates
|
||||
@@ -235,7 +286,7 @@ function generateYearlyValues (rule: RecurringRule, currentDate: Date, from: Tim
|
||||
}
|
||||
if (endDate != null && next > endDate) return values
|
||||
if (next >= to) return values
|
||||
currentDate = new Date(next)
|
||||
currentDate = new Date(currentDate.setFullYear(currentDate.getFullYear() + (interval ?? 1)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user