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 @@
@@ -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
};
}