Commit d985e9e4 by Yvon Kerdoncuff

#7332 : rework makeups management in binom creation code + some makeups refactoring

parent 97e7bc61
......@@ -437,14 +437,41 @@ def update_members_makeups(request):
return response
def update_members_makeups_core(members_data, res):
def update_std_member_makeups_to_do_and_points_given_points_target(member_id, points_target, description):
cm = CagetteMember(member_id)
cs = CagetteShift()
points_diff = points_target - cm.get_member_points("standard")
makeup_change_count = - points_diff
target_makeups_nb = makeup_change_count + cs.get_member_makeups_to_do(cm.id)
members_data = {
'member_id': member_id,
'points_diff': points_diff,
'description': description,
'member_shift_type': 'standard',
'target_makeups_nb': target_makeups_nb
}
update_members_makeups_core([members_data])
def update_members_makeups_core(members_data, res = None):
"""Met à jour makeups_to_do et le nombre de points.
members_data est une liste dont chaque élément doit contenir :
- member_id
- points_diff (positif : ajout de points)
- description
- member_shift_type
- target_makeups_nb
Si res est fourni, écrit dedans des données de retour des opérations ainsi que le nombre de points standard
selon un format (à préciser).
- """
for member_data in members_data:
cm = CagetteMember(int(member_data["member_id"]))
# If points are added, we need to manage makeups count change here,
# otherwise this is handled automatically by odoo when points are changed
if member_data["points_diff"] > 0:
res["res"].append(cm.update_member_makeups(member_data))
update_makeups_res = cm.update_member_makeups(member_data)
if res:
res["res"].append(update_makeups_res)
data = {
'name': "Admin BDM - " + member_data["description"],
......@@ -455,6 +482,7 @@ def update_members_makeups_core(members_data, res):
}
cm.update_member_points(data)
if res:
res["res"][-1]['standard_points'] = cm.get_member_points("standard")
def regenerate_member_delay(request):
......@@ -833,64 +861,34 @@ def create_pair(request):
parent['shift_type'] = 'standard'
if not 'shift_type' in child:
child['shift_type'] = 'standard'
# fusion des rattrapages
child_makeups = child['makeups_to_do']
parent_makeups = parent['makeups_to_do']
child_scheduled_makeups = api.search_read('shift.registration', [['partner_id', '=', child_id],
['is_makeup', '=', True],
['state', '=', 'open'],
['date_begin', '>', datetime.now().isoformat()]])
parent_scheduled_makeups = api.search_read('shift.registration', [['partner_id', '=', parent_id],
['is_makeup', '=', True],
['state', '=', 'open'],
['date_begin', '>', datetime.now().isoformat()]])
child_scheduled_makeups = shifts.fonctions.get_scheduled_makeups(api, partner_ids=[child_id])
parent_scheduled_makeups_length = len(shifts.fonctions.get_scheduled_makeups(api, partner_ids=[parent_id]))
child_makeups += len(child_scheduled_makeups)
parent_makeups += len(parent_scheduled_makeups)
if child_makeups:
# le suppléant a des rattrapages
if child_makeups + parent_makeups <=2:
# on transfert les rattrapages sur le parent
# Comme on annule les services du suppléant, les makeup_to_do du titulaire seront affectés par la modification du compteur
# On annule les rattrapages du child
api.update('res.partner', [child_id], {"makeups_to_do": 0})
for makeup in range(child_makeups):
# reset du compteur du suppléant
api.create('shift.counter.event', {"name": 'passage en binôme',
"shift_id": False,
"type": child['shift_type'],
"partner_id": child_id,
"point_qty": 1})
# on retire les points au titulaire, les rattrages sont automatiquement ajoutés
api.create('shift.counter.event', {"name": 'passage en binôme',
"shift_id": False,
"type": parent['shift_type'],
"partner_id": parent_id,
"point_qty": -1})
elif child_makeups + parent_makeups > 2:
# on annule les rattrapages du suppléant et les rattrapages du titulaire seront ajustés par les modifications de compteur
api.update('res.partner', [child_id], {"makeups_to_do": 0})
for makeup in range(child_makeups):
# reset du compteur du suppléant
api.create('shift.counter.event', {"name": 'passage en binôme',
"shift_id": False,
"type": child['shift_type'],
"partner_id": child_id,
"point_qty": 1})
for i in range(abs(parent_makeups - 2)):
# màj du compteur du titulaire
api.create('shift.counter.event', {"name": "passage en binôme",
"shift_id": False,
"type": parent['shift_type'],
"partner_id": parent_id,
"point_qty": -1})
# No more useful since status is fully managed by lacagette_addons modules
# api.execute('res.partner', 'run_process_target_status', [])
parent_makeups += parent_scheduled_makeups_length
unsubscription_limit = api.get_system_param('lacagette_membership.points_limit_to_get_unsubscribed')
min_total_points = unsubscription_limit + 1
max_total_makeups = - min_total_points
# 1. First of all, set the proper final number of points / total makeups of titulaire :
parent_points_target = max(min_total_points, - (child_makeups + parent_makeups))
update_std_member_makeups_to_do_and_points_given_points_target(
parent_id, parent_points_target, 'création de binôme (transfert vers titulaire)'
)
# 2.Then, try to transfer some scheduled makeups of the suppleant on the titulaire, when possible.
# Note that this second step will maintain the same point count and the same total number of makeups.
handle_suppleant_scheduled_makeups_on_pairing(parent_id, child, child_scheduled_makeups, parent,
parent_scheduled_makeups_length, max_total_makeups)
# 3. Final step is to set to reset points of the child. This is easy as the child has no more scheduled makeups.
update_std_member_makeups_to_do_and_points_given_points_target(
child_id, 0, 'création de binôme (mise à zéro suppléant)'
)
m = CagetteMember(child_id).unsubscribe_member()
# update child base account state
......@@ -921,6 +919,29 @@ def create_pair(request):
return JsonResponse({"message": "Method Not Allowed"}, status=405)
def handle_suppleant_scheduled_makeups_on_pairing(parent_id, child, child_scheduled_makeups, parent, parent_scheduled_makeups_length, max_total_makeups):
"""Unselect scheduled makeups of suppleant, and, when possible, transfert them to the titulaire."""
# If one of the two is not standard there is nothing to do
if parent['shift_type'] == 'standard' and child["shift_type"] == 'standard':
for child_scheduled_makeup in child_scheduled_makeups:
cs = CagetteShift()
cs.unselect_makeup(
child_scheduled_makeup['id'],
cancellation_origin="Admin Bdm",
cancellation_description="Désélection d'un rattrapage du suppléant à la création d'un binôme"
)
# If there is room for additional scheduled makeup on the titulaire, subscribe to the makeup !
if parent_scheduled_makeups_length < max_total_makeups:
data = {
'idPartner': parent_id,
'idShift': child_scheduled_makeup['shift_id'][0],
'shift_type': 'standard',
'is_makeup': True
}
cs.set_shift(data) # Automaticaly decrements makeups_to_do to preserve total count.
parent_scheduled_makeups_length = parent_scheduled_makeups_length + 1
def isPartnerInvolvedInBinom(api, partner):
# First make sure the selected partner "is not already a suppleant"
# Let's be prudent : cover both case of partner being suppleant member,
......
......@@ -1065,20 +1065,11 @@ class CagetteMember(models.Model):
return res
def get_member_selected_makeups(self):
res = {}
c = [["partner_id", "=", self.id], ["is_makeup", "=", True], ["state", "=", "open"]]
f=['id']
res = self.o_api.search_read("shift.registration", c, f)
return res
def get_makeup_registrations_ids_on_shift_template(self, shift_template_id):
""" Get the makeup registrations that are on a shift template """
makeup_reg_ids = []
c = [["partner_id", "=", self.id], ["is_makeup", "=", True], ["state", "=", "open"]]
f = ['id', 'shift_id']
res_shift_ids = self.o_api.search_read("shift.registration", c, f)
res_shift_ids = shifts.fonctions.get_scheduled_makeups(self.api, partner_ids=[self.id])
for shift_reg in res_shift_ids:
c = [["id", "=", int(shift_reg['shift_id'][0])]]
f = ['shift_template_id']
......@@ -1369,6 +1360,7 @@ class CagetteMembers(models.Model):
@staticmethod
def get_makeups_members(ids=[]):
# 0 : fetch members with makeups_to_do > 0
api = OdooAPI()
cond = [['makeups_to_do','>', 0]]
......@@ -1405,8 +1397,7 @@ class CagetteMembers(models.Model):
def add_makeups_to_come_to_member_data(api, res):
if res:
for idx, partner in enumerate(res):
[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'] = len(shifts.fonctions.get_scheduled_makeups(api, partner_ids=[int(partner['id'])]))
@staticmethod
def get_attached_members():
......
......@@ -9,9 +9,7 @@ def dateIsoUTC(myDate):
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)
shift_data = get_scheduled_makeups(api)
count_dic = {}
for value in shift_data:
if value['partner_id'][0] in count_dic:
......@@ -48,3 +46,12 @@ def get_exempted_ids_from(api, partner_ids):
['cooperative_state', 'in', ['exempted']]]
fields = ['id']
return api.search_read('res.partner', cond, fields)
def get_scheduled_makeups(api, partner_ids=None):
c = [["is_makeup", "=", True], ["state", "=", "open"], ['date_begin', '>', datetime.datetime.now().isoformat()]]
if partner_ids:
c.append(["partner_id", "in", partner_ids])
f = ['id', 'shift_id', 'partner_id']
res_shift_ids = api.search_read("shift.registration", c, f)
return res_shift_ids
......@@ -297,7 +297,13 @@ class CagetteShift(models.Model):
def set_shift(self, data):
"""Shift registration.
Decrement makeups_to_do if shift has to be a makeup.
Handle partner already registered on this shift case."""
Handle partner already registered on this shift case.
data should coutain :
- idPartner
- idShift
- shift_type
- is_makeup
"""
st_r_id = False
try:
shift_type = "standard"
......
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