~tempo-openerp/+junk/openerp-tempo-addon-fr-dayoff

« back to all changes in this revision

Viewing changes to fr_dayoff.py

  • Committer: vg at tempo-consulting
  • Date: 2013-09-03 08:07:51 UTC
  • Revision ID: vg@tempo-consulting.fr-20130903080751-rfiyx26ftx168swk
[NEW] Code review and Unit test

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
from datetime import timedelta
35
35
 
36
36
 
 
37
# https://fr.wikipedia.org/wiki/F%C3%AAtes_et_jours_f%C3%A9ri%C3%A9s_en_France
 
38
# DOM-TOM is not implemented
 
39
 
37
40
FR_DAY_OFF_SETTINGS = {
38
 
    'rest_days': [6,7],  # iso weekdays list
39
 
    'alsace_lorraine': True,
 
41
    'rest_days': [6,7],  # iso weekdays list (1 Monday, 7 Sunday)
 
42
    'region': 'alsace_moselle'  # False, '', 'alsace_moselle'
40
43
}    
41
44
 
42
45
class fr_dayoff(osv.osv):
45
48
        
46
49
    _columns = {
47
50
    }
48
 
    
49
 
    def _get_easter_hodges(self, year):
50
 
        """
51
 
        return easter day from Hodges Algorithm
52
 
        year: (integer) year
53
 
        """
54
 
        a=year//100
55
 
        b=year%100
56
 
        c=(3*(a+25))//4
57
 
        d=(3*(a+25))%4
58
 
        e=(8*(a+11))//25
59
 
        f=(5*a+b)%19
60
 
        g=(19*f+c-e)%30
61
 
        h=(f+11*g)//319
62
 
        j=(60*(5-d)+b)//4
63
 
        k=(60*(5-d)+b)%4
64
 
        m=(2*j-k-g+h)%7
65
 
        n=(g-h+m+114)//31
66
 
        p=(g-h+m+114)%31
67
 
        day=p+1
68
 
        month=n
69
 
        return datetime.date(year, month, day)
70
51
        
71
52
    def is_dayoff(self, d):
72
53
        """
78
59
            if d.isoweekday() in FR_DAY_OFF_SETTINGS['rest_days']:
79
60
                return True
80
61
    
81
 
        dayoffs = self.get_year_dayoffs(self, year, filter_rest_days=True)
 
62
        dayoffs = self.get_year_dayoffs(d.year)
82
63
        if d in dayoffs:
83
64
            return True
84
65
        else:
86
67
        
87
68
    def get_period_worked_days(self, d_from, d_to):
88
69
        """
89
 
        return (integer) day count of work days for the period
 
70
        return (worked_days, rest_days) (tuple of integers) day count of work days for the period
90
71
        d_from: (date) period start date included
91
72
        d_to: (date) period end date included
92
73
        """
 
74
        worked_days = 0
 
75
        rest_days = 0
93
76
        d = d_from
94
 
        while d < d_to:
 
77
        while d <= d_to:
95
78
            if self.is_dayoff(d):
96
 
                d = d + timedelta(days=1)
 
79
                rest_days += 1
 
80
            else:
 
81
                worked_days += 1
 
82
            d = d + timedelta(days=1)
 
83
        return (worked_days, rest_days)
97
84
        
98
85
    def get_year_dayoffs(self, year, filter_rest_days=True):
99
86
        """
111
98
        days[datetime.date(year, 11, 1)] = "Toussaint"
112
99
        days[datetime.date(year, 11, 11)] = "Armistice"
113
100
        days[datetime.date(year, 12, 25)] = "Noël"
114
 
        if 'alsace_lorraine' in FR_DAY_OFF_SETTINGS \
115
 
            and FR_DAY_OFF_SETTINGS['alsace_lorraine']:
 
101
        if 'region' in FR_DAY_OFF_SETTINGS \
 
102
            and FR_DAY_OFF_SETTINGS['region'] == 'alsace_moselle':
116
103
            days[datetime.date(year, 12, 26)] = "Saint Etienne"
117
104
        
118
105
        # easter dates
121
108
        days[e + timedelta(days=1)] = "Lundi de Pâques"
122
109
        days[e + timedelta(days=39)] = "Jeudi de l'Ascension"
123
110
        days[e + timedelta(days=50)] = "Lundi de Pentecôte"
 
111
        if 'region' in FR_DAY_OFF_SETTINGS \
 
112
            and FR_DAY_OFF_SETTINGS['region'] == 'alsace_moselle':
 
113
            # Vendredi Saint
 
114
            days[e - timedelta(days=2)] = "Vendredi Saint"
124
115
        
125
116
        # result
126
117
        if filter_rest_days and 'rest_days' in FR_DAY_OFF_SETTINGS \
132
123
            return res
133
124
        else:
134
125
            return days
 
126
            
 
127
    def _get_easter_hodges(self, year):
 
128
        """
 
129
        return easter day from Hodges Algorithm
 
130
        year: (integer) year
 
131
        """
 
132
        a=year//100
 
133
        b=year%100
 
134
        c=(3*(a+25))//4
 
135
        d=(3*(a+25))%4
 
136
        e=(8*(a+11))//25
 
137
        f=(5*a+b)%19
 
138
        g=(19*f+c-e)%30
 
139
        h=(f+11*g)//319
 
140
        j=(60*(5-d)+b)//4
 
141
        k=(60*(5-d)+b)%4
 
142
        m=(2*j-k-g+h)%7
 
143
        n=(g-h+m+114)//31
 
144
        p=(g-h+m+114)%31
 
145
        day=p+1
 
146
        month=n
 
147
        return datetime.date(year, month, day)
 
148
            
 
149
    def _unit_test(self):
 
150
        dayoffs = self.get_year_dayoffs(2013, filter_rest_days=True)
 
151
        print dayoffs
 
152
        
 
153
        test =  self.is_dayoff(datetime.date(2013, 8, 15))
 
154
        print 'is_dayoff 15 august th (True):', test
 
155
        test =  self.is_dayoff(datetime.date(2013, 8, 16))
 
156
        print 'is_dayoff 16 august fr (False):', test
 
157
        test =  self.is_dayoff(datetime.date(2013, 8, 17))
 
158
        print 'is_dayoff 17 august sa (True):', test
 
159
        test =  self.is_dayoff(datetime.date(2013, 8, 18))
 
160
        print 'is_dayoff 18 august su (True):', test
 
161
        test =  self.is_dayoff(datetime.date(2013, 3, 29))
 
162
        print 'is_dayoff 29 March (Vendredi Saint):', test
 
163
        test =  self.is_dayoff(datetime.date(2013, 12, 26))
 
164
        print 'is_dayoff 26 December (Saint-Etienne):', test
 
165
        
 
166
        worked, rest =  self.get_period_worked_days(datetime.date(2013, 8, 2),
 
167
                            datetime.date(2013, 8, 16))    
 
168
        print 'get_period_worked_days from 16 august worked days'
 
169
        print '10 work days / 5 rest days'
 
170
        print '(2 weekends and 15 is dayoff):', worked, rest
135
171
 
136
172
fr_dayoff()
137
173