Skip to content

Commit

Permalink
[FIX] hr_timesheet_purchase_order: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dessanhemrayev committed Aug 3, 2023
1 parent 91a6ded commit e051a34
Show file tree
Hide file tree
Showing 8 changed files with 513 additions and 185 deletions.
1 change: 1 addition & 0 deletions hr_timesheet_purchase_order/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"external_dependencies": {},
"demo": [],
"data": [
"security/ir.model.access.csv",
"data/ir_actions_server.xml",
"data/hr_timesheet_cron.xml",
"views/hr_employee_view.xml",
Expand Down
2 changes: 1 addition & 1 deletion hr_timesheet_purchase_order/data/hr_timesheet_cron.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<odoo noupdate="1">
<record id="ir_cron_auto_generate_po" model="ir.cron">
<field name="name">HR Timesheet : Auto generate Purchase Order</field>
<field name="model_id" ref="hr.model_hr_employee" />
<field name="model_id" ref="model_hr_timesheet_recurrence" />
<field name="state">code</field>
<field name="code">model._cron_generate_auto_po()</field>
<field name="interval_type">days</field>
Expand Down
2 changes: 2 additions & 0 deletions hr_timesheet_purchase_order/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import hr_timesheet_recurrence
from . import hr_employee_base
from . import hr_employee
from . import hr_timesheet_sheet
from . import res_config_settings
from . import res_company
Expand Down
7 changes: 7 additions & 0 deletions hr_timesheet_purchase_order/models/hr_employee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from odoo import fields, models


class HR(models.Model):
_inherit = "hr.employee"

recurrence_id = fields.Many2one("hr.timesheet.recurrence", copy=False)
224 changes: 73 additions & 151 deletions hr_timesheet_purchase_order/models/hr_employee_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,11 @@
from datetime import timedelta

from dateutil.relativedelta import relativedelta
from dateutil.rrule import (
DAILY,
FR,
MO,
MONTHLY,
SA,
SU,
TH,
TU,
WE,
WEEKLY,
YEARLY,
rrule,
)
from dateutil.rrule import DAILY, MONTHLY, WEEKLY, YEARLY, rrule

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo import api, fields, models

MONTHS = {
"january": 31,
"february": 28,
"march": 31,
"april": 30,
"may": 31,
"june": 30,
"july": 31,
"august": 31,
"september": 30,
"october": 31,
"november": 30,
"december": 31,
}

DAYS = {
"mon": MO,
"tue": TU,
"wed": WE,
"thu": TH,
"fri": FR,
"sat": SA,
"sun": SU,
}

WEEKS = {
"first": 1,
"second": 2,
"third": 3,
"last": 4,
}
from .hr_timesheet_recurrence import DAYS, MONTHS


class HrEmployeeBase(models.AbstractModel):
Expand All @@ -64,13 +20,16 @@ class HrEmployeeBase(models.AbstractModel):
is_auto_po_generate = fields.Boolean(
string="Automatic PO generation", default=False
)
recurrence_id = fields.Many2one("hr.timesheet.recurrence", copy=False)

is_send_po = fields.Boolean(
string="Send RFQ by email after creation", default=False
)
next_recurrence_date = fields.Date()
recurrence_left = fields.Integer(string="Number of tasks left to create")
repeat_interval = fields.Integer(string="Repeat Every", default=1, readonly=False)

next_recurrence_date = fields.Date(related="recurrence_id.next_recurrence_date")
repeat_interval = fields.Integer(
string="Repeat Every", default=1, compute="_compute_repeat", readonly=False
)
repeat_unit = fields.Selection(
[
("day", "Days"),
Expand All @@ -79,6 +38,8 @@ class HrEmployeeBase(models.AbstractModel):
("year", "Years"),
],
default="week",
compute="_compute_repeat",
readonly=False,
)
repeat_type = fields.Selection(
[
Expand All @@ -88,16 +49,24 @@ class HrEmployeeBase(models.AbstractModel):
],
default="forever",
string="Until",
compute="_compute_repeat",
readonly=False,
)
repeat_until = fields.Date(
string="End Date", compute="_compute_repeat", readonly=False
)
repeat_number = fields.Integer(
string="Repetitions", default=1, compute="_compute_repeat", readonly=False
)
repeat_until = fields.Date(string="End Date", readonly=False)
repeat_number = fields.Integer(string="Repetitions", default=1, readonly=False)

repeat_on_month = fields.Selection(
[
("date", "Date of the Month"),
("day", "Day of the Month"),
],
default="date",
compute="_compute_repeat",
readonly=False,
)

repeat_on_year = fields.Selection(
Expand All @@ -106,18 +75,22 @@ class HrEmployeeBase(models.AbstractModel):
("day", "Day of the Year"),
],
default="date",
compute="_compute_repeat",
readonly=False,
)

mon = fields.Boolean(string="Mon", readonly=False)
tue = fields.Boolean(string="Tue", readonly=False)
wed = fields.Boolean(string="Wed", readonly=False)
thu = fields.Boolean(string="Thu", readonly=False)
fri = fields.Boolean(string="Fri", readonly=False)
sat = fields.Boolean(string="Sat", readonly=False)
sun = fields.Boolean(string="Sun", readonly=False)
mon = fields.Boolean(string="Mon", compute="_compute_repeat", readonly=False)
tue = fields.Boolean(string="Tue", compute="_compute_repeat", readonly=False)
wed = fields.Boolean(string="Wed", compute="_compute_repeat", readonly=False)
thu = fields.Boolean(string="Thu", compute="_compute_repeat", readonly=False)
fri = fields.Boolean(string="Fri", compute="_compute_repeat", readonly=False)
sat = fields.Boolean(string="Sat", compute="_compute_repeat", readonly=False)
sun = fields.Boolean(string="Sun", compute="_compute_repeat", readonly=False)

repeat_day = fields.Selection(
[(str(i), str(i)) for i in range(1, 32)],
compute="_compute_repeat",
readonly=False,
)
repeat_week = fields.Selection(
[
Expand All @@ -127,6 +100,8 @@ class HrEmployeeBase(models.AbstractModel):
("last", "Last"),
],
default="first",
compute="_compute_repeat",
readonly=False,
)
repeat_weekday = fields.Selection(
[
Expand All @@ -139,6 +114,8 @@ class HrEmployeeBase(models.AbstractModel):
("sun", "Sunday"),
],
string="Day Of The Week",
compute="_compute_repeat",
readonly=False,
)
repeat_month = fields.Selection(
[
Expand All @@ -155,6 +132,8 @@ class HrEmployeeBase(models.AbstractModel):
("november", "November"),
("december", "December"),
],
compute="_compute_repeat",
readonly=False,
)

repeat_show_dow = fields.Boolean(compute="_compute_repeat_visibility")
Expand Down Expand Up @@ -198,6 +177,20 @@ def _compute_repeat(self):
@api.model
def _get_recurrence_fields(self):
return [
"repeat_interval",
"repeat_unit",
"repeat_type",
"repeat_until",
"repeat_number",
"repeat_on_month",
"repeat_on_year",
"mon",
"tue",
"wed",
"thu",
"fri",
"sat",
"sun",
"repeat_day",
"repeat_week",
"repeat_month",
Expand Down Expand Up @@ -226,62 +219,6 @@ def default_get(self, default_fields):

return vals

@api.constrains("repeat_unit", "mon", "tue", "wed", "thu", "fri", "sat", "sun")
def _check_recurrence_days(self):
for timesheet in self.filtered(lambda p: p.repeat_unit == "week"):
if not any(
[
timesheet.mon,
timesheet.tue,
timesheet.wed,
timesheet.thu,
timesheet.fri,
timesheet.sat,
timesheet.sun,
]
):
raise ValidationError(_("You should select a least one day"))

def _check_next_recurrence_date(self):
for record in self.filtered(lambda t: t.is_auto_po_generate):
record._set_next_recurrence_date()

@api.constrains("repeat_interval")
def _check_repeat_interval(self):
if self.filtered(lambda t: t.repeat_interval <= 0 and t.is_auto_po_generate):
raise ValidationError(_("The interval should be greater than 0"))

@api.constrains("repeat_number", "repeat_type")
def _check_repeat_number(self):
if self.filtered(lambda t: t.repeat_type == "after" and t.repeat_number <= 0):
raise ValidationError(_("Should repeat at least once"))

@api.constrains("repeat_type", "repeat_until")
def _check_repeat_until_date(self):
today = fields.Date.today()
if self.filtered(lambda t: t.repeat_type == "until" and t.repeat_until < today):
raise ValidationError(_("The end date should be in the future"))

@api.constrains(
"repeat_unit", "repeat_on_month", "repeat_day", "repeat_type", "repeat_until"
)
def _check_repeat_until_month(self):
if self.filtered(
lambda r: r.repeat_type == "until"
and r.repeat_unit == "month"
and r.repeat_until
and r.repeat_on_month == "date"
and int(r.repeat_day) > r.repeat_until.day
and monthrange(r.repeat_until.year, r.repeat_until.month)[1]
!= r.repeat_until.day
):
raise ValidationError(
_(
"The end date should be after the day of "
"the month or the last day of the month"
)
)

def _set_next_recurrence_date(self):
today = fields.Date.today()
tomorrow = today + relativedelta(days=1)

Check warning on line 224 in hr_timesheet_purchase_order/models/hr_employee_base.py

View check run for this annotation

Codecov / codecov/patch

hr_timesheet_purchase_order/models/hr_employee_base.py#L223-L224

Added lines #L223 - L224 were not covered by tests
Expand Down Expand Up @@ -392,44 +329,29 @@ def _get_next_recurring_dates(
rules = rrule(**rrule_kwargs)
return list(rules) if rules else []

Check warning on line 330 in hr_timesheet_purchase_order/models/hr_employee_base.py

View check run for this annotation

Codecov / codecov/patch

hr_timesheet_purchase_order/models/hr_employee_base.py#L329-L330

Added lines #L329 - L330 were not covered by tests

def _create_purchase_order(self):
for item in self:
timesheet = item.timesheet_sheet_ids.filtered(
lambda t: not t.purchase_order_id and t.state == "done"
)
if not timesheet:
continue
timesheet = timesheet[0]
timesheet.action_create_purchase_order()
if item.is_send_po:
email_act = timesheet.purchase_order_id.action_rfq_send()
email_ctx = email_act.get("context", {})
timesheet.purchase_order_id.with_context(
**email_ctx
).message_post_with_template(email_ctx.get("default_template_id"))

@api.model
def _cron_generate_auto_po(self):
today = fields.Date.today()
recurring_today = self.search(
[("next_recurrence_date", "<=", today), ("is_auto_po_generate", "=", True)]
)
recurring_today._create_purchase_order()
for recurrence in recurring_today.filtered(lambda r: r.repeat_type == "after"):
recurrence.recurrence_left -= 1
recurring_today._set_next_recurrence_date()

def write(self, vals):
if vals.get("repeat_number"):
vals["recurrence_left"] = vals.get("repeat_number")
if "next_recurrence_date" not in vals:
self._check_next_recurrence_date()
rec_fields = vals.keys() & self._get_recurrence_fields()
if rec_fields:
rec_values = {rec_field: vals[rec_field] for rec_field in rec_fields}
for timesheet in self:
if timesheet.recurrence_id:
timesheet.recurrence_id.write(rec_values)
elif vals.get("is_auto_po_generate"):
rec_values["next_recurrence_date"] = fields.Datetime.today()
recurrence = self.env["hr.timesheet.recurrence"].create(rec_values)
timesheet.recurrence_id = recurrence.id

Check warning on line 342 in hr_timesheet_purchase_order/models/hr_employee_base.py

View check run for this annotation

Codecov / codecov/patch

hr_timesheet_purchase_order/models/hr_employee_base.py#L340-L342

Added lines #L340 - L342 were not covered by tests

if "is_auto_po_generate" in vals and not vals.get("is_auto_po_generate"):
self.recurrence_id.unlink()

return super().write(vals)

@api.model
def create(self, vals):
if vals.get("repeat_number"):
vals["recurrence_left"] = vals.get("repeat_number")
res = super().create(vals)
res.filtered(lambda x: x.is_auto_po_generate)._set_next_recurrence_date()
return res
rec_fields = vals.keys() & self._get_recurrence_fields()
if rec_fields and vals.get("is_auto_po_generate") is True:
rec_values = {rec_field: vals[rec_field] for rec_field in rec_fields}
rec_values["next_recurrence_date"] = fields.Datetime.today()
recurrence = self.env["hr.timesheet.recurrence"].create(rec_values)
vals["recurrence_id"] = recurrence.id
return super().create(vals)
Loading

0 comments on commit e051a34

Please sign in to comment.