← Back to team overview

openerp-community-reviewer team mailing list archive

[Merge] lp:~camptocamp/sale-wkfl/add-sale_cancel_reason-jge into lp:sale-wkfl

 

Joël Grand-Guillaume @ camptocamp has proposed merging lp:~camptocamp/sale-wkfl/add-sale_cancel_reason-jge into lp:sale-wkfl.

Commit message:
[ADD] module sale_cancel_reason that force you to choose a reason why to cancel a given SO. The reasons are chosen from a configurable list.

Requested reviews:
  Sale Core Editors (sale-core-editors)

For more details, see:
https://code.launchpad.net/~camptocamp/sale-wkfl/add-sale_cancel_reason-jge/+merge/193599

Hi,


This proposal add the module sale_cancel_reason that force you to choose a reason why to cancel a given SO. The reasons are chosen from a configurable list.

Regards,


-- 
https://code.launchpad.net/~camptocamp/sale-wkfl/add-sale_cancel_reason-jge/+merge/193599
Your team Sale Core Editors is requested to review the proposed merge of lp:~camptocamp/sale-wkfl/add-sale_cancel_reason-jge into lp:sale-wkfl.
=== added directory 'sale_cancel_reason'
=== added file 'sale_cancel_reason/__init__.py'
--- sale_cancel_reason/__init__.py	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/__init__.py	2013-11-01 13:24:46 +0000
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Guewen Baconnier
+#    Copyright 2013 Camptocamp SA
+#
+#    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 wizard
+from . import model

=== added file 'sale_cancel_reason/__openerp__.py'
--- sale_cancel_reason/__openerp__.py	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/__openerp__.py	2013-11-01 13:24:46 +0000
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Guewen Baconnier
+#    Copyright 2013 Camptocamp SA
+#
+#    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': 'Sale Cancel Reason',
+ 'version': '1.0',
+ 'author': 'Camptocamp',
+ 'category': 'Sale',
+ 'license': 'AGPL-3',
+ 'complexity': 'normal',
+ 'images': [],
+ 'website': "http://www.camptocamp.com";,
+ 'description': """
+Sale Cancel Reason
+==================
+
+When a sale order is canceled, a reason must be given,
+it is choosed from a configured list.
+
+""",
+ 'depends': ['sale',
+             ],
+ 'demo': [],
+ 'data': ['wizard/cancel_reason_view.xml',
+          'view/sale_view.xml',
+          'security/ir.model.access.csv',
+          'data/sale_order_cancel_reason.xml',
+          ],
+ 'auto_install': False,
+ 'test': ['test/sale_order_cancel.yml',
+          ],
+ 'installable': True,
+ }

=== added directory 'sale_cancel_reason/data'
=== added file 'sale_cancel_reason/data/sale_order_cancel_reason.xml'
--- sale_cancel_reason/data/sale_order_cancel_reason.xml	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/data/sale_order_cancel_reason.xml	2013-11-01 13:24:46 +0000
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="1">
+        <record id="cancel_reason_only_quotation" model="sale.order.cancel.reason">
+            <field name="name">Just for Quotation</field>
+        </record>
+        <record id="cancel_reason_no_service_needed" model="sale.order.cancel.reason">
+            <field name="name">No service needed anymore</field>
+        </record>
+        <record id="cancel_reason_other_provider" model="sale.order.cancel.reason">
+            <field name="name">Other Service Provider selected</field>
+        </record>
+    </data>
+</openerp>

=== added directory 'sale_cancel_reason/i18n'
=== added directory 'sale_cancel_reason/model'
=== added file 'sale_cancel_reason/model/__init__.py'
--- sale_cancel_reason/model/__init__.py	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/model/__init__.py	2013-11-01 13:24:46 +0000
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Guewen Baconnier
+#    Copyright 2013 Camptocamp SA
+#
+#    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 sale

=== added file 'sale_cancel_reason/model/sale.py'
--- sale_cancel_reason/model/sale.py	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/model/sale.py	2013-11-01 13:24:46 +0000
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Guewen Baconnier
+#    Copyright 2013 Camptocamp SA
+#
+#    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 openerp.osv import orm, fields
+from openerp.tools.translate import _
+
+
+class sale_order(orm.Model):
+    _inherit = 'sale.order'
+
+    _columns = {
+        'cancel_reason_id': fields.many2one(
+            'sale.order.cancel.reason',
+            string="Reason for cancellation",
+            readonly=True,
+            ondelete="restrict"
+        ),
+    }
+
+
+class sale_order_cancel_reason(orm.Model):
+    _name = 'sale.order.cancel.reason'
+    _description = 'Sale Order Cancel Reason'
+    _columns = {
+        'name': fields.char('Reason', required=True, translate=True),
+    }

