views.py 19.3 KB
Newer Older
Administrator committed
1 2 3 4
from outils.common_imports import *
from outils.for_view_imports import *
from outils.common import Verification

5
from shifts.models import CagetteShift
Damien Moulard committed
6
from members.models import CagetteMember
Administrator committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

# working_state = ['up_to_date', 'alert', 'exempted', 'delay', 'suspended']
state_shift_allowed = ["up_to_date", "alert", "delay"]

tz = pytz.timezone("Europe/Paris")

def dateIsoUTC(myDate):
    tDate = tz.localize(datetime.datetime.strptime(myDate, '%Y-%m-%d %H:%M:%S'))
    return tDate.isoformat()

def home(request, partner_id, hashed_date):
    import hashlib
    cs = CagetteShift()
    partnerData = cs.get_data_partner(partner_id)

    md5_calc = hashlib.md5(partnerData['create_date'].encode('utf-8')).hexdigest()
    if (md5_calc == hashed_date):
        # if not request.session.get('odoo_token', False):
        #     import uuid
        #     request.session['odoo_token'] = uuid.uuid4().hex
        #     request.session.modified = True
        # Ne fonctionne pas !!! Les données de sessions sont perdues à la connexion suivante (ajax : voir cross domain cookies
        if len(partnerData) > 0:
            partnerData['verif_token'] = md5_calc
            if len(partnerData['leave_ids']) > 0:
                listLeave = cs.get_leave(int(partner_id))
                if len(listLeave) > 0:
                    partnerData["is_leave"] = True
                    partnerData["leave_start_date"] = listLeave[0]["start_date"]
                    partnerData["leave_stop_date"] = listLeave[0]["stop_date"]

            # Error case encountered from Odoo: member in delay state and last extension is over -> member is suspended
            try:
                if partnerData['cooperative_state'] == "delay" and datetime.datetime.strptime(partnerData['date_delay_stop'], '%Y-%m-%d') < datetime.datetime.now():
                    partnerData['cooperative_state'] = "suspended"
            except:
                pass

            if partnerData['cooperative_state'] in state_shift_allowed:
                # domain = "127.0.0.1"
47
                domain = getattr(settings, 'EMAIL_DOMAIN', 'lacagette-coop.fr')
Administrator committed
48 49 50 51 52 53 54 55
                days_to_hide = "0"
                if hasattr(settings, 'SHIFT_EXCHANGE_DAYS_TO_HIDE'):
                    days_to_hide = settings.SHIFT_EXCHANGE_DAYS_TO_HIDE
                context = {'title': 'Calendrier', "partnerData": partnerData,
                           'daysToHide': days_to_hide,
                           'SHIFT_INFO': settings.SHIFT_INFO,
                           'PB_INSTRUCTIONS': settings.PB_INSTRUCTIONS,
                           'domain': domain}
56
                context['ADDITIONAL_INFO_SHIFT_PAGE'] = getattr(settings, 'ADDITIONAL_INFO_SHIFT_PAGE', '')
Administrator committed
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
                if hasattr(settings, 'CALENDAR_NO_MORE_LINK'):
                    if settings.CALENDAR_NO_MORE_LINK is True:
                        context['calendarEventNoMoreLinks'] = True
                if hasattr(settings, 'CAL_INITIAL_VIEW'):
                    context['calInitialView'] = settings.CAL_INITIAL_VIEW
                    #  No effect with 3.9 version : TODO upgrade fullCalendar lib
                    #  Needs init calendar rewriting
                response = render(request, 'shifts/shift_exchange.html', context)
            else:
                context = {'title': 'Invitation', "partnerData": partnerData}
                if hasattr(settings, 'UNSUBSCRIBED_MSG'):
                    context['UNSUBSCRIBED_MSG'] = settings.UNSUBSCRIBED_MSG
                response = render(request, 'shifts/shift_states_not_allowed.html', context)

            # response.set_cookie('odoo_token', request.session.get('odoo_token', False) )
            return response
        else:
            return HttpResponseNotFound('<h1>Nothing to show !</h1>')
    else:
        return HttpResponseForbidden()


