Skip to content

Commit

Permalink
fieldservice_recurring: refactore stages
Browse files Browse the repository at this point in the history
Stages are now:
draft: not started yet
progress: orders are and will continue to be generated
suspend: it can continue to generate orders but it has been put on pause
for some reason
close: no new orders will / can be generated

```dot

digraph {
draft -> progress -> suspend -> close
suspend -> progress
}
```

Why this change ?

- it was impossible to go back to progress after cancel
- pending / renew is too opinated to be in a base module,
- renew duration was hardcoded

(btw renew can be implemented by a renew_date instead of a stage
in a dedicated module)
  • Loading branch information
hparfr authored and brian10048 committed Nov 13, 2023
1 parent 57742c5 commit 4aa5093
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 58 deletions.
2 changes: 1 addition & 1 deletion fieldservice_recurring/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{
"name": "Field Service Recurring Work Orders",
"summary": "Manage recurring Field Service orders",
"version": "16.0.1.0.1",
"version": "16.0.2.0.0",
"category": "Field Service",
"author": "Brian McMaster, "
"Open Source Integrators, "
Expand Down
7 changes: 7 additions & 0 deletions fieldservice_recurring/migrations/16.0.2.0.0/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (C) 2022 Raphaël Reverdy <raphael.reverdy@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).


def migrate(env, version):
env.execute("UPDATE fsm_recurring SET state = 'close' WHERE state = 'cancel';")
env.execute("UPDATE fsm_recurring SET state = 'progress' WHERE state = 'pending';")
42 changes: 10 additions & 32 deletions fieldservice_recurring/models/fsm_recurring.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ def _default_team_id(self):
[
("draft", "Draft"),
("progress", "In Progress"),
("pending", "To Renew"),
("suspend", "Suspended"),
("close", "Closed"),
("cancel", "Cancelled"),
],
readonly=True,
default="draft",
Expand Down Expand Up @@ -66,7 +65,7 @@ def _default_team_id(self):
help="This is the order template that will be recurring",
)
company_id = fields.Many2one(
"res.company", "Company", default=lambda self: self.env.company
"res.company", "Company", default=lambda self: self.env.user.company_id
)
fsm_order_ids = fields.One2many(
"fsm.order", "fsm_recurring_id", string="Orders", copy=False
Expand Down Expand Up @@ -135,15 +134,12 @@ def action_start(self):
rec.write({"state": "progress"})
rec._generate_orders()

def action_renew(self):
return self.action_start()

def action_cancel(self):
def action_suspend(self):
for order in self.fsm_order_ids.filtered(
lambda o: o.stage_id.is_closed is False
):
order.action_cancel()
return self.write({"state": "cancel"})
return self.write({"state": "suspend"})

def _get_rruleset(self):
self.ensure_one()
Expand Down Expand Up @@ -172,7 +168,7 @@ def _get_rruleset(self):
thru_date = request_thru_date
# use variables to calulate and return the rruleset object
ruleset = self.fsm_frequency_set_id._get_rruleset(
dtstart=next_date, until=thru_date, tz=self.location_id.tz
dtstart=next_date, until=thru_date
)
return ruleset

Expand Down Expand Up @@ -238,44 +234,26 @@ def _cron_generate_orders(self):
"""
return (
self.env["fsm.recurring"]
.search([("state", "in", ("progress", "pending"))])
.search([("state", "=", "progress")])
._generate_orders()
)

@api.model
def _cron_manage_expiration(self):
"""
Executed by Cron task to put all 'pending' recurring orders into
Executed by Cron task to put all 'in progress' recurring orders into
'close' stage if it is after their end date or the max orders have
been generated. Next, the 'progress' recurring orders are put in
'pending' stage by first checking if the end date is within the next
30 days and then checking if the max number of orders will be created
within the next 30 days
been generated.
"""
to_close = self.env["fsm.recurring"]
pending_rec = self.env["fsm.recurring"].search([("state", "=", "pending")])
for rec in pending_rec:
open_rec = self.env["fsm.recurring"].search([("state", "=", "progress")])
for rec in open_rec:
if rec.end_date and rec.end_date <= datetime.today():
to_close += rec
continue
if rec.max_orders > 0 and rec.fsm_order_count >= rec.max_orders:
to_close += rec
to_close.write({"state": "close"})
to_renew = self.env["fsm.recurring"]
expire_date = datetime.today() + relativedelta(days=+30)
open_rec = self.env["fsm.recurring"].search([("state", "=", "progress")])
for rec in open_rec:
if rec.end_date and rec.end_date <= expire_date:
to_renew += rec
continue
if rec.max_orders > 0:
orders_in_30 = rec.fsm_order_count
orders_in_30 += rec.fsm_frequency_set_id._get_rruleset(
until=expire_date, tz=rec.location_id.tz
).count()
if orders_in_30 >= rec.max_orders:
to_renew += rec
to_renew.write({"state": "pending"})

@api.model
def _cron_scheduled_task(self):
Expand Down
2 changes: 0 additions & 2 deletions fieldservice_recurring/tests/test_fsm_recurring.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ def test_cron_generate_orders_rule1(self):
)
recurring.action_start()
test_recurring.action_start()
test_recurring.action_renew()
# Run schedule job now, to compute the future work orders
recurring._cron_scheduled_task()
recurring.onchange_recurring_template_id()
Expand Down Expand Up @@ -295,4 +294,3 @@ def test_fsm_order(self):
fsm_order = self.env["fsm.order"].create(order_vals)
self.env["fsm.order"].create(order_vals2)
fsm_order.action_view_fsm_recurring()
recurring.action_cancel()
32 changes: 9 additions & 23 deletions fieldservice_recurring/views/fsm_recurring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,19 @@
<button
id="action_start"
name="action_start"
string="Confirm"
string="Start"
class="oe_highlight"
type="object"
groups="fieldservice.group_fsm_dispatcher"
attrs="{'invisible': [('state', '!=', 'draft')]}"
attrs="{'invisible': [('state', 'in',('close', 'progress'))]}"
/>
<button
id="action_renew"
name="action_renew"
string="Renew"
class="oe_highlight"
id="action_suspend"
name="action_suspend"
string="Suspend"
type="object"
groups="fieldservice.group_fsm_dispatcher"
attrs="{'invisible': [('state', '!=', 'pending')]}"
/>
<button
id="action_cancel"
name="action_cancel"
string="Cancel"
type="object"
groups="fieldservice.group_fsm_dispatcher"
attrs="{'invisible': [('state', 'in', ('close', 'cancel'))]}"
attrs="{'invisible': [('state', 'in', ('draft', 'close'))]}"
/>
<field name="state" widget="statusbar" />
</header>
Expand Down Expand Up @@ -142,20 +133,15 @@
domain="[('state', '=', 'progress')]"
name="progress"
/>
<filter
string="To Renew"
domain="[('state', '=', 'pending')]"
name="renew"
/>
<filter
string="Closed"
domain="[('state', '=', 'close')]"
name="closed"
/>
<filter
string="Cancelled"
domain="[('state', '=', 'cancel')]"
name="cancelled"
string="Suspended"
domain="[('state', '=', 'suspend')]"
name="suspended"
/>
<separator />
<group expand="0" string="Group By">
Expand Down

0 comments on commit 4aa5093

Please sign in to comment.