=== added directory 'sale_cancel_reason/security'
=== added file 'sale_cancel_reason/security/ir.model.access.csv'
--- sale_cancel_reason/security/ir.model.access.csv	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/security/ir.model.access.csv	2013-11-01 13:24:46 +0000
@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_sale_order_cancel_reason_user,access_sale_order_cancel_reason user,model_sale_order_cancel_reason,base.group_sale_salesman,1,0,0,0
+access_sale_order_cancel_reason_manager,access_sale_order_cancel_reason manager,model_sale_order_cancel_reason,base.group_sale_manager,1,1,1,1

=== added directory 'sale_cancel_reason/test'
=== added file 'sale_cancel_reason/test/sale_order_cancel.yml'
--- sale_cancel_reason/test/sale_order_cancel.yml	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/test/sale_order_cancel.yml	2013-11-01 13:24:46 +0000
@@ -0,0 +1,33 @@
+-
+  In order to test the choice of a cancel reason when canceling a sale order
+  I create a new cancel reason
+-
+  !record {model: sale.order.cancel.reason, id: cancel_reason_test}:
+    name: Canceled for tests
+-
+  Given I create a sale order
+-
+  !record {model: sale.order, id: sale_order_cancel_01}:
+    partner_id: base.res_partner_2
+    order_line:
+      - product_id: product.product_product_7
+        product_uom_qty: 8
+-
+  When I cancel it with the wizard asking for the reason
+-
+  !python {model: sale.order.cancel}: |
+    context = {'active_model': 'sale.order',
+               'active_ids': [ref('sale_order_cancel_01')],
+               }
+    reason_id = ref('cancel_reason_test')
+    wizard_id = self.create(cr, uid,
+                            {'reason_id': reason_id},
+                            context=context)
+    self.confirm_cancel(cr, uid, wizard_id, context=context)
+-
+  Then the sale order should be canceled
+  and the reason stored
+-
+  !assert {model: sale.order, id: sale_order_cancel_01, string: the sale order should be canceled}:
+    - state == 'cancel'
+    - cancel_reason_id.id == ref('cancel_reason_test')

=== added directory 'sale_cancel_reason/view'
=== added file 'sale_cancel_reason/view/sale_view.xml'
--- sale_cancel_reason/view/sale_view.xml	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/view/sale_view.xml	2013-11-01 13:24:46 +0000
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="0">
+        <record id="view_order_form" model="ir.ui.view">
+            <field name="name">sale.order.form</field>
+            <field name="model">sale.order</field>
+            <field name="inherit_id" ref="sale.view_order_form"/>
+            <field name="arch" type="xml">
+                <xpath expr="/form/header/button[@name='action_cancel']" position="attributes">
+                    <attribute name="type">action</attribute>
+                    <attribute name="name">%(action_sale_order_cancel)d</attribute>
+                </xpath>
+                <xpath expr="/form/header/button[@name='cancel']" position="attributes">
+                    <attribute name="type">action</attribute>
+                    <attribute name="name">%(action_sale_order_cancel)d</attribute>
+                </xpath>
+                <xpath expr="/form/sheet/h1[1]" position="after">
+                    <h2 attrs="{'invisible': [('state', '!=', 'cancel')]}">
+                        <label for="cancel_reason_id" string="Cancellation reason:"/>
+                        <field name="cancel_reason_id" class="oe_inline"
+                          options='{"no_open": True}' />
+                    </h2>
+                </xpath>
+            </field>
+        </record>
+
+        <record model="ir.ui.view" id="view_sale_order_cancel_reason_form">
+            <field name="name">Sale Order Cancel Reason</field>
+            <field name="model">sale.order.cancel.reason</field>
+            <field name="arch" type="xml">
+                <form string="Sale Order Cancel Reasons">
+                    <field name="name"/>
+                </form>
+            </field>
+        </record>
+
+        <record model="ir.ui.view" id="view_sale_order_cancel_reason_tree">
+            <field name="name">Sale Order Cancel Reason</field>
+            <field name="model">sale.order.cancel.reason</field>
+            <field name="arch" type="xml">
+                <tree string="Sale Order Cancel Reasons">
+                    <field name="name"/>
+                </tree>
+            </field>
+        </record>
+
+        <record model="ir.actions.act_window" id="action_sale_order_cancel_reason">
+            <field name="name">Sale Order Cancel Reason</field>
+            <field name="res_model">sale.order.cancel.reason</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">tree,form</field>
+        </record>
+
+        <menuitem id="menu_sale_order_cancel_reason"
+          parent="base.menu_base_config"
+          name="Sale Order Cancel Reasons"
+          action="action_sale_order_cancel_reason"
+          sequence="150"
+          groups="base.group_sale_manager"/>
+    </data>
+</openerp>

=== added directory 'sale_cancel_reason/wizard'
=== added file 'sale_cancel_reason/wizard/__init__.py'
--- sale_cancel_reason/wizard/__init__.py	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/wizard/__init__.py	2013-11-01 13:24:46 +0000
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Guewen Baconnier
+#    Copyright 2013 Camptocamp SA
+#
+#    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 cancel_reason

=== added file 'sale_cancel_reason/wizard/cancel_reason.py'
--- sale_cancel_reason/wizard/cancel_reason.py	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/wizard/cancel_reason.py	2013-11-01 13:24:46 +0000
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Guewen Baconnier
+#    Copyright 2013 Camptocamp SA
+#
+#    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 openerp.osv import orm, fields
+from openerp import netsvc
+
+
+class logistic_requisition_cancel(orm.TransientModel):
+    """ Ask a reason for the sale order cancellation."""
+    _name = 'sale.order.cancel'
+    _description = __doc__
+
+    quotation_states = ['draft', 'sent']
+
+    _columns = {
+        'reason_id': fields.many2one('sale.order.cancel.reason',
+                                     string='Reason',
+                                     required=True),
+    }
+
+    def confirm_cancel(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+        if isinstance(ids, (list, tuple)):
+            assert len(ids) == 1, "1 ID expected"
+            ids = ids[0]
+        act_close = {'type': 'ir.actions.act_window_close'}
+        sale_ids = context.get('active_ids')
+        if sale_ids is None:
+            return act_close
+        assert len(sale_ids) == 1, "Only 1 sale ID expected"
+        form = self.browse(cr, uid, ids, context=context)
+        sale_obj = self.pool.get('sale.order')
+        sale_obj.write(cr, uid, sale_ids,
+                       {'cancel_reason_id': form.reason_id.id},
+                       context=context)
+        sale = sale_obj.browse(cr, uid, sale_ids[0], context=context)
+        # in the official addons, they call the signal on quotations
+        # but directly call action_cancel on sales orders
+        if sale.state in self.quotation_states:
+            wf_service = netsvc.LocalService("workflow")
+            wf_service.trg_validate(uid, 'sale.order',
+                                    sale_ids[0], 'cancel', cr)
+        else:
+            sale_obj.action_cancel(cr, uid, sale_ids, context=context)
+        return act_close

=== added file 'sale_cancel_reason/wizard/cancel_reason_view.xml'
--- sale_cancel_reason/wizard/cancel_reason_view.xml	1970-01-01 00:00:00 +0000
+++ sale_cancel_reason/wizard/cancel_reason_view.xml	2013-11-01 13:24:46 +0000
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="0">
+        <record id="view_sale_order_cancel" model="ir.ui.view">
+            <field name="name">Reason for the cancellation</field>
+            <field name="model">sale.order.cancel</field>
+            <field name="arch" type="xml">
+             <form string="Reason for the cancellation" version="7.0">
+                <p class="oe_grey">
+                    Choose the reason for the cancellation of the
+                    sale order.
+                </p>
+                <group>
+                    <field name="reason_id" widget="selection"/>
+                </group>
+                <footer>
+                    <button name="confirm_cancel"
+                        string="Confirm" type="object"
+                        class="oe_highlight"/>
+                    or
+                    <button string="Cancel" class="oe_link"
+                        special="cancel" />
+                </footer>
+            </form>
+            </field>
+        </record>
+
+        <record id="action_sale_order_cancel" model="ir.actions.act_window">
+            <field name="name">Reason for the cancellation</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">sale.order.cancel</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">form</field>
+            <field name="view_id" ref="view_sale_order_cancel"/>
+            <field name="target">new</field>
+        </record>
+    </data>
+</openerp>
+


Follow ups