Skip to content

Commit

Permalink
Merge pull request #140 from coopiteasy/9.0-a13-available-bikes
Browse files Browse the repository at this point in the history
[9.0] add available resource category tab on activities
  • Loading branch information
Houssine BAKKALI authored Jan 19, 2021
2 parents 0f5f630 + 903087d commit dfb28ae
Show file tree
Hide file tree
Showing 16 changed files with 396 additions and 4 deletions.
3 changes: 2 additions & 1 deletion resource_activity/__openerp__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
##############################################################################
{
"name": "Resource activity",
"version": "1.0",
"version": "9.0.1.0.1",
"depends": [
"base",
"mail",
Expand Down Expand Up @@ -60,6 +60,7 @@
"reports/layouts.xml",
"views/menus.xml",
],
"demo": ["demo/demo.xml",],
"installable": True,
"application": True,
}
12 changes: 12 additions & 0 deletions resource_activity/data/cron.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,17 @@
<field name="args">()</field>
<field name="active" eval="False"/>
</record>

<record id="ir_cron_garbage_collect_available_categories" model="ir.cron">
<field name="name">Garbage Collect Available Categories</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="True"/>
<field name="model">resource.category.available</field>
<field name="function">garbage_collect</field>
<field name="args">()</field>
<field name="active" eval="True"/>
</record>
</data>
</odoo>
3 changes: 3 additions & 0 deletions resource_activity/data/resource_activity_data.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">

<!-- todo give multi location right to admin -->

<record id="sequence_resource_activity" model="ir.sequence">
<field name="name">Resource activity</field>
<field name="code">resource.activity</field>
Expand Down
16 changes: 16 additions & 0 deletions resource_activity/demo/demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 Coop IT Easy
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="resource_activity_type_tour_demo" model="resource.activity.type">
<field name="name">Tour</field>
</record>
<record id="base.user_root" model="res.users">
<field name="resource_location" ref="resource_planning.main_location"/>
</record>
<record id="base.user_demo" model="res.users">
<field name="resource_location" ref="resource_planning.main_location"/>
</record>
</odoo>
66 changes: 65 additions & 1 deletion resource_activity/models/resource_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,30 @@ class ResourceActivityLang(models.Model):
active = fields.Boolean("Active", default=True)


class ResourceCategoryAvailable(models.Model):
_name = "resource.category.available"
activity_id = fields.Many2one(
comodel_name="resource.activity", string="Activity"
)
category_id = fields.Many2one(
comodel_name="resource.category", string="Category", required=True
)
nb_resources = fields.Integer(string="Number of resources")

@api.model
def garbage_collect(self):
"""cleanup resource category available for past activities"""
a_week_ago = datetime.now() - timedelta(days=7)
a_week_ago_str = fields.Datetime.to_string(a_week_ago)
self.search(
[
"|",
("activity_id", "=", False),
("activity_id.date_start", "<=", a_week_ago_str),
]
).unlink()


class ResourceActivity(models.Model):
_name = "resource.activity"
_inherit = ["mail.thread"]
Expand Down Expand Up @@ -310,9 +334,49 @@ def _default_location(self):
string="Activity end is outside opening hours",
compute="_compute_outside_opening_hours",
)
available_category_ids = fields.One2many(
comodel_name="resource.category.available",
inverse_name="activity_id",
string="Available Bikes Per Category",
compute="_compute_available_categories",
store=True,
)

@api.multi
@api.depends("date_end", "date_start")
@api.depends(
"date_start", "date_end", "location_id", "registrations.state"
)
def _compute_available_categories(self):
for activity in self:
activity.available_category_ids = [(5, 0, 0)] # reset field
if (
activity.date_start
and activity.date_end
and activity.location_id
):
available_categories = self.env[
"resource.category"
].get_available_categories(
date_start=activity.date_start,
date_end=activity.date_end,
location=activity.location_id,
)
update_values = [
(
0,
0,
{
"activity_id": activity.id,
"category_id": category_id,
"nb_resources": nb_resources,
},
)
for category_id, nb_resources in available_categories.items()
]
activity.available_category_ids = update_values

@api.multi
@api.depends("date_end", "date_start", "location_id")
def _compute_outside_opening_hours(self):
opening_hours = self.env["activity.opening.hours"]
for activity in self:
Expand Down
1 change: 1 addition & 0 deletions resource_activity/security/ir.model.access.csv
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ access_resource_available_user,resource.available user,resource_activity.model_r
access_resource_available_manager,resource.available manager,resource_activity.model_resource_available,resource_planning.group_resource_manager,1,1,1,1
access_resource_activity_type_user,resource.activity.type user,resource_activity.model_resource_activity_type,resource_planning.group_resource_user,1,1,1,0
access_resource_activity_type_manager,resource.activity.type manager,resource_activity.model_resource_activity_type,resource_planning.group_resource_manager,1,1,1,0
access_resource_category_available_user,access_resource_category_available_user,model_resource_category_available,base.group_user,1,1,1,1
access_resource_activity_lang_user,resource.activity.lang user,resource_activity.model_resource_activity_lang,resource_planning.group_resource_user,1,1,1,0
access_resource_activity_lang_manager,resource.activity.lang manager,resource_activity.model_resource_activity_lang,resource_planning.group_resource_manager,1,1,1,0
access_resource_activity_theme_user,resource.activity.theme user,resource_activity.model_resource_activity_theme,resource_planning.group_resource_user,1,1,1,0
Expand Down
1 change: 1 addition & 0 deletions resource_activity/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import test_opening_hours
from . import test_resource_activity
69 changes: 69 additions & 0 deletions resource_activity/tests/test_resource_activity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright 2020 Coop IT Easy SCRL fs
# Robin Keunen <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).


from openerp.tests import common


class TestResourceActivity(common.TransactionCase):
def setUp(self):
super(TestResourceActivity, self).setUp()
self.main_location = self.browse_ref("resource_planning.main_location")
self.activity_type = self.browse_ref(
"resource_activity.resource_activity_type_tour_demo"
)

def test_compute_available_resources(self):
activity_obj = self.env["resource.activity"]
activity = activity_obj.create(
{
"date_start": "2020-11-23 14:30",
"date_end": "2020-11-23 16:00",
"location_id": self.main_location.id,
"activity_type": self.activity_type.id,
}
)
self.assertEquals(len(activity.available_category_ids), 0)

activity = activity_obj.create(
{
"date_start": "2020-11-23 19:30",
"date_end": "2020-11-23 20:00",
"location_id": self.main_location.id,
"activity_type": self.activity_type.id,
}
)
categories = {
av_categ.category_id.id: av_categ.nb_resources
for av_categ in activity.available_category_ids
}
self.assertEquals({1: 1, 2: 1}, categories)

activity = activity_obj.create(
{
"date_start": "2020-11-23 17:00",
"date_end": "2020-11-23 17:30",
"location_id": self.main_location.id,
"activity_type": self.activity_type.id,
}
)
categories = {
av_categ.category_id.id: av_categ.nb_resources
for av_categ in activity.available_category_ids
}
self.assertEquals({1: 2}, categories)

activity = activity_obj.create(
{
"date_start": "2020-11-24 19:30",
"date_end": "2020-11-24 20:00",
"location_id": self.main_location.id,
"activity_type": self.activity_type.id,
}
)
categories = {
av_categ.category_id.id: av_categ.nb_resources
for av_categ in activity.available_category_ids
}
self.assertEquals({1: 2, 2: 1}, categories)
9 changes: 9 additions & 0 deletions resource_activity/views/resource_activity_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,15 @@
<page name="booked_resources" string="Booked resources">
<field name="booked_resources"/>
</page>
<page name="available_resources" string="Available resources">
<field name="available_category_ids">
<tree>
<field name="category_id"/>
<!-- type="char" allows to align left the nb_resource column-->
<field name="nb_resources" type="char"/>
</tree>
</field>
</page>
<page name="sale_orders" string="Sale orders"
attrs="{'invisible':[('sale_orders','=',False)]}">
<field name="sale_orders">
Expand Down
3 changes: 2 additions & 1 deletion resource_planning/__openerp__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
##############################################################################
{
"name": "Resource Planning",
"version": "1.0",
"version": "9.0.1.0.1",
"depends": ["base", "mail", "resource", "web_gantt8",],
"author": "Houssine BAKKALI <[email protected]>",
"category": "Resource",
Expand All @@ -43,6 +43,7 @@
"views/actions.xml",
"views/menus.xml",
],
"demo": ["demo/demo.xml",],
"installable": True,
"application": True,
}
85 changes: 85 additions & 0 deletions resource_planning/demo/demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 Coop IT Easy
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="resource_category_bike_demo" model="resource.category">
<field name="name">Bike</field>
</record>
<record id="resource_category_ebike_demo" model="resource.category">
<field name="name">E-Bike</field>
</record>

