Commit e5bff7b4 by Yvon Kerdoncuff

Merge branch 'migration-v12' into refonte_espace_membre_sc

parents 550ea71e 3277594d
Pipeline #4065 canceled with stage
...@@ -8,6 +8,7 @@ from outils.common import CouchDB ...@@ -8,6 +8,7 @@ from outils.common import CouchDB
from outils.common import Verification from outils.common import Verification
from products.models import OFF from products.models import OFF
from envelops.models import CagetteEnvelops from envelops.models import CagetteEnvelops
import shifts.fonctions
import sys import sys
import pytz import pytz
...@@ -203,6 +204,7 @@ class CagetteMember(models.Model): ...@@ -203,6 +204,7 @@ class CagetteMember(models.Model):
if getattr(settings, 'ALLOW_NON_MEMBER_TO_CONNECT', False) is False: if getattr(settings, 'ALLOW_NON_MEMBER_TO_CONNECT', False) is False:
cond.append('|') cond.append('|')
cond.append(['is_member', '=', True]) cond.append(['is_member', '=', True])
# TODO : consider replacing is_associated_people by suppleant_member_id to exclude mineurs rattachés
cond.append(['is_associated_people', '=', True]) cond.append(['is_associated_people', '=', True])
fields = ['name', 'email', 'birthdate_date', 'create_date', 'cooperative_state', 'is_associated_people', 'barcode_base'] fields = ['name', 'email', 'birthdate_date', 'create_date', 'cooperative_state', 'is_associated_people', 'barcode_base']
...@@ -212,6 +214,7 @@ class CagetteMember(models.Model): ...@@ -212,6 +214,7 @@ class CagetteMember(models.Model):
if (res and len(res) >= 1): if (res and len(res) >= 1):
coop_id = None coop_id = None
hashed_password = None hashed_password = None
# TODO : add comment to explain why there is a loop here
for item in res: for item in res:
coop = item coop = item
if 'hashed_password' in item: if 'hashed_password' in item:
...@@ -219,6 +222,7 @@ class CagetteMember(models.Model): ...@@ -219,6 +222,7 @@ class CagetteMember(models.Model):
if item["birthdate_date"] is not False: if item["birthdate_date"] is not False:
coop_birthdate = item['birthdate_date'] coop_birthdate = item['birthdate_date']
coop_state = item['cooperative_state'] coop_state = item['cooperative_state']
# TODO : consider replacing is_associated_people check by suppleant_member_id to exclude mineurs rattachés
if item["is_associated_people"] == True: if item["is_associated_people"] == True:
coop_id = item['id'] coop_id = item['id']
...@@ -460,18 +464,12 @@ class CagetteMember(models.Model): ...@@ -460,18 +464,12 @@ class CagetteMember(models.Model):
def is_associated(id_parent): def is_associated(id_parent):
api = OdooAPI() api = OdooAPI()
cond = [['parent_id', '=', int(id_parent)]] cond = [['parent_id', '=', int(id_parent)]]
fields = ['id','name','parent_id','birthdate_date'] fields = ['id','name','parent_id','birthdate_date','suppleant_member_id']
res = api.search_read('res.partner', cond, fields, 10, 0, 'id DESC') res = api.search_read('res.partner', cond, fields, 10, 0, 'id DESC')
already_have_adult_associated = False
for partner in res: for partner in res:
birthdate = partner['birthdate_date'] if partner['suppleant_member_id']:
if(birthdate): return True
today = date.today() return False
date1 = datetime.datetime.strptime(birthdate, "%Y-%m-%d")
age = today.year - date1.year - ((today.month, today.day) < (date1.month, date1.day))
if age > 17 :
already_have_adult_associated = True
return already_have_adult_associated
@staticmethod @staticmethod
def finalize_coop_creation(post_data): def finalize_coop_creation(post_data):
...@@ -657,7 +655,8 @@ class CagetteMember(models.Model): ...@@ -657,7 +655,8 @@ class CagetteMember(models.Model):
'city': post_data['city'], 'city': post_data['city'],
'phone': format_phone_number(post_data['mobile']), # Because list view default show Phone and people mainly gives mobile 'phone': format_phone_number(post_data['mobile']), # Because list view default show Phone and people mainly gives mobile
'barcode_rule_id': settings.ASSOCIATE_BARCODE_RULE_ID, 'barcode_rule_id': settings.ASSOCIATE_BARCODE_RULE_ID,
'parent_id' : post_data['parent_id'], 'parent_id': post_data['parent_id'],
'suppleant_member_id': partner_id,
'is_associated_people': True, 'is_associated_people': True,
'function': function 'function': function
} }
...@@ -901,6 +900,7 @@ class CagetteMember(models.Model): ...@@ -901,6 +900,7 @@ class CagetteMember(models.Model):
cond = [['name', 'ilike', str(key)]] cond = [['name', 'ilike', str(key)]]
cond.append('|') cond.append('|')
cond.append(['is_member', '=', True]) cond.append(['is_member', '=', True])
#TODO : replace is_associated_people check by suppleant_member_id check to exclude mineurs rattachés
if search_type != 'members' and search_type != 'envelops': if search_type != 'members' and search_type != 'envelops':
cond.append(['is_associated_people', '=', True]) cond.append(['is_associated_people', '=', True])
else: else:
...@@ -953,7 +953,7 @@ class CagetteMember(models.Model): ...@@ -953,7 +953,7 @@ class CagetteMember(models.Model):
fields = fields + ['shift_type', 'makeups_to_do', 'display_ftop_points', 'display_std_points', 'shift_type'] fields = fields + ['shift_type', 'makeups_to_do', 'display_ftop_points', 'display_std_points', 'shift_type']
cond.append(['shift_type', '=', 'standard']) cond.append(['shift_type', '=', 'standard'])
res = api.search_read('res.partner', cond, fields) res = api.search_read('res.partner', cond, fields)
CagetteMembers.add_makeups_to_come_to_member_data(res) CagetteMembers.add_makeups_to_come_to_member_data(api, res)
return res return res
elif search_type == "shift_template_data": elif search_type == "shift_template_data":
fields = CagetteMember.m_short_default_fields fields = CagetteMember.m_short_default_fields
...@@ -1044,25 +1044,19 @@ class CagetteMember(models.Model): ...@@ -1044,25 +1044,19 @@ class CagetteMember(models.Model):
res = {} res = {}
c = [["parent_id", "=", self.id]] c = [["parent_id", "=", self.id]]
f = ["id", "name", "barcode_base"] f = ["id", "name", "barcode_base", 'suppleant_member_id']
res = self.o_api.search_read('res.partner', c, f) res = self.o_api.search_read('res.partner', c, f)
try: for partner in res:
return res[0] if partner['suppleant_member_id']:
except: return partner
return None return None
def update_member_makeups(self, member_data): def update_member_makeups(self, member_data):
api = OdooAPI() api = OdooAPI()
res = {} makeups_to_do = int(member_data["target_makeups_nb"])
f = {'makeups_to_do': makeups_to_do}
# Prevent setting a negative number of makeups_to_do
# https://redmine.coopdev.fr/issues/6090
# This could happen when bdm has two screens open and clicks on minus btn on a coop line
# with exactly 1 makeup_to_do on both screens
makeups_to_do = max(0,int(member_data["target_makeups_nb"]))
f = { 'makeups_to_do': makeups_to_do }
res_item = api.update('res.partner', [self.id], f) res_item = api.update('res.partner', [self.id], f)
res = { res = {
'mid': self.id, 'mid': self.id,
...@@ -1164,6 +1158,12 @@ class CagetteMember(models.Model): ...@@ -1164,6 +1158,12 @@ class CagetteMember(models.Model):
else: else:
return False return False
def has_state_unsubscribed_gone_or_associated(self):
c = [['id', '=', self.id]]
f = ['cooperative_state']
state = self.o_api.search_read("res.partner", c, f)[0]["cooperative_state"]
return state in ("unsubscribed", "gone", "associated")
class CagetteMembers(models.Model): class CagetteMembers(models.Model):
"""Class to manage operations on all members or part of them.""" """Class to manage operations on all members or part of them."""
...@@ -1400,8 +1400,7 @@ class CagetteMembers(models.Model): ...@@ -1400,8 +1400,7 @@ class CagetteMembers(models.Model):
# 1 : fetching members with no makeups to do but with some makeups to come # 1 : fetching members with no makeups to do but with some makeups to come
# 2 : providing makeups to come to all members # 2 : providing makeups to come to all members
cs = CagetteShift() makeups_to_come_per_partner = shifts.fonctions.get_partners_with_makeups_to_come(api)
makeups_to_come_per_partner = cs.get_partners_with_makeups_to_come()
# 1 : fetching members with no makeups to do but with some makeups to come # 1 : fetching members with no makeups to do but with some makeups to come
cond = [['makeups_to_do', '=', 0], ['id', 'in', list(makeups_to_come_per_partner.keys())]] cond = [['makeups_to_do', '=', 0], ['id', 'in', list(makeups_to_come_per_partner.keys())]]
...@@ -1421,20 +1420,20 @@ class CagetteMembers(models.Model): ...@@ -1421,20 +1420,20 @@ class CagetteMembers(models.Model):
return res return res
@staticmethod @staticmethod
def add_makeups_to_come_to_member_data(res): def add_makeups_to_come_to_member_data(api, res):
if res: if res:
cs = CagetteShift()
for idx, partner in enumerate(res): for idx, partner in enumerate(res):
[shift_data, is_ftop] = cs.get_shift_partner(int(partner['id'])) [shift_data, is_ftop] = shifts.fonctions.get_shift_partner(api, int(partner['id']))
res[idx]['makeups_to_come'] = sum(1 for value in shift_data if value['is_makeup']) res[idx]['makeups_to_come'] = sum(1 for value in shift_data if value['is_makeup'])
@staticmethod @staticmethod
def get_attached_members(): def get_attached_members():
api = OdooAPI() api = OdooAPI()
cond = [['is_associated_people','=', True]] cond = [['is_associated_people', '=', True]]
fields = ['id', 'name', 'parent_name'] fields = ['id', 'name', 'parent_name', 'suppleant_member_id']
res = api.search_read('res.partner', cond, fields) res = api.search_read('res.partner', cond, fields)
return res # Exclude mineurs rattachés
return [x for x in res if res['suppleant_member_id']]
class CagetteUser(models.Model): class CagetteUser(models.Model):
...@@ -1525,5 +1524,3 @@ class CagetteUser(models.Model): ...@@ -1525,5 +1524,3 @@ class CagetteUser(models.Model):
res['error'] = str(e) res['error'] = str(e)
return res return res
\ No newline at end of file
from shifts.models import CagetteShift
...@@ -218,7 +218,7 @@ def home(request): ...@@ -218,7 +218,7 @@ def home(request):
if partnerData['cooperative_state'] == "unsubscribed": if partnerData['cooperative_state'] == "unsubscribed":
coop_can_change_shift_template = False coop_can_change_shift_template = False
if getattr(settings, 'ASSOCIATE_PEOPLE_CAN_CHANGE_SHIFT_TEMPLE_REGISTRATION', False) is False: if getattr(settings, 'ASSOCIATE_PEOPLE_CAN_CHANGE_SHIFT_TEMPLE_REGISTRATION', False) is False:
if partnerData['is_associated_people'] is True: if partnerData['suppleant_member_id']:
coop_can_change_shift_template = False coop_can_change_shift_template = False
context = { context = {
'title': 'Espace Membres', 'title': 'Espace Membres',
......
import datetime, pytz import datetime, pytz
tz = pytz.timezone("Europe/Paris")
def dateIsoUTC(myDate): def dateIsoUTC(myDate):
tz = pytz.timezone("Europe/Paris")
tDate = tz.localize(datetime.datetime.strptime(myDate, '%Y-%m-%d %H:%M:%S')) tDate = tz.localize(datetime.datetime.strptime(myDate, '%Y-%m-%d %H:%M:%S'))
return dDate.isoformat() return tDate.isoformat()
def get_partners_with_makeups_to_come(api):
"""Returns a dictionary with : keys = the partners ids having at least one makeup to come ; values = #makeups_to_come"""
fields = ['partner_id']
cond = [['state', '=', 'open'], ['date_begin', '>', datetime.datetime.now().isoformat()], ['is_makeup', '=', True]]
shift_data = api.search_read('shift.registration', cond, fields)
count_dic = {}
for value in shift_data:
if value['partner_id'][0] in count_dic:
count_dic[value['partner_id'][0]] = count_dic[value['partner_id'][0]] + 1
else:
count_dic[value['partner_id'][0]] = 1
return count_dic
def get_shift_partner(api, id, start_date=None, end_date=None):
"""Récupère les shift du membre"""
shifts = []
is_ftop = False
not_before = datetime.datetime.now().isoformat()
if start_date:
not_before = start_date.isoformat()
fields = ['date_begin', 'date_end',
'shift_id', 'shift_type', 'partner_id', "id", "associate_registered", "is_makeup"] # res.partner
cond = [['partner_id.id', '=', id], ['state', '=', 'open'],
['date_begin', '>', not_before]]
if end_date:
cond.append(['date_begin', '<', end_date.isoformat()])
shiftData = api.search_read('shift.registration', cond, fields, order="date_begin ASC")
for s in shiftData:
if not ('Equipe volante' in s['shift_id'][1]):
shifts.append(s)
else:
is_ftop = True
return [shifts, is_ftop]
def get_exempted_ids_from(api, partner_ids):
cond = [['id', 'in', partner_ids],
['cooperative_state', 'in', ['exempted']]]
fields = ['id']
return api.search_read('res.partner', cond, fields)
\ No newline at end of file
...@@ -4,16 +4,13 @@ from outils.common import Verification ...@@ -4,16 +4,13 @@ from outils.common import Verification
from shifts.models import CagetteShift from shifts.models import CagetteShift
from members.models import CagetteMember from members.models import CagetteMember
import shifts.fonctions
# working_state = ['up_to_date', 'alert', 'exempted', 'delay', 'suspended'] # working_state = ['up_to_date', 'alert', 'exempted', 'delay', 'suspended']
state_shift_allowed = ["up_to_date", "alert", "delay"] state_shift_allowed = ["up_to_date", "alert", "delay"]
tz = pytz.timezone("Europe/Paris") 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): def home(request, partner_id, hashed_date):
import hashlib import hashlib
cs = CagetteShift() cs = CagetteShift()
...@@ -96,7 +93,7 @@ def _is_middled_filled_considered(reserved, max): ...@@ -96,7 +93,7 @@ def _is_middled_filled_considered(reserved, max):
def get_list_shift_calendar(request, partner_id): def get_list_shift_calendar(request, partner_id):
cs = CagetteShift() cs = CagetteShift()
[registerPartner, is_ftop] = cs.get_shift_partner(partner_id) [registerPartner, is_ftop] = shifts.fonctions.get_shift_partner(cs.o_api, partner_id)
use_new_members_space = getattr(settings, 'USE_NEW_MEMBERS_SPACE', False) use_new_members_space = getattr(settings, 'USE_NEW_MEMBERS_SPACE', False)
remove_15_minutes_at_shift_end = getattr(settings, 'REMOVE_15_MINUTES_AT_SHIFT_END', True) remove_15_minutes_at_shift_end = getattr(settings, 'REMOVE_15_MINUTES_AT_SHIFT_END', True)
...@@ -132,12 +129,12 @@ def get_list_shift_calendar(request, partner_id): ...@@ -132,12 +129,12 @@ def get_list_shift_calendar(request, partner_id):
event["title"] = title_prefix + str(value['seats_reserved']) + "/" + str(smax) event["title"] = title_prefix + str(value['seats_reserved']) + "/" + str(smax)
event["start"] = dateIsoUTC(value['date_begin_tz']) event["start"] = shifts.fonctions.dateIsoUTC(value['date_begin_tz'])
datetime_object = datetime.datetime.strptime(value['date_end_tz'], "%Y-%m-%d %H:%M:%S") - datetime.timedelta(minutes=15) datetime_object = datetime.datetime.strptime(value['date_end_tz'], "%Y-%m-%d %H:%M:%S") - datetime.timedelta(minutes=15)
if remove_15_minutes_at_shift_end is True: if remove_15_minutes_at_shift_end is True:
datetime_object -= datetime.timedelta(minutes=15) datetime_object -= datetime.timedelta(minutes=15)
event["end"] = dateIsoUTC(datetime_object.strftime("%Y-%m-%d %H:%M:%S")) event["end"] = shifts.fonctions.dateIsoUTC(datetime_object.strftime("%Y-%m-%d %H:%M:%S"))
if len(l) > 0: if len(l) > 0:
if use_new_members_space is True: if use_new_members_space is True:
...@@ -178,7 +175,7 @@ def get_list_shift_calendar(request, partner_id): ...@@ -178,7 +175,7 @@ def get_list_shift_calendar(request, partner_id):
def get_list_shift_partner(request, partner_id): def get_list_shift_partner(request, partner_id):
cs = CagetteShift() cs = CagetteShift()
[shiftData, is_ftop] = cs.get_shift_partner(partner_id) [shiftData, is_ftop] = shifts.fonctions.get_shift_partner(cs.o_api, partner_id)
for value in shiftData: for value in shiftData:
value['date_begin'] = value['date_begin'] + "Z" value['date_begin'] = value['date_begin'] + "Z"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment