Commit df15e861 by François C.

Fix removing shift template subscription when counter reaches unsubscription limit

parent 5d5cd2a4
...@@ -9,17 +9,17 @@ _logger = logging.getLogger(__name__) ...@@ -9,17 +9,17 @@ _logger = logging.getLogger(__name__)
class ShiftCounterEvent(models.Model): class ShiftCounterEvent(models.Model):
_inherit = 'shift.counter.event' _inherit = 'shift.counter.event'
def _alter_point_event_depending_on_makeups_total_count(self, vals): def _alter_point_event_depending_on_makeups_total_count(self, res_partner, vals, suspension_limit):
""" """
This code helps keeping the consistency between std_counter and makeup total count. This code helps keeping the consistency between std_counter and makeup total count.
It solves very specific discrepancy occuring when following conditions are met : It solves very specific discrepancy occuring when following conditions are met :
A. the total makeup count (makeups_to_do + makeups_to_come) is more than 2 and std_counter = -2 A. the total makeup count (makeups_to_do + makeups_to_come) is more than |suspension_limit| and std_counter = suspension_limit
B. some action increments std_counter B. some action increments std_counter
In that case, the std_counter becomes -1 whereas we would like it to be -2. In that case, the std_counter becomes -1 whereas we would like it to be suspension_limit.
The idea behind the restriction to the [std_counter = -2] situation is that discrepancy The idea behind the restriction to the [std_counter = -2] situation is that discrepancy
is always due to the fact that we are adding more makeups to a member where std_counter = -2. is always due to the fact that we are adding more makeups to a member where std_counter = suspension_limit.
TODO : take into account historically corrupted data where there is discrepancy with std_counter = -1 TODO : take into account historically corrupted data where there is discrepancy with std_counter = -1
Below typical scenario where A and B are met (there are probably more than those two !) : Below typical scenario where A and B are met (there are probably more than those two !) :
...@@ -31,15 +31,16 @@ class ShiftCounterEvent(models.Model): ...@@ -31,15 +31,16 @@ class ShiftCounterEvent(models.Model):
to be use on ftop shift members. to be use on ftop shift members.
TODO : WARNING odoo openerp.models: shift.registration.read() with unknown field 'final_standard_point' : is it caused by this piece of code ? TODO : WARNING odoo openerp.models: shift.registration.read() with unknown field 'final_standard_point' : is it caused by this piece of code ?
TODO : understand difference in relative position of update_partner_target_status and actual value write in "CREATE" and "WRITE" methods below TODO : nderstand difference in relative position of update_partner_target_status and actual value write in "CREATE" and "WRITE" methods below
TODO : _update_partner_target_status looks similar to run_process_target_status... is it necessary to call run_process_target_status in update_members_makeups_core ? TODO : _update_partner_target_status looks similar to run_process_target_status... is it necessary to call run_process_target_status in update_members_makeups_core ?
Que faire si le type de service est "ftop" ?
""" """
try: try:
if vals['type'] == 'standard' and vals['point_qty'] > 0: if vals['type'] == 'standard' and vals['point_qty'] > 0:
res_partner = self.env['res.partner'].search([('id', '=', vals['partner_id'])])
if res_partner: if res_partner:
p = res_partner[0] p = res_partner[0]
if p.final_standard_point == -2 and p.shift_type != "ftop": if p.final_standard_point == suspension_limit and p.shift_type != "ftop":
_logger.info("Le nombre de points est la limite pour être suspendu, et membre ABCD, on va chercher à ajuster les points")
cond = [ cond = [
['name', '=', p["name"]], ['name', '=', p["name"]],
['shift_type', '=', 'standard'], ['shift_type', '=', 'standard'],
...@@ -53,43 +54,124 @@ class ShiftCounterEvent(models.Model): ...@@ -53,43 +54,124 @@ class ShiftCounterEvent(models.Model):
makeups_total_count = p['makeups_to_do'] + len(res_shift_reg) makeups_total_count = p['makeups_to_do'] + len(res_shift_reg)
if points_after_required_change + makeups_total_count > 0: if points_after_required_change + makeups_total_count > 0:
points_target = - makeups_total_count points_target = - makeups_total_count
if points_target < -2: if points_target < suspension_limit:
points_target = -2 points_target = suspension_limit
vals['point_qty'] = points_target - p.final_standard_point vals['point_qty'] = points_target - p.final_standard_point
except Exception as e: except Exception as e:
# don't block process if an error occurs here # don't block process if an error occurs here
_logger.error("Error during _alter_point_event_depending_on_makeups_total_count : %s", str(e)) _logger.error("Error during _alter_point_event_depending_on_makeups_total_count : %s", str(e))
return vals
@api.model
def unsubscribe_partner(self, partner, unsubscribe_limit, current_points):
result = None
try:
conf = self.env['ir.config_parameter']
makeups_todo_after_unsubscribed = conf.get_param("lacagette_membership.makeups_to_do_after_unsubscribed")
result = 'done'
new_values = {'makeups_to_do': makeups_todo_after_unsubscribed,
'working_state': 'unsubscribed', 'cooperative_state': 'unsubscribed'}
# Get points difference to set points to unsubscribe_limit - 1
_logger.info("unsubscribe_partner : current_points = %s", str(current_points))
target_points = unsubscribe_limit + 1
points_diff = abs(current_points - target_points)
if points_diff != 0:
if current_points > target_points:
points_update = - points_diff
else:
points_update = points_diff
data = {
'name': "Désinscription : passage à " + str(target_points) + " pts",
'shift_id': False,
'type': partner.shift_type,
'partner_id': partner.id,
'point_qty': points_update,
'note': 'no trigger'
}
self.env['shift.counter.event'].create(data)
"""
unlink model: "shift.template.registration"
to delete all future shifts linked to this coop.
"""
now = datetime.datetime.now().isoformat()
for streg in self.env['shift.template.registration'].search([('partner_id', '=', partner.id)]):
streg.unlink()
for sreg in self.env['shift.registration']\
.search([('partner_id', '=', partner.id),
('date_begin', '>', now)]):
sreg.unlink()
# Close extensions
for ext in self.env['shift.extension']\
.search([('partner_id', '=', partner.id),
('date_start', '<=', now),
('date_stop', '>=', now)]):
ext.update({'date_stop': now})
try:
mail_template = self.env.ref('coop_membership.unsubscribe_email')
if mail_template:
mail_template.send_mail(partner.id)
except Exception as e:
_logger.error("run_unsubscribe_process - send mail : %s - Process not interrupted", str(e))
partner.update(new_values)
except Exception as e:
_logger.error("run_unsubscribe_process : %s", str(e))
return None
return result
def _update_partner_target_status(self, vals): def _update_partner_target_status(self, vals):
"""actions when points are removed or added""" """actions when points are removed or added"""
partner = None
try: try:
conf = self.env['ir.config_parameter'] conf = self.env['ir.config_parameter']
suspension_limit = int(conf.get_param("lacagette_membership.points_limit_to_get_suspended")) suspension_limit = int(conf.get_param("lacagette_membership.points_limit_to_get_suspended"))
unsubscribe_limit = int(conf.get_param("lacagette_membership.points_limit_to_get_unsubscribed")) unsubscribe_limit = int(conf.get_param("lacagette_membership.points_limit_to_get_unsubscribed"))
if vals['point_qty'] != 0: if 'point_qty' in vals and vals['point_qty'] != 0:
res_partner = self.env['res.partner'].search([('id', '=', vals['partner_id'])]) res_partner = self.env['res.partner'].search([('id', '=', vals['partner_id'])])
# to_consider_vals = self._alter_point_event_depending_on_makeups_total_count(res_partner, vals, suspension_limit)
# _logger.info("to_consider_vals : %s", str(to_consider_vals))
to_consider_vals = vals # TODO : Reimplement this adjustments
if res_partner: if res_partner:
p = res_partner[0] partner = res_partner[0]
points_before_removing_points = p.final_ftop_point if p.shift_type == "ftop" else p.final_standard_point _logger.info("partner = : %s", str(partner))
points_after_removal = points_before_removing_points + vals['point_qty'] if to_consider_vals['type'] != partner.shift_type:
_logger.info("points_after_removal = %s, current_state = %s", str(points_after_removal), p.cooperative_state) _logger.error("Counter shift type is not corresponding to partner shift_type : %s", str(to_consider_vals))
if points_after_removal <= suspension_limit or points_after_removal <= unsubscribe_limit: return None
# Do not continue if method has been triggered by a 'no trigger' created shift_counter_event (while executing unsubscribe_partner)
if 'note' in to_consider_vals and to_consider_vals == 'no trigger':
return None
points_after_computation = partner.final_ftop_point if partner.shift_type == "ftop" else partner.final_standard_point
target_status = None
if points_after_computation <= suspension_limit or points_after_computation <= unsubscribe_limit:
target_status = None target_status = None
if (points_after_removal <= suspension_limit if (points_after_computation <= suspension_limit
and and
p.cooperative_state != 'delay'): partner.cooperative_state != 'delay'):
target_status = 'suspended' target_status = 'suspended'
if points_after_removal <= unsubscribe_limit: if points_after_computation <= unsubscribe_limit:
target_status = 'unsubscribed' target_status = 'unsubscribed'
elif points_after_computation < 0:
target_status = 'alert'
elif points_after_computation >= 0:
if partner.cooperative_state not in ['gone', 'associated', 'exempted', 'vacation']:
if partner.makeups_to_do == 0:
target_status = 'up_to_date'
else:
already_choosen_makeups_to_do = partner.get_makeups_choosen_shifts()
_logger.info("already_choosen_makeups_to_do : %s", str(already_choosen_makeups_to_do))
target_status = 'delay'
if target_status is not None: if target_status is not None:
p.update({'working_state': target_status, 'cooperative_state': target_status}) vals_for_update = {'working_state': target_status, 'cooperative_state': target_status}
# p.update({'target_status': target_status, if vals['point_qty'] < 0:
# 'current_cooperative_state': p.cooperative_state}) vals_for_update['makeups_to_do'] = partner.makeups_to_do + abs(vals['point_qty'])
elif points_after_removal >= 0: partner.update(vals_for_update)
p.update({'working_state': 'up_to_date', 'cooperative_state': 'up_to_date'}) if target_status == 'unsubscribed':
self.unsubscribe_partner(partner, unsubscribe_limit, points_after_computation)
except Exception as e: except Exception as e:
# don't block process if an error occurs here # don't block process if an error occurs here
_logger.error("Error during _update_partner_target_status : %s", str(e)) _logger.error("Error during _update_partner_target_status : %s", str(e))
...@@ -97,7 +179,6 @@ class ShiftCounterEvent(models.Model): ...@@ -97,7 +179,6 @@ class ShiftCounterEvent(models.Model):
@api.model @api.model
def write(self, vals): def write(self, vals):
self._alter_point_event_depending_on_makeups_total_count(vals)
res = super(ShiftCounterEvent, self).write(vals) res = super(ShiftCounterEvent, self).write(vals)
_logger.info("Vals recues = %s", str(vals)) _logger.info("Vals recues = %s", str(vals))
self._update_partner_target_status(vals) self._update_partner_target_status(vals)
...@@ -105,8 +186,8 @@ class ShiftCounterEvent(models.Model): ...@@ -105,8 +186,8 @@ class ShiftCounterEvent(models.Model):
@api.model @api.model
def create(self, vals): def create(self, vals):
self._alter_point_event_depending_on_makeups_total_count(vals)
self._update_partner_target_status(vals)
_logger.info("Vals recues creation = %s", str(vals)) _logger.info("Vals recues creation = %s", str(vals))
return super(ShiftCounterEvent, self).create(vals) res = super(ShiftCounterEvent, self).create(vals)
self._update_partner_target_status(vals)
return res
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