Repository: peopledoc/workalendar (python)

Issue:
Russia public holidays are shifted if happening on SAT/SUN
as described in https://en.wikipedia.org/wiki/Public_holidays_in_Russia and confirmed by https://www.timeanddate.com/calendar/custom.html?year=2020&country=20&cols=3&hol=1&df=1, for example, holidays should be shifted to the next MON when required.

Pull request:
Fix Russia calendar: non-working days shifted to MON when they happen on the week-end

closes #589

- [x] Tests with a significant number of years to be tested for your calendar.
- [x] Changelog amended with a mention describing your changes. **Note** *Please do NOT change the version number here. It's the project maintainers' duty.*


Patch:
diff --git a/Changelog.md b/Changelog.md
index 9c1855f..e462020 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,7 +2,7 @@
 
 ## master (unreleased)
 
-Nothing here yet.
+- Fix Russia calendar: non-working days are shifted to the next MON when they happen on the week-end (#589).
 
 ## v13.0.0 (2020-11-13)
 
diff --git a/workalendar/europe/russia.py b/workalendar/europe/russia.py
index 6a95862..783854a 100644
--- a/workalendar/europe/russia.py
+++ b/workalendar/europe/russia.py
@@ -1,11 +1,10 @@
-from ..core import OrthodoxCalendar
+from ..core import OrthodoxCalendar, MON
 from ..registry_tools import iso_register
 
 
 @iso_register('RU')
 class Russia(OrthodoxCalendar):
     'Russia'
-
     shift_new_years_day = True
 
     # Civil holidays
@@ -20,3 +19,15 @@ class Russia(OrthodoxCalendar):
         (6, 12, "National Day"),
         (11, 4, "Day of Unity"),
     )
+
+    def get_calendar_holidays(self, year):
+        holidays = super().get_calendar_holidays(year)
+        shifts = []
+        for day, label in holidays:
+            if day.weekday() in self.get_weekend_days():
+                shifts.append((
+                    self.get_first_weekday_after(day, MON),
+                    label + " shift"
+                ))
+        holidays.extend(shifts)
+        return holidays


Test patch:
diff --git a/workalendar/tests/test_europe.py b/workalendar/tests/test_europe.py
index 04c5220..073aebd 100644
--- a/workalendar/tests/test_europe.py
+++ b/workalendar/tests/test_europe.py
@@ -1410,6 +1410,33 @@ class RussiaTest(GenericCalendarTest):
         self.assertIn(date(2018, 6, 12), holidays)  # National Day
         self.assertIn(date(2018, 11, 4), holidays)  # Independence Day
 
+    def test_year_2020_shift(self):
+        holidays = dict(self.cal.holidays(2020))
+        # Defender of the Fatherland Day
+        self.assertIn(date(2020, 2, 23), holidays)
+        # SUN => Shift to MON
+        self.assertIn(date(2020, 2, 24), holidays)
+        self.assertEqual(
+            holidays[date(2020, 2, 24)],
+            "Defendence of the Fatherland shift"
+        )
+        # International Women's Day
+        self.assertIn(date(2020, 3, 8), holidays)
+        # SUN => Shift to MON
+        self.assertIn(date(2020, 3, 9), holidays)
+        self.assertEqual(
+            holidays[date(2020, 3, 9)],
+            "International Women's Day shift"
+        )
+        # Victory Day
+        self.assertIn(date(2020, 5, 9), holidays)
+        # SAT => Shift to MON
+        self.assertIn(date(2020, 5, 11), holidays)
+        self.assertEqual(
+            holidays[date(2020, 5, 11)],
+            "Victory Day shift"
+        )
+
 
 class UkraineTest(GenericCalendarTest):
     cal_class = Ukraine