diff --git a/src/app/bank-calendar/bank-calendar.component.html b/src/app/bank-calendar/bank-calendar.component.html index b7f912e0f..d4996f7fa 100644 --- a/src/app/bank-calendar/bank-calendar.component.html +++ b/src/app/bank-calendar/bank-calendar.component.html @@ -44,8 +44,11 @@
-
{{ overallStats.sat2nd4th }}
-
2nd & 4th Sat
+
{{ overallStats.sat2nd4th + overallStats.weeklyOff }}
+
+ {{ saturdayIsWorkingDay ? '2nd & 4th Sat' : 'Saturdays' + }}{{ overallStats.weeklyOff > 0 ? ' / Weekly Off' : '' }} +
@@ -69,7 +72,11 @@
Working Day
Sunday
-
2nd / 4th Saturday
+
+ + {{ saturdayIsWorkingDay ? '2nd / 4th Saturday' : 'Saturday' + }}{{ overallStats.weeklyOff > 0 ? ' / Weekly Off' : '' }} +
Holiday
Today
@@ -319,7 +326,9 @@ [class.cal-grid__day--other]="!day.isCurrentMonth" [class.cal-grid__day--today]="day.isToday" [class.cal-grid__day--sunday]="day.isSunday && day.isCurrentMonth" - [class.cal-grid__day--sat2nd4th]="(day.is2ndSaturday || day.is4thSaturday) && day.isCurrentMonth" + [class.cal-grid__day--sat2nd4th]=" + (day.is2ndSaturday || day.is4thSaturday || day.isWeeklyOff) && day.isCurrentMonth + " [class.cal-grid__day--holiday]="day.isHoliday && day.isCurrentMonth" [class.cal-grid__day--working]="day.isWorking && day.isCurrentMonth" [matTooltip]=" @@ -328,9 +337,11 @@ ? '2nd Saturday Off' : day.is4thSaturday ? '4th Saturday Off' - : day.isSunday && day.isCurrentMonth - ? 'Sunday' - : '') + : day.isWeeklyOff && day.isCurrentMonth + ? weekDays[day.dayOfWeek] + ' Off (Working Days)' + : day.isSunday && day.isCurrentMonth + ? 'Sunday' + : '') " > {{ day.isCurrentMonth ? day.date : '' }} @@ -343,10 +354,15 @@ @if (month.holidays > 0) { {{ month.holidays }} Holiday{{ month.holidays > 1 ? 's' : '' }} } - {{ month.sundays }} Sun + @if (month.sundays > 0) { + {{ month.sundays }} Sun + } @if (month.secondFourthSat > 0) { {{ month.secondFourthSat }} Sat Off } + @if (month.weeklyOff > 0) { + {{ month.weeklyOff }} Weekly Off + }
} diff --git a/src/app/bank-calendar/bank-calendar.component.ts b/src/app/bank-calendar/bank-calendar.component.ts index bfcacb185..9102f10d6 100644 --- a/src/app/bank-calendar/bank-calendar.component.ts +++ b/src/app/bank-calendar/bank-calendar.component.ts @@ -63,6 +63,8 @@ interface CalendarDay { isSunday: boolean; is2ndSaturday: boolean; is4thSaturday: boolean; + /** Off every week because Admin > Working Days leaves this weekday out (Sunday aside). */ + isWeeklyOff: boolean; holidayName?: string; dayOfWeek: number; // 0=Sun, 6=Sat } @@ -76,9 +78,23 @@ interface MonthData { nonWorkingDays: number; holidays: number; sundays: number; + /** Saturdays off: the 2nd and 4th when Saturday is a working day, every one when it is not. */ secondFourthSat: number; + /** Other weekdays off every week because Working Days leaves them out. */ + weeklyOff: number; } +/** Weekday codes in Date#getDay() order, as used by the /workingdays recurrence (BYDAY=MO,TU,...). */ +const DAY_CODES = [ + 'SU', + 'MO', + 'TU', + 'WE', + 'TH', + 'FR', + 'SA' +]; + @Component({ selector: 'mifosx-bank-calendar', templateUrl: './bank-calendar.component.html', @@ -118,7 +134,7 @@ export class BankCalendarComponent implements OnInit { ]; workingDaysConfig: string[] = []; holidays: any[] = []; - overallStats = { working: 0, nonWorking: 0, holidays: 0, sundays: 0, sat2nd4th: 0, totalDays: 0 }; + overallStats = { working: 0, nonWorking: 0, holidays: 0, sundays: 0, sat2nd4th: 0, weeklyOff: 0, totalDays: 0 }; // ───── Holiday list (office-wise) ───── offices: OfficeLite[] = []; @@ -202,7 +218,8 @@ export class BankCalendarComponent implements OnInit { } private loadWorkingDays() { - // Default Indian banking working days: Mon-Sat (Sun off, 2nd & 4th Sat off) + // Default Indian banking working days: Mon-Sat (Sun off, 2nd & 4th Sat off), used until + // Admin > Working Days answers, or if it cannot be read. this.workingDaysConfig = [ 'MO', 'TU', @@ -215,6 +232,19 @@ export class BankCalendarComponent implements OnInit { this.buildCalendar(); this.rebuildHolidayRows(); + // The calendar has to agree with Admin > Working Days: a weekday unticked there is off every + // week here too. + this.organizationService.getWorkingDays().subscribe({ + next: (data: any) => { + const configured = this.parseWorkingDays(data?.recurrence); + if (configured.length > 0) { + this.workingDaysConfig = configured; + this.buildCalendar(); + } + }, + error: () => {} + }); + // Pull offices then fan-out a per-office holiday fetch so each office's // calendar entries are surfaced in the list panel (calendar grid still // unions everything for the year-at-a-glance view). @@ -273,6 +303,23 @@ export class BankCalendarComponent implements OnInit { }); } + /** Weekday codes out of a recurrence such as "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR". */ + private parseWorkingDays(recurrence: string | undefined): string[] { + const byDay = /BYDAY=([^;]*)/.exec(recurrence || ''); + if (!byDay) { + return []; + } + return byDay[1] + .split(',') + .map((d) => d.trim().toUpperCase()) + .filter((d) => DAY_CODES.includes(d)); + } + + /** True when Admin > Working Days counts Saturday as a working day (so only the 2nd and 4th are off). */ + get saturdayIsWorkingDay(): boolean { + return this.workingDaysConfig.includes('SA'); + } + /** Flatten the holidays array into a presentable list with office labels. */ private rebuildHolidayRows(): void { this.holidayRows = this.holidays.map((h: any) => { @@ -511,7 +558,15 @@ export class BankCalendarComponent implements OnInit { buildCalendar() { this.months = []; - this.overallStats = { working: 0, nonWorking: 0, holidays: 0, sundays: 0, sat2nd4th: 0, totalDays: 0 }; + this.overallStats = { + working: 0, + nonWorking: 0, + holidays: 0, + sundays: 0, + sat2nd4th: 0, + weeklyOff: 0, + totalDays: 0 + }; for (let m = 0; m < 12; m++) { const monthData = this.buildMonth(m, this.currentYear); @@ -521,6 +576,7 @@ export class BankCalendarComponent implements OnInit { this.overallStats.holidays += monthData.holidays; this.overallStats.sundays += monthData.sundays; this.overallStats.sat2nd4th += monthData.secondFourthSat; + this.overallStats.weeklyOff += monthData.weeklyOff; } this.overallStats.totalDays = this.overallStats.working + this.overallStats.nonWorking; } @@ -552,6 +608,7 @@ export class BankCalendarComponent implements OnInit { let holidayCount = 0; let sundayCount = 0; let sat2nd4thCount = 0; + let weeklyOffCount = 0; // Previous month padding const prevMonthDays = new Date(year, month, 0).getDate(); @@ -567,6 +624,7 @@ export class BankCalendarComponent implements OnInit { isSunday: false, is2ndSaturday: false, is4thSaturday: false, + isWeeklyOff: false, dayOfWeek: (startDayOfWeek - i - 1 + 7) % 7 }); } @@ -576,24 +634,29 @@ export class BankCalendarComponent implements OnInit { for (let d = 1; d <= daysInMonth; d++) { const date = new Date(year, month, d); const dow = date.getDay(); - const isSunday = dow === 0; const isSaturday = dow === 6; + const isWorkingWeekday = this.workingDaysConfig.includes(DAY_CODES[dow]); + const isSunday = dow === 0 && !isWorkingWeekday; if (isSaturday) saturdayCount++; - const is2ndSat = isSaturday && saturdayCount === 2; - const is4thSat = isSaturday && saturdayCount === 4; + // RBI: when Saturday is a working day the 2nd and 4th are still off. When Working Days leaves + // Saturday out, every Saturday is a weekly off instead. + const is2ndSat = isSaturday && isWorkingWeekday && saturdayCount === 2; + const is4thSat = isSaturday && isWorkingWeekday && saturdayCount === 4; + const isWeeklyOff = dow !== 0 && !isWorkingWeekday; const isToday = date.toDateString() === today.toDateString(); // Check if holiday const holiday = this.getHolidayForDate(year, month, d); const isHoliday = !!holiday; - // Non-working: Sunday, 2nd Sat, 4th Sat, or holiday - const isNonWorking = isSunday || is2ndSat || is4thSat || isHoliday; + // Non-working: Sunday, 2nd Sat, 4th Sat, a weekly off from Working Days, or holiday + const isNonWorking = isSunday || is2ndSat || is4thSat || isWeeklyOff || isHoliday; if (isSunday) sundayCount++; - if (is2ndSat || is4thSat) sat2nd4thCount++; + if (is2ndSat || is4thSat || (isSaturday && isWeeklyOff)) sat2nd4thCount++; + if (isWeeklyOff && !isSaturday) weeklyOffCount++; if (isHoliday) holidayCount++; if (isNonWorking) { @@ -613,6 +676,7 @@ export class BankCalendarComponent implements OnInit { isSunday, is2ndSaturday: is2ndSat, is4thSaturday: is4thSat, + isWeeklyOff, holidayName: holiday?.name, dayOfWeek: dow }); @@ -632,6 +696,7 @@ export class BankCalendarComponent implements OnInit { isSunday: false, is2ndSaturday: false, is4thSaturday: false, + isWeeklyOff: false, dayOfWeek: days.length % 7 }); } @@ -645,7 +710,8 @@ export class BankCalendarComponent implements OnInit { nonWorkingDays: nonWorkingCount, holidays: holidayCount, sundays: sundayCount, - secondFourthSat: sat2nd4thCount + secondFourthSat: sat2nd4thCount, + weeklyOff: weeklyOffCount }; }