Skip to content

[16.0] [ADD] volunteer_holiday#578

Draft
Genepi314 wants to merge 19 commits into16.0from
16.0-add-volunteer_holiday
Draft

[16.0] [ADD] volunteer_holiday#578
Genepi314 wants to merge 19 commits into16.0from
16.0-add-volunteer_holiday

Conversation

@Genepi314
Copy link

Description

Add holidays for companies and leaves for volunteers.

Odoo task (if applicable)

Checklist before approval

  • Tests are present (or not needed).
  • Credits/copyright have been changed correctly.
  • Change log snippet is present.
  • (If a new module) Moving this to OCA has been considered.

@remytms remytms changed the title 16.0 add volunteer holiday [16.0] [ADD] volunteer_holiday Mar 2, 2026
Comment on lines +100 to +114
if (
(
shift_start_date >= holiday_start_date
and shift_start_date <= holiday_end_date
)
or (
shift_end_date >= holiday_start_date
and shift_start_date <= holiday_end_date
)
or (
shift_start_date <= holiday_start_date
and shift_end_date >= holiday_end_date
)
):
return True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply write:

Suggested change
if (
(
shift_start_date >= holiday_start_date
and shift_start_date <= holiday_end_date
)
or (
shift_end_date >= holiday_start_date
and shift_start_date <= holiday_end_date
)
or (
shift_start_date <= holiday_start_date
and shift_end_date >= holiday_end_date
)
):
return True
return (
(
shift_start_date >= holiday_start_date
and shift_start_date <= holiday_end_date
)
or (
shift_end_date >= holiday_start_date
and shift_start_date <= holiday_end_date
)
or (
shift_start_date <= holiday_start_date
and shift_end_date >= holiday_end_date
)
)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I didn't know about this simplified syntax. It is done.

Copy link
Collaborator

@remytms remytms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First partial review.

@@ -0,0 +1 @@
from . import controllers
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should remove the controllers directory if your have nothing more than the __init__.py file in it.

Comment on lines +8 to +18
<!-- Après test, passer en noupdate=1 -->
<record id="ir_cron_cancel_holiday_shift" model="ir.cron">
<field name="name">Cancel Generated Shifts During Company Holidays</field>
<field name="model_id" ref="model_volunteer_company_holiday" />
<field name="state">code</field>
<field name="code">model._cancel_holiday_shift()</field>
<field name="interval_number">24</field>
<field name="interval_type">hours</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False" />
</record>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apply your comment here. :)

<field name="name">Christmas Holidays</field>
<field
name="start_date"
eval="(datetime.today().replace(month=12, day=24)).strftime('%Y-%m-%d')"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Starting with python 3.9 (odoo 16.0 uses 3.10), prefer using isformat() instead of strftime for standard iso formatting.

See method here.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some tests on these cases, neither strftime() nor isoformat() seems to be required. On my side, loading works fine without any formatting. That said, I'm not sure of all the details behind it.

/>
<field
name="end_date"
eval="(datetime.today().replace(month=12, day=25)).strftime('%Y-%m-%d')"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isoformat()

<field name="name">Store Inventory</field>
<field
name="start_date"
eval="(datetime.today().replace(month=7, day=1)).strftime('%Y-%m-%d')"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isoformat

Comment on lines +34 to +35
# Retirer la limite de temps, regarder les shifts futurs
def _cancel_holiday_shift(self, time_in_months=3):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you should apply your comment, and remove the time limit. Just check all shifts, and see if they are overlapping a holiday.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that for now it’s ok if the method starts at now() and all future shifts.

Because, we don’t want to change the past.

Comment on lines +68 to +71
# Create dictionary key-company for list of values-shifts
shifts_by_company = {}
for shift in confirmed_future_generated_shifts_in_range:
shifts_by_company.setdefault(shift.company_id, []).append(shift)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just order them by company_id when using the search() method.

Also, as there is less holiday than shifts, it’s better to do so with holiday, or even fetch holiday for the company when needed.

Comment on lines +73 to +88
for holiday in future_company_holidays_in_range:
same_company_shifts = shifts_by_company.get(holiday.company_id, [])
for shift in same_company_shifts:
if shift.state != "canceled" and self._shift_covers_holiday(
shift.start_time,
shift.end_time,
holiday.start_date,
holiday.end_date,
):
shift.sudo().write(
{
"stage_id": self.env.ref(
"volunteer.volunteer_shift_stage_canceled"
).id
}
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If your shifts are ordered by company_id, you can use itertools.groupby() to iterate through all the shifts, company by company. Then you can fetch the holiday of the comany, each time you face a new company.

Using itertools.groupby() is more efficient for such a task.

volunteer_leave_ids = fields.One2many(
comodel_name="volunteer.volunteer.leave",
inverse_name="volunteer_id",
string="Leave",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here for the user interface you can use plural form.

Suggested change
string="Leave",
string="Leaves",

class VolunteerVolunteerLeave(models.Model):
_name = "volunteer.volunteer.leave"
_description = "Volunteer Leave"
_order = "start_date"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_order = "start_date"
_order = "start_date desc, volunteer_id, id"

Same as for company.holiday.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants