Pack de réservations #17
19
golem_resource_pack/__init__.py
Normal file
19
golem_resource_pack/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import models, wizard
|
33
golem_resource_pack/__manifest__.py
Normal file
33
golem_resource_pack/__manifest__.py
Normal file
@ -0,0 +1,33 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
{
|
||||
'name': 'GOLEM resources pack',
|
||||
'summary': 'GOLEM resources pack',
|
||||
'description': ''' GOLEM resources pack ''',
|
||||
'version': '10.0.0.0.4',
|
||||
'category': 'GOLEM',
|
||||
'author': 'Youssef El Ouahby, Fabien Bourgeois',
|
||||
'license': 'AGPL-3',
|
||||
'application': True,
|
||||
'installable': True,
|
||||
'depends': ['golem_resource'],
|
||||
'data': ['views/golem_resource_pack_views.xml',
|
||||
'wizard/golem_pack_rejection_views.xml',
|
||||
'security/ir.model.access.csv']
|
||||
}
|
20
golem_resource_pack/models/__init__.py
Normal file
20
golem_resource_pack/models/__init__.py
Normal file
@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import golem_resource_pack, \
|
||||
golem_resource_reservation
|
138
golem_resource_pack/models/golem_resource_pack.py
Normal file
138
golem_resource_pack/models/golem_resource_pack.py
Normal file
@ -0,0 +1,138 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
""" GOLEM Resource Packs """
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class GolemResourcePack(models.Model):
|
||||
""" GOLEM Resource Pack Model """
|
||||
_name = 'golem.resource.pack'
|
||||
_description = 'GOLEM Resource Pack Model'
|
||||
_inherit = 'mail.thread'
|
||||
|
||||
name = fields.Char(compute='_compute_name', store=True)
|
||||
reservation_ids = fields.One2many('golem.resource.reservation', 'pack_id',
|
||||
readonly=True, track_visibility='onchange',
|
||||
states={'draft': [('readonly', False)],
|
||||
False : [('readonly', False)]})
|
||||
|
||||
note = fields.Text(help='Notes, optional subject for the reservation, reason',
|
||||
track_visibility='onchange', readonly=True,
|
||||
states={'draft': [('readonly', False)],
|
||||
False : [('readonly', False)]})
|
||||
|
||||
user_id = fields.Many2one('res.users', required=True, index=True, readonly=True,
|
||||
string='User', default=lambda self: self.env.user)
|
||||
partner_id = fields.Many2one('res.partner', string='On behalf of', required=True,
|
||||
index=True, track_visibility='onchange', readonly=True,
|
||||
states={'draft': [('readonly', False)],
|
||||
False : [('readonly', False)]})
|
||||
state = fields.Selection([('canceled', 'Canceled'),
|
||||
('draft', 'Draft'),
|
||||
('confirmed', 'Confirmed'),
|
||||
('validated', 'Validated'),
|
||||
('rejected', 'Rejected')],
|
||||
default='draft', compute="_compute_pack_state",
|
||||
track_visibility='onchange')
|
||||
reservation_count = fields.Integer(compute="_compute_reservation_count",
|
||||
string="Reservation count")
|
||||
rejection_reason = fields.Text(readonly=True, track_visibility='onchange')
|
||||
|
||||
@api.multi
|
||||
@api.constrains('partner_id')
|
||||
def set_reservation_partner(self):
|
||||
""" Set reservation partner """
|
||||
for pack in self:
|
||||
pack.reservation_ids.write({'partner_id': pack.partner_id.id})
|
||||
|
||||
@api.multi
|
||||
@api.depends('reservation_ids')
|
||||
def _compute_reservation_count(self):
|
||||
for pack in self:
|
||||
pack.reservation_count = len(pack.reservation_ids)
|
||||
|
||||
@api.multi
|
||||
def state_confirm(self):
|
||||
""" pack confirm """
|
||||
for pack in self:
|
||||
pack.reservation_ids.state_confirm()
|
||||
|
||||
@api.multi
|
||||
def state_draft(self):
|
||||
""" pack canceled """
|
||||
for pack in self:
|
||||
pack.reservation_ids.state_draft()
|
||||
|
||||
@api.multi
|
||||
def state_canceled(self):
|
||||
""" pack canceled """
|
||||
for pack in self:
|
||||
pack.reservation_ids.state_canceled()
|
||||
|
||||
@api.multi
|
||||
def state_validated(self):
|
||||
""" pack validated """
|
||||
for pack in self:
|
||||
pack.reservation_ids.state_validated()
|
||||
|
||||
@api.multi
|
||||
def state_rejected(self):
|
||||
""" Wizard call for pack reject """
|
||||
self.ensure_one()
|
||||
pack_id = self[0]
|
||||
return {'name' : _('Please enter the rejection reason'),
|
||||
'type' : 'ir.actions.act_window',
|
||||
'res_model' : 'golem.pack.rejection.wizard',
|
||||
'context': {'default_pack_id': pack_id.id},
|
||||
'view_mode': 'form',
|
||||
'target': 'new'}
|
||||
|
||||
|
||||
@api.depends('partner_id')
|
||||
def _compute_name(self):
|
||||
""" Compute pack name """
|
||||
for pack in self:
|
||||
pack.name = u'{}/{}'.format(pack.partner_id.name,
|
||||
pack.create_date)
|
||||
@api.multi
|
||||
@api.constrains('reservation_ids')
|
||||
def check_reservation_partner(self):
|
||||
""" Check reservation partner """
|
||||
for pack in self:
|
||||
if len(filter(lambda x: x.partner_id == pack.partner_id, pack.reservation_ids)) < len(pack.reservation_ids):
|
||||
raise ValidationError(_('Pack client should be the same for all reservations'))
|
||||
|
||||
@api.multi
|
||||
@api.depends('reservation_ids')
|
||||
def _compute_pack_state(self):
|
||||
""" get pack state """
|
||||
for pack in self:
|
||||
reservation_states = list(map(lambda x: x.state, pack.reservation_ids))
|
||||
if "rejected" in reservation_states:
|
||||
pack.state = 'rejected'
|
||||
elif "canceled" in reservation_states:
|
||||
pack.state = 'canceled'
|
||||
elif "draft" in reservation_states:
|
||||
pack.state = 'draft'
|
||||
elif "confirmed" in reservation_states:
|
||||
pack.state = 'confirmed'
|
||||
elif "validated" in reservation_states:
|
||||
pack.state = 'validated'
|
28
golem_resource_pack/models/golem_resource_reservation.py
Normal file
28
golem_resource_pack/models/golem_resource_reservation.py
Normal file
@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
""" GOLEM Resource Reservation """
|
||||
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class GolemResourceReservation(models.Model):
|
||||
""" GOLEM Resource Reservation Model """
|
||||
_inherit = 'golem.resource.reservation'
|
||||
|
||||
pack_id = fields.Many2one('golem_resource_reservation', 'Reservation Pack')
|
3
golem_resource_pack/security/ir.model.access.csv
Normal file
3
golem_resource_pack/security/ir.model.access.csv
Normal file
@ -0,0 +1,3 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_golem_resource_pack_user,Access GOLEM Resource Pack User,model_golem_resource_pack,golem_base.group_golem_user,1,0,0,0
|
||||
access_golem_resource_pack_manager,Access GOLEM Resource Pack Manager,model_golem_resource_pack,golem_base.group_golem_manager,1,1,1,1
|
|
19
golem_resource_pack/tests/__init__.py
Normal file
19
golem_resource_pack/tests/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import test_golem_resource_pack
|
144
golem_resource_pack/tests/test_golem_resource_pack.py
Normal file
144
golem_resource_pack/tests/test_golem_resource_pack.py
Normal file
@ -0,0 +1,144 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
""" GOLEM Resource Pack testing """
|
||||
|
||||
import logging
|
||||
from odoo.tests.common import TransactionCase
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestGolemResourcePack(TransactionCase):
|
||||
""" GOLEM Resource Reservation testing """
|
||||
|
||||
def setUp(self, *args, **kwargs):
|
||||
""" Bootstrap Resource Reservation """
|
||||
super(TestGolemResourcePack, self).setUp(*args, **kwargs)
|
||||
|
||||
self.resource = self.env['golem.resource'].create({
|
||||
'name': 'Resource',
|
||||
'avaibility_start': '2018-01-01',
|
||||
'avaibility_stop': '2020-01-01',
|
||||
'availibility_24_7': True
|
||||
})
|
||||
self.resource_val = self.env['golem.resource'].create({
|
||||
'name': 'Resource to validate',
|
||||
'avaibility_start': '2018-01-01',
|
||||
'avaibility_stop': '2020-01-01',
|
||||
'validation_required': True,
|
||||
'availibility_24_7': True
|
||||
})
|
||||
|
||||
self.partner = self.env['res.partner'].create({'firstname': 'John',
|
||||
'lastname': 'DOE',
|
||||
'is_company': False})
|
||||
|
||||
reservation_obj = self.env['golem.resource.reservation']
|
||||
self.reservation_1 = reservation_obj.create({
|
||||
'resource_id': self.resource.id,
|
||||
'date_start': '2018-02-05 11:00:00',
|
||||
'date_stop': '2018-02-05 12:00:00',
|
||||
'partner_id': self.partner.id
|
||||
})
|
||||
self.reservation_2 = reservation_obj.create({
|
||||
'resource_id': self.resource.id,
|
||||
'date_start': '2018-02-06 11:00:00',
|
||||
'date_stop': '2018-02-06 12:00:00',
|
||||
'partner_id': self.partner.id
|
||||
})
|
||||
self.reservation_3 = reservation_obj.create({
|
||||
'resource_id': self.resource_val.id,
|
||||
'date_start': '2018-02-05 11:00:00', # is monday
|
||||
'date_stop': '2018-02-05 12:00:00',
|
||||
'partner_id': self.partner.id
|
||||
})
|
||||
self.pack_obj = self.env['golem.resource.pack']
|
||||
self.pack_data = {
|
||||
'partner_id': self.partner.id
|
||||
}
|
||||
|
||||
|
||||
def test_pack_basic(self):
|
||||
""" Test pack bases """
|
||||
pack = self.pack_obj.create(self.pack_data)
|
||||
self.assertFalse(pack.reservation_ids)
|
||||
self.assertFalse(self.reservation_1.pack_id)
|
||||
pack.reservation_ids = [(4, self.reservation_1.id, 0),
|
||||
(4, self.reservation_2.id, 0)]
|
||||
self.assertEqual(pack.reservation_ids[0].state, "draft")
|
||||
self.assertEqual(self.reservation_1.pack_id.id, pack.id)
|
||||
self.assertEqual(pack.state, "draft")
|
||||
self.assertEqual(pack.reservation_count, 2)
|
||||
#confirm pack ==> all validated
|
||||
pack.state_confirm()#no validation required
|
||||
self.assertEqual(pack.reservation_ids[0].state, "validated")
|
||||
self.assertEqual(pack.state, "validated")
|
||||
#pack draft ==> all draft
|
||||
pack.state_draft()
|
||||
self.assertEqual(pack.reservation_ids[0].state, "draft")
|
||||
self.assertEqual(pack.state, "draft")
|
||||
# confirm pack and draft reservation ==> pack draft
|
||||
pack.state_confirm()
|
||||
pack.reservation_ids[0].state_draft()
|
||||
self.assertEqual(pack.reservation_ids[0].state, "draft")
|
||||
self.assertEqual(pack.state, "draft")
|
||||
#confirm reservation ==> pack validated
|
||||
pack.reservation_ids[0].state_confirm()
|
||||
self.assertEqual(pack.reservation_ids[0].state, "validated")
|
||||
self.assertEqual(pack.state, "validated")
|
||||
pack.reservation_ids = [(5, 0, 0)]
|
||||
self.assertFalse(pack.reservation_ids)
|
||||
self.assertEqual(pack.reservation_count, 0)
|
||||
|
||||
|
||||
def test_pack_validation(self):
|
||||
""" Test pack validation """
|
||||
pack = self.pack_obj.create(self.pack_data)
|
||||
self.assertFalse(pack.reservation_ids)
|
||||
self.assertFalse(self.reservation_1.pack_id)
|
||||
pack.reservation_ids = [(4, self.reservation_1.id, 0),
|
||||
(4, self.reservation_3.id, 0)]
|
||||
self.assertEqual(pack.reservation_ids[0].state, "draft")
|
||||
self.assertEqual(self.reservation_1.pack_id.id, pack.id)
|
||||
self.assertEqual(pack.state, "draft")
|
||||
pack.state_confirm()#validation required
|
||||
self.assertEqual(pack.state, "confirmed")
|
||||
pack.state_validated()
|
||||
self.assertEqual(pack.state, "validated")
|
||||
self.assertEqual(pack.reservation_ids[0].state, "validated")
|
||||
self.assertEqual(pack.reservation_ids[1].state, "validated")
|
||||
|
||||
def test_pack_rejection(self):
|
||||
""" test pack rejection """
|
||||
pack = self.pack_obj.create(self.pack_data)
|
||||
self.assertFalse(pack.reservation_ids)
|
||||
self.assertFalse(self.reservation_1.pack_id)
|
||||
pack.reservation_ids = [(4, self.reservation_1.id, 0),
|
||||
(4, self.reservation_3.id, 0)]
|
||||
self.assertEqual(pack.reservation_ids[0].state, "draft")
|
||||
self.assertEqual(self.reservation_1.pack_id.id, pack.id)
|
||||
self.assertEqual(pack.state, "draft")
|
||||
pack.state_confirm()#validation required
|
||||
rej_wizard = self.env['golem.pack.rejection.wizard'].create({
|
||||
'pack_id': pack.id,
|
||||
'reason' : 'reason1'
|
||||
})
|
||||
rej_wizard.reject()
|
||||
self.assertEqual(pack.state, "rejected")
|
||||
self.assertEqual(self.reservation_3.state, "rejected")
|
||||
self.assertEqual(pack.rejection_reason, 'reason1')
|
87
golem_resource_pack/views/golem_resource_pack_views.xml
Normal file
87
golem_resource_pack/views/golem_resource_pack_views.xml
Normal file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- Trees -->
|
||||
<record model="ir.ui.view" id="golem_resource_pack_view_tree">
|
||||
<field name="name">GOLEM Resource Pack Tree</field>
|
||||
<field name="model">golem.resource.pack</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="black: state=='draft'; blue: state=='validated'; gree : state=='validated'; grey: state=='canceled'; orange: state=='rejected'">
|
||||
<field name="name" />
|
||||
<field name="partner_id" />
|
||||
<field name="state" />
|
||||
<field name="reservation_count" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Forms -->
|
||||
<record model="ir.ui.view" id="golem_resource_pack_view_form">
|
||||
<field name="name">GOLEM Resource Pack Form</field>
|
||||
<field name="model">golem.resource.pack</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header>
|
||||
<button name="state_confirm" type="object" string="Confirm" class="oe_highlight"
|
||||
attrs="{'invisible': ['|', ('state', 'not in', 'draft'), ('id', '=', False)]}" />
|
||||
<button name="state_canceled" type="object"
|
||||
string="Cancel" states="confirmed,validated" />
|
||||
<button name="state_draft" type="object" string="Set to draft"
|
||||
states="canceled,confirmed,validated,rejected" />
|
||||
<button name="state_validated" type="object" string="Validate"
|
||||
states="confirmed" class="oe_highlight"
|
||||
groups="golem_base.group_golem_manager" />
|
||||
<button name="state_rejected" type="object" string="Reject"
|
||||
states="confirmed" class="oe_highlight"
|
||||
groups="golem_base.group_golem_manager" />
|
||||
<field name="state" widget="statusbar" />
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<group name="general" string="Genaral">
|
||||
<field name="id" invisible="1"/>
|
||||
<field name="user_id" />
|
||||
<field name="partner_id" />
|
||||
<field name="note" />
|
||||
<field name="rejection_reason"
|
||||
attrs="{'invisible': [('state', '!=', 'rejected')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="reservation_ids" context="{'default_partner_id' : partner_id}" />
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers" />
|
||||
<field name="message_ids" widget="mail_thread" />
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Actions -->
|
||||
<act_window id="golem_resource_pack_action" name="Reservation Pack"
|
||||
res_model="golem.resource.pack" view_mode="tree,form" />
|
||||
|
||||
<!-- Menus -->
|
||||
<menuitem id="golem_resource_packs_menu" name="Reservation Packs"
|
||||
parent="golem_resource.golem_resource_menu" action="golem_resource_pack_action"
|
||||
sequence="20" />
|
||||
|
||||
</data>
|
||||
</odoo>
|
19
golem_resource_pack/wizard/__init__.py
Normal file
19
golem_resource_pack/wizard/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import golem_pack_rejection
|
38
golem_resource_pack/wizard/golem_pack_rejection.py
Normal file
38
golem_resource_pack/wizard/golem_pack_rejection.py
Normal file
@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
""" GOLEM Resources Pack management """
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
class GolemReservationRejectionWizard(models.TransientModel):
|
||||
"""GOLEM Resource wizard : refusal reason for a pack """
|
||||
_name = "golem.pack.rejection.wizard"
|
||||
|
||||
pack_id = fields.Many2one('golem.resource.pack', required=True)
|
||||
reason = fields.Text(required=True)
|
||||
|
||||
@api.multi
|
||||
def reject(self):
|
||||
""" Sets pack status to rejected and add reason """
|
||||
self.ensure_one()
|
||||
rejection = self[0]
|
||||
for reservation in rejection.pack_id.reservation_ids:
|
||||
if reservation.state == "confirmed":
|
||||
reservation.write({'state' :'rejected'})
|
||||
rejection.pack_id.write({'rejection_reason': rejection.reason})
|
41
golem_resource_pack/wizard/golem_pack_rejection_views.xml
Normal file
41
golem_resource_pack/wizard/golem_pack_rejection_views.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<!-- Forms -->
|
||||
<record model="ir.ui.view" id="golem_pack_rejection_wizard_view_form">
|
||||
<field name="name">GOLEM Pack Rejection Wizard Form</field>
|
||||
<field name="model">golem.pack.rejection.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Rejection reason">
|
||||
<group>
|
||||
<field name="pack_id" readonly="1" />
|
||||
<field name="reason" />
|
||||
</group>
|
||||
<footer>
|
||||
<button name="reject" string="Reject" type="object"
|
||||
class="oe_highlight" />
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
19
golem_resource_pack_account/__init__.py
Normal file
19
golem_resource_pack_account/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import models
|
32
golem_resource_pack_account/__manifest__.py
Normal file
32
golem_resource_pack_account/__manifest__.py
Normal file
@ -0,0 +1,32 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
{
|
||||
'name': 'GOLEM resources pack invoicing',
|
||||
'summary': 'GOLEM resources pack invoicing',
|
||||
'description': ''' GOLEM resources pack invoicing ''',
|
||||
'version': '10.0.0.0.1',
|
||||
'category': 'GOLEM',
|
||||
'author': 'Youssef El Ouahby, Fabien Bourgeois',
|
||||
'license': 'AGPL-3',
|
||||
'application': True,
|
||||
'installable': True,
|
||||
'depends': ['golem_resource_pack', 'golem_resource_account'],
|
||||
'data': ['views/golem_resource_pack_views.xml']
|
||||
#'security/ir.model.access.csv']
|
||||
}
|
19
golem_resource_pack_account/models/__init__.py
Normal file
19
golem_resource_pack_account/models/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import golem_resource_pack
|
90
golem_resource_pack_account/models/golem_resource_pack.py
Normal file
90
golem_resource_pack_account/models/golem_resource_pack.py
Normal file
@ -0,0 +1,90 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
""" GOLEM Resource Pack Invoicing """
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class GolemResourcePack(models.Model):
|
||||
""" GOLEM Resource Pack invoice extention """
|
||||
_inherit = 'golem.resource.pack'
|
||||
|
||||
invoice_id = fields.Many2one('account.invoice', string="Invoice")
|
||||
|
||||
invoice_state = fields.Selection(related='invoice_id.state', store=True,
|
||||
copy=False)
|
||||
invoice_amount_total = fields.Monetary(related='invoice_id.amount_total')
|
||||
currency_id = fields.Many2one(related='invoice_id.currency_id')
|
||||
is_products_set = fields.Boolean(compute="_compute_is_products_set")
|
||||
|
||||
@api.multi
|
||||
def _compute_is_products_set(self):
|
||||
""" compute is_products_set """
|
||||
for pack in self:
|
||||
if len(filter(lambda x: x.resource_product_id.id is False, pack.reservation_ids)) \
|
||||
> 0:
|
||||
pack.is_products_set = False
|
||||
else:
|
||||
pack.is_products_set = True
|
||||
|
||||
@api.multi
|
||||
def chek_pack_to_invoice(self):
|
||||
""" chek pack before invoicing """
|
||||
for pack in self:
|
||||
if pack.state != 'validated':
|
||||
raise ValidationError(_('The current pack is not validated, please validate '
|
||||
'it before creating invoice'))
|
||||
elif not pack.is_products_set:
|
||||
raise ValidationError(_('You can not create an invoice for a pack without '
|
||||
'linked product on every resource reserved.'))
|
||||
elif pack.invoice_id.id:
|
||||
raise ValidationError(_('You can not create an invoice as there '
|
||||
'is already one.'))
|
||||
|
||||
|
||||
@api.multi
|
||||
def create_invoice(self):
|
||||
""" Invoice creation """
|
||||
for pack in self:
|
||||
pack.chek_pack_to_invoice()
|
||||
pack.reservation_ids.check_before_invoicing()
|
||||
inv_obj = self.env['account.invoice']
|
||||
partner_id = pack.partner_id
|
||||
invoice_id = inv_obj.create({
|
||||
'origin': pack.name,
|
||||
'type': 'out_invoice',
|
||||
'reference': False,
|
||||
'account_id': partner_id.property_account_receivable_id.id,
|
||||
'partner_id': partner_id.id
|
||||
})
|
||||
pack.invoice_id = invoice_id.id
|
||||
pack.reservation_ids.create_invoice_line(invoice_id)
|
||||
|
||||
@api.multi
|
||||
def show_invoice(self):
|
||||
""" Redirects to linked invoice """
|
||||
self.ensure_one()
|
||||
pack = self[0]
|
||||
if pack.invoice_id:
|
||||
return {'type': 'ir.actions.act_window',
|
||||
'res_model': 'account.invoice',
|
||||
'res_id': pack.invoice_id.id,
|
||||
'view_mode': 'form',
|
||||
'view_id': self.env.ref('account.invoice_form').id}
|
18
golem_resource_pack_account/tests/__init__.py
Normal file
18
golem_resource_pack_account/tests/__init__.py
Normal file
@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
from . import test_golem_pack_invoice
|
114
golem_resource_pack_account/tests/test_golem_pack_invoice.py
Normal file
114
golem_resource_pack_account/tests/test_golem_pack_invoice.py
Normal file
@ -0,0 +1,114 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
# Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
""" GOLEM Resource Reservation testing """
|
||||
|
||||
import logging
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import ValidationError
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestGolemResourcePack(TransactionCase):
|
||||
""" GOLEM Resource Pack testing """
|
||||
|
||||
def setUp(self, *args, **kwargs):
|
||||
""" Bootstrap Resource Reservation """
|
||||
super(TestGolemResourcePack, self).setUp(*args, **kwargs)
|
||||
# set product
|
||||
self.product = self.env['product.template'].create({
|
||||
'name': 'Product',
|
||||
'categ_id': self.env.ref('product.product_category_all').id,
|
||||
'list_price': 7.0,
|
||||
'type': 'service',
|
||||
'uom_id': self.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': self.env.ref('product.product_uom_hour').id,
|
||||
'property_account_income_id': self.env.ref('l10n_fr.pcg_706').id
|
||||
})
|
||||
#set resources
|
||||
self.resource_1 = self.env['golem.resource'].create({
|
||||
'name': 'Resource1',
|
||||
'product_tmpl_id': self.product.id,
|
||||
'avaibility_start': '2018-01-01',
|
||||
'avaibility_stop': '2020-01-01',
|
||||
'availibility_24_7': True
|
||||
})
|
||||
self.resource_2 = self.env['golem.resource'].create({
|
||||
'name': 'Resource2',
|
||||
'avaibility_start': '2018-01-01',
|
||||
'avaibility_stop': '2020-01-01',
|
||||
'availibility_24_7': True
|
||||
})
|
||||
|
||||
#set partners
|
||||
self.partner_1 = self.env['res.partner'].create({'firstname': 'John',
|
||||
'lastname': 'DOE',
|
||||
'is_company': False})
|
||||
self.partner_2 = self.env['res.partner'].create({'firstname': 'John2',
|
||||
'lastname': 'DOE2',
|
||||
'is_company': False})
|
||||
|
||||
# set reservations
|
||||
self.reservation_1 = self.env['golem.resource.reservation'].create({
|
||||
'resource_id': self.resource_1.id,
|
||||
'date_start': '2018-02-05 11:00:00',
|
||||
'date_stop': '2018-02-05 12:00:00',
|
||||
'partner_id': self.partner_1.id
|
||||
})
|
||||
self.reservation_2 = self.env['golem.resource.reservation'].create({
|
||||
'resource_id': self.resource_1.id,
|
||||
'date_start': '2018-02-06 11:00:00',
|
||||
'date_stop': '2018-02-06 12:00:00',
|
||||
'partner_id': self.partner_1.id
|
||||
})
|
||||
|
||||
#set pack env
|
||||
self.pack_obj = self.env['golem.resource.pack']
|
||||
self.pack_data = {
|
||||
'partner_id': self.partner_1.id,
|
||||
'reservation_ids': [(4, self.reservation_1.id, 0),
|
||||
(4, self.reservation_2.id, 0)]}
|
||||
|
||||
|
||||
def test_pack_invoice_basic(self):
|
||||
""" Test pack invoice basic """
|
||||
pack = self.pack_obj.create(self.pack_data)
|
||||
pack.state_confirm()
|
||||
pack.create_invoice()
|
||||
self.assertTrue(pack.invoice_id.id)
|
||||
self.assertEqual(pack.invoice_state, 'draft')
|
||||
|
||||
def test_unallowed_pack_invoice(self):
|
||||
""" Test unallowed pack invoice cases """
|
||||
pack = self.pack_obj.create(self.pack_data)
|
||||
with self.assertRaises(ValidationError) as err:
|
||||
pack.create_invoice()
|
||||
self.assertIn(u'current pack is not validated', err.exception.args[0])
|
||||
self.reservation_2.write({'resource_id': self.resource_2.id})#no product linked
|
||||
pack.state_confirm()
|
||||
with self.assertRaises(ValidationError) as err:
|
||||
pack.create_invoice()
|
||||
self.assertIn(u'linked product on every resource', err.exception.args[0])
|
||||
pack.state_draft()
|
||||
self.reservation_2.write({'resource_id': self.resource_1.id})# with product linked
|
||||
pack.state_confirm()
|
||||
pack.create_invoice()
|
||||
self.assertTrue(pack.invoice_id.id)
|
||||
with self.assertRaises(ValidationError) as err:
|
||||
pack.create_invoice()
|
||||
self.assertIn(u'can not create an invoice as there', err.exception.args[0])
|
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Youssef El Ouahby <youssef@yaltik.com>
|
||||
Copyright 2018 Fabien Bourgeois <fabien@yaltik.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- Tree -->
|
||||
<record model="ir.ui.view" id="golem_resource_pack_inherit_account_tree">
|
||||
<field name="name">GOLEM Resource Pack Account extention Tree</field>
|
||||
<field name="model">golem.resource.pack</field>
|
||||
<field name="inherit_id" ref="golem_resource_pack.golem_resource_pack_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="reservation_count" position="after">
|
||||
<field name="invoice_state" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
<!-- Forms -->
|
||||
<record model="ir.ui.view" id="golem_resource_pack_inherit_account_form">
|
||||
<field name="name">GOLEM Resource Pack Account extention Form</field>
|
||||
<field name="model">golem.resource.pack</field>
|
||||
<field name="inherit_id" ref="golem_resource_pack.golem_resource_pack_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<button name="state_rejected" position="after">
|
||||
<button name="create_invoice" type="object" string="Create Invoice" class="oe_highlight"
|
||||
attrs="{'invisible': ['|', ('state', '!=', 'validated'), '|', ('invoice_id', '!=', False), ('is_products_set', '=', False)]}" />
|
||||
<button name="show_invoice" type="object" string="Show invoice" class="oe_highlight"
|
||||
attrs="{'invisible': [('invoice_id', '=', False)]}" />
|
||||
</button>
|
||||
<group name="general" position="after">
|
||||
<group name="invoicing" string="Invoicing"
|
||||
attrs="{'invisible': [('invoice_id', '=', False)]}">
|
||||
<field name="is_products_set" invisible="1"/>
|
||||
<field name="invoice_id" />
|
||||
<field name="invoice_state" />
|
||||
<field name="invoice_amount_total" />
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
Loading…
x
Reference in New Issue
Block a user