79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
def _is_middled_filled_considered(reserved, max):
    """Added to fit with new LaCagette need. (based on num rather than %)."""
    answer = False
    toggle_num = 0
    try:
        toggle_num = int(getattr(settings, 'SHIFT_COLOR_TOGGLE_NUM', 0))
    except:
        coop_logger.warning("Wrong value for SHIFT_COLOR_TOGGLE_NUM : %s",
                            str(getattr(settings, 'SHIFT_COLOR_TOGGLE_NUM', 0))
                            )
    if toggle_num == 0:
        if int(reserved) / int(max) < 0.5:
            answer = True
    else:
        answer = int(reserved) <= toggle_num
    return answer


Administrator committed
97 98 99 100
def get_list_shift_calendar(request, partner_id):
    cs = CagetteShift()
    registerPartner = cs.get_shift_partner(partner_id)

101
    use_new_members_space = getattr(settings, 'USE_NEW_MEMBERS_SPACE', False) 
102
    remove_15_minutes_at_shift_end = getattr(settings, 'REMOVE_15_MINUTES_AT_SHIFT_END', True)
Administrator committed
103
    listRegisterPartner = []
Etienne Freiss committed
104
    listMakeUpShift = []
Administrator committed
105 106
    for v in registerPartner:
        listRegisterPartner.append(v['id'])
Etienne Freiss committed
107 108
        if v['is_makeup']:
            listMakeUpShift.append(v['id'])
Administrator committed
109 110 111 112 113 114 115

    start = request.GET.get('start')
    end = request.GET.get('end')
    listService = cs.get_shift_calendar(partner_id, start, end)

    events = []
    for value in listService:
116
        if value['shift_type_id'][0] == 1 or getattr(settings, 'USE_STANDARD_SHIFT', True) is False:
117
            #  Standard ou volant si on n'utilise pas les services standards (config)
Administrator committed
118 119 120 121 122 123
            l = set(value['registration_ids']) & set(listRegisterPartner)
            # if (int(value['seats_reserved']) == int(value['seats_max']) and len(l) > 0 ) or (int(value['seats_reserved']) < int(value['seats_max'])):
            if (int(value['seats_available']) > 0 or len(l) > 0 ):
                event = {}
                event["id"] = value['id']
                smax = int(value['seats_available']) + int(value['seats_reserved'])
124
 
Damien Moulard committed
125
                company_code = getattr(settings, 'COMPANY_CODE', '')
Félicie committed
126
                title_prefix = ''
Damien Moulard committed
127
                if company_code != "lacagette" and len(value['address_id']) == 2 and ',' in value['address_id'][1]:
Félicie committed
128
                    title_prefix = str(value['address_id'][1]).split(",")[1] + " --"
Damien Moulard committed
129
                elif company_code == "lacagette":
130
                    title_prefix = " - "
131

Administrator committed
132 133
                event["title"] = title_prefix + str(value['seats_reserved']) + "/" + str(smax)

Félicie committed
134

Administrator committed
135
                event["start"] = dateIsoUTC(value['date_begin_tz'])
Félicie committed
136

137 138 139
                datetime_object = datetime.datetime.strptime(value['date_end_tz'], "%Y-%m-%d %H:%M:%S")
                if remove_15_minutes_at_shift_end is True:
                    datetime_object -= datetime.timedelta(minutes=15)
Félicie committed
140
                event["end"] = dateIsoUTC(datetime_object.strftime("%Y-%m-%d %H:%M:%S"))
Administrator committed
141 142

                if len(l) > 0:
143
                    if use_new_members_space is True:
Etienne Freiss committed
144 145 146 147
                        if set(value['registration_ids']) & set(listRegisterPartner) & set(listMakeUpShift):
                            event["classNames"] = ["shift_booked_makeup"]
                        else : 
                            event["classNames"] = ["shift_booked"]
148 149
                    else:
                        event["className"] = "shift_booked"