<record id="resource_resource_bike_1_demo" model="resource.resource">
<field name="name">Bike 1</field>
<field name="serial_number">BK1</field>
<field name="state">available</field>
<field name="category_id" ref="resource_category_bike_demo"/>
<field name="location" ref="main_location"/>
</record>
<record id="resource_resource_bike_2_demo" model="resource.resource">
<field name="name">Bike 2</field>
<field name="serial_number">BK2</field>
<field name="state">available</field>
<field name="category_id" ref="resource_category_bike_demo"/>
<field name="location" ref="main_location"/>
</record>
<record id="resource_resource_ebike_1_demo" model="resource.resource">
<field name="name">E-Bike 1</field>
<field name="serial_number">EBK1</field>
<field name="state">available</field>
<field name="category_id" ref="resource_category_ebike_demo"/>
<field name="location" ref="main_location"/>
</record>
<record id="resource_resource_ebike_2_demo" model="resource.resource">
<field name="name">E-Bike 2</field>
<field name="serial_number">EBK2</field>
<field name="state">unavailable</field>
<field name="category_id" ref="resource_category_ebike_demo"/>
<field name="location" ref="main_location"/>
</record>

<record id="resource_allocation_1_demo" model="resource.allocation">
<field name="resource_id" ref="resource_resource_bike_1_demo"/>
<field name="date_start">2020-11-23 14:00</field>
<field name="date_end">2020-11-23 16:00</field>
<field name="state">booked</field>
<field name="location" ref="main_location"/>
</record>
<record id="resource_allocation_2_demo" model="resource.allocation">
<field name="resource_id" ref="resource_resource_bike_1_demo"/>
<field name="date_start">2020-11-23 18:00</field>
<field name="date_end">2020-11-23 20:00</field>
<field name="state">booked</field>
<field name="location" ref="main_location"/>
</record>
<record id="resource_allocation_3_demo" model="resource.allocation">
<field name="resource_id" ref="resource_resource_bike_2_demo"/>
<field name="date_start">2020-11-23 10:00</field>
<field name="date_end">2020-11-23 15:00</field>
<field name="state">booked</field>
<field name="location" ref="main_location"/>
</record>
<record id="resource_allocation_4_demo" model="resource.allocation">
<field name="resource_id" ref="resource_resource_bike_2_demo"/>
<field name="date_start">2020-11-23 19:00</field>
<field name="date_end">2020-11-23 20:00</field>
<field name="state">cancel</field>
<field name="location" ref="main_location"/>
</record>
<record id="resource_allocation_5_demo" model="resource.allocation">
<field name="resource_id" ref="resource_resource_ebike_1_demo"/>
<field name="date_start">2020-11-23 17:00</field>
<field name="date_end">2020-11-23 18:30</field>
<field name="state">booked</field>
<field name="location" ref="main_location"/>
</record>
<record id="resource_allocation_6_demo" model="resource.allocation">
<field name="resource_id" ref="resource_resource_ebike_1_demo"/>
<field name="date_start">2020-11-23 14:00</field>
<field name="date_end">2020-11-23 16:00</field>
<field name="state">booked</field>
<field name="location" ref="main_location"/>
</record>
</odoo>
1 change: 1 addition & 0 deletions resource_planning/models/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def check_dates(self, date_start, date_end):

@api.multi
def check_availabilities(self, date_start, date_end, location):
# todo refactor, use resource.allocation.get_allocations
self.check_dates(date_start, date_end)
available_resources = self.filtered(lambda r: r.state == "available")
if location:
Expand Down
13 changes: 13 additions & 0 deletions resource_planning/models/resource_allocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,16 @@ def action_cancel(self):
def action_option(self):
for allocation in self:
allocation.state = "option"

@api.model
def get_allocations(self, date_start, date_end, location):
return self.env["resource.allocation"].search(
[
("location", "=", location.id),
("state", "!=", "cancel"),
"!",
"|",
("date_end", "<=", date_start),
("date_start", ">=", date_end),
]
)
Loading

0 comments on commit dfb28ae

Please sign in to comment.