Administrator committed
150 151 152 153 154
                    event["changed"] = False
                # elif int(value['seats_reserved']) == int(value['seats_max']):
                #     event["className"] = "shift_full"
                #     event["changed"] = False
                elif int(value['seats_reserved']) == 0:
155 156 157 158
                    if use_new_members_space is True:
                        event["classNames"] = ["shift_empty"]
                    else:
                        event["className"] = "shift_empty"
Administrator committed
159
                    event["changed"] = True
160
                elif _is_middled_filled_considered(value['seats_reserved'], smax) is True:
161 162 163 164
                    if use_new_members_space is True:
                        event["classNames"] = ["shift_less_alf"]
                    else:
                        event["className"] = "shift_less_alf"
Administrator committed
165 166
                    event["changed"] = True
                else:
167 168 169 170
                    if use_new_members_space is True:
                        event["classNames"] = ["shift_other"]
                    else:
                        event["className"] = "shift_other"
Administrator committed
171 172 173 174 175 176 177 178 179 180 181
                    event["changed"] = True

                event["registration_ids"] = value['registration_ids']
                events.append(event)

    response = JsonResponse(events, safe=False)
    return response

def get_list_shift_partner(request, partner_id):
    cs = CagetteShift()
    shiftData = cs.get_shift_partner(partner_id)
182

Administrator committed
183 184 185
    for value in shiftData:
        value['date_begin'] = value['date_begin'] + "Z"
        value['date_end'] = value['date_end'] + "Z"
186

Administrator committed
187 188 189 190 191 192 193 194 195 196
    return JsonResponse(shiftData, safe=False)

def change_shift(request):
    if 'verif_token' in request.POST:
        if Verification.verif_token(request.POST.get('verif_token'), int(request.POST.get('idPartner'))) is True:

            cs = CagetteShift()

            if 'idNewShift' in request.POST and 'idOldShift' in request.POST:
                idOldShift = request.POST['idOldShift']
197
                listRegister = [int(request.POST['idRegister'])]
198 199
                data = {
                    "idPartner": int(request.POST['idPartner']),
200
                    "idShift": int(request.POST['idNewShift']),
201
                    "shift_type": request.POST['shift_type'],
202
                    "is_makeup": cs.shift_is_makeup(listRegister[0])
203 204 205 206 207 208 209 210 211 212 213 214 215 216
                }
                
                should_block_service_exchange = getattr(settings, 'BLOCK_SERVICE_EXCHANGE_24H_BEFORE', False)
                if should_block_service_exchange:
                    # Block change if old shift is to happen in less than 24 hours
                    now = datetime.datetime.now(tz)

                    old_shift = cs.get_shift(idOldShift)
                    day_before_old_shift_date_start = tz.localize(datetime.datetime.strptime(old_shift['date_begin_tz'], '%Y-%m-%d %H:%M:%S') - datetime.timedelta(hours=24))

                    if now > day_before_old_shift_date_start:
                        response = {'msg': "Old service in less than 24hours."}
                        return JsonResponse(response, status=400)

217 218 219 220 221
                if cs.is_shift_exchange_allowed(idOldShift, data["idShift"], data["shift_type"], data["idPartner"]) is False:
                    response = {'msg': "Not allowed to change shift"}
                    return JsonResponse(response, status=400)


Administrator committed
222 223 224 225 226 227 228 229
                st_r_id = False
                #Insertion du nouveau shift
                try:
                    st_r_id = cs.set_shift(data)
                except Exception as e:
                    coop_logger.error("Change shift : %s, %s", str(e), str(data))
                if st_r_id:
                    listRegister = [int(request.POST['idRegister'])]
230 231

                    # Annule l'ancien shift
Administrator committed
232 233 234 235
                    response = cs.cancel_shift(listRegister)

                    response = {'result': True}
                else:
Félicie committed
236 237
                    response = {'msg': "Fail to create shift"}
                    return JsonResponse(response, status=500)
Administrator committed
238
            else:
Félicie committed
239 240
                response = {'msg': "Bad arguments"}
                return JsonResponse(response, status=400)
Administrator committed
241 242 243 244 245 246
            return JsonResponse(response)
        else:
            return HttpResponseForbidden()
    else:
        return HttpResponseForbidden()

Etienne Freiss committed
247 248 249 250 251
def affect_shift(request):
    if 'verif_token' in request.POST:
        if Verification.verif_token(request.POST.get('verif_token'), int(request.POST.get('idPartner'))) is True:
            cs = CagetteShift()
            if 'idShiftRegistration' in request.POST and 'affected_partner' in request.POST:
252 253
                #  if request is made by associated people, idPartner is it's id, not "master" res.partner
                #  it's will be handled in model's method (affect_shift)
Etienne Freiss committed
254 255 256 257 258
                data = {
                    "idPartner": int(request.POST['idPartner']),
                    "idShiftRegistration": int(request.POST['idShiftRegistration']),
                    "affected_partner": request.POST['affected_partner'],
                }
259
                st_r_id = None
Etienne Freiss committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
                try:
                    st_r_id = cs.affect_shift(data)
                except Exception as e:
                    coop_logger.error("affect shift : %s, %s", str(e), str(data))
                if st_r_id:
                    response = {'result': True}
                else:
                    response = {'msg': "Internal Error"}
                    return JsonResponse(response, status=500)
                return(JsonResponse({'result': True}))
            else:
                response = {'msg': "Bad args"}
                return JsonResponse(response, status=400)
        else:
            return HttpResponseForbidden()
    else:
        return HttpResponseForbidden()

Administrator committed
278 279 280 281 282 283
def add_shift(request):
    if 'verif_token' in request.POST:
        if Verification.verif_token(request.POST.get('verif_token'), int(request.POST.get('idPartner'))) is True:
            cs = CagetteShift()

            if 'idNewShift' in request.POST and 'idPartner' in request.POST:
284 285 286
                data = {
                    "idPartner": int(request.POST['idPartner']), 
                    "idShift":int(request.POST['idNewShift']), 
287
                    "shift_type":request.POST['shift_type'],
288
                    "is_makeup": False
289
                }
290 291 292

                if 'is_makeup' in request.POST and request.POST['is_makeup'] == "1":
                    data['is_makeup'] = True
293
                
Administrator committed
294 295 296 297 298 299
                #Insertion du nouveau shift
                st_r_id = False
                try:
                    st_r_id = cs.set_shift(data)
                except Exception as e:
                    coop_logger.error("Add shift : %s, %s", str(e), str(data))
300

Administrator committed
301 302 303 304
                if st_r_id:
                    response = {'result': True}
                else:
                    response = {'result': False}
305 306 307 308 309 310 311 312 313 314 315 316 317

                # decrement makeups_to_do
                res_decrement = False
                try:
                    res_decrement = cs.decrement_makeups_to_do(int(request.POST['idPartner']))
                except Exception as e:
                    coop_logger.error("Decrement makeups to do : %s, %s", str(e), str(data))

                if res_decrement:
                    response["decrement_makeups"] = res_decrement
                else:
                    response["decrement_makeups"] = False

Administrator committed
318 319 320 321 322 323 324 325
            else:
                response = {'result': False}
            return JsonResponse(response)
        else:
            return HttpResponseForbidden()
    else:
        return HttpResponseForbidden()

326 327 328 329 330 331 332 333 334 335 336 337
def cancel_shift(request):
    """ Annule une présence à un shift """
    if 'verif_token' in request.POST:
        partner_id = int(request.POST.get('idPartner'))
        if Verification.verif_token(request.POST.get('verif_token'), partner_id) is True:

            cs = CagetteShift()
            listRegister = [int(request.POST['idRegister'])]

            try:
                # decrement extra_shift_done if param exists
                if 'extra_shift_done' in request.POST:
338
                    response = cs.cancel_shift(listRegister, origin='memberspace extra shift done')
339 340 341 342 343 344 345 346
                    target = int(request.POST["extra_shift_done"]) - 1

                    # extra security
                    if target < 0:
                        target = 0

                    cm = CagetteMember(partner_id)
                    cm.update_extra_shift_done(target)
347 348
                else:
                    response = cs.cancel_shift(listRegister)
349 350 351 352 353 354 355 356 357

                return JsonResponse({"res" : 'response'})
            except Exception as e:
                return JsonResponse({"error" : str(e)}, status=500)
        else:
            return HttpResponseForbidden()
    else:
        return HttpResponseForbidden()

Administrator committed
358 359 360 361
def request_delay(request):
    if 'verif_token' in request.POST:
        if Verification.verif_token(request.POST.get('verif_token'), int(request.POST.get('idPartner'))) is True:
            cs = CagetteShift()
362
            partner_id = int(request.POST['idPartner'])
363

364 365 366 367 368 369
            use_new_members_space = getattr(settings, 'USE_NEW_MEMBERS_SPACE', False) 
            if use_new_members_space is True:
                member_can_have_delay = cs.member_can_have_delay(int(request.POST.get('idPartner')))
                if member_can_have_delay is False:
                    res = { 'message' : 'delays limit reached'}
                    return JsonResponse(res, status=403)
370
            
Administrator committed
371
            data = {
372
                "idPartner": partner_id,
Administrator committed
373 374 375 376
                "start_date" : request.POST['start_date']
            }
            if ('extension_beginning' in request.POST):
                data['extension_beginning'] = request.POST['extension_beginning']
377
            duration = 28
378 379 380
            if ('duration' in request.POST):
                duration = int(request.POST['duration'])

Administrator committed
381 382 383
            response = {'result': False}

            try:
384
                new_id = cs.create_delay(data, duration)
Administrator committed
385
                if (new_id):
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
                    try:
                        cm = CagetteMember(partner_id)

                        # Add 0 pt to counter so odoo updates member status
                        data = {
                            'name': "Forcer l'entrée en délai",
                            'shift_id': False,
                            'type': "standard",
                            'partner_id': partner_id,
                            'point_qty': 0
                        }
                        cm.update_member_points(data)

                        data = {
                            'name': "Forcer l'entrée en délai",
                            'shift_id': False,
                            'type': "ftop",
                            'partner_id': partner_id,
                            'point_qty': 0
                        }
                        cm.update_member_points(data)
                    except Exception as e:
                        print(str(e))

Administrator committed
410 411
                    response = {'result': True}
                else:
412
                    coop_logger.error("request delay : %s, %s", str(new_id), str(data))
Administrator committed
413 414
                    return HttpResponseServerError()
            except Exception as e:
415
                coop_logger.error("request delay : %s, %s", str(e), str(data))
Administrator committed
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
                return HttpResponseServerError()

            return JsonResponse(response)
        else:
            return HttpResponseForbidden()
    else:
        return HttpResponseForbidden()

def reset_members_positive_points(request):
    """Called by a cron script"""
    return JsonResponse({'res': CagetteShift.reset_members_positive_points()})

def get_test(request):
    cs = CagetteShift()

    fields = ['shift_ticket_ids', 'shift_type_id']  # res.partner
    cond = []
    # cond = [['partner_id','=',1522],['start_date','<',datetime.datetime.now().isoformat()],['stop_date','>',datetime.datetime.now().isoformat()]]
    # registerPartner = cs.get_test('shift.shift',cond,fields)
    registerPartner =  cs.get_shift_calendar(1018)  # cs.get_data_partner(1538)

    response = JsonResponse(registerPartner, safe=False)
    return response
    #return  HttpResponse(shiftData)

def get_list(request):
    cs = CagetteShift()

    fields = ['cooperative_state']  # res.partner
    cond = []
    registerPartner = cs.get_test('res.partner', cond, fields)
    liste = []
    for val in registerPartner:
        if val[fields[0]] not in liste:
            liste.append(val[fields[0]])

    return JsonResponse(liste, safe=False)