Merge pull request #128 from ursais/10.0_crm_claim

[MIG] crm_claim_rma
This commit is contained in:
Maxime Chambreuil
2019-06-25 18:50:58 -05:00
committed by GitHub
21 changed files with 91 additions and 164 deletions

View File

@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Vauxoo
# © 2015 Eezee-It
# © 2009-2013 Akretion
@@ -6,9 +7,10 @@
{
'name': 'RMA Claim (Product Return Management)',
'version': '9.0.1.0.0',
'version': '10.0.1.0.0',
'category': 'Generic Modules/CRM & SRM',
'author': "Akretion, Camptocamp, Eezee-it, MONK Software, Vauxoo, "
"Techspawn Solutions, "
"Odoo Community Association (OCA)",
'website': 'http://www.akretion.com, http://www.camptocamp.com, '
'http://www.eezee-it.com, http://www.wearemonk.com, '
@@ -36,9 +38,6 @@
'security/ir.model.access.csv',
],
'demo': [],
'test': [
'test/test_invoice_refund.yml'
],
'installable': False,
'installable': True,
'auto_install': False,
}

View File

@@ -2,6 +2,5 @@
<odoo noupdate="1">
<record id="team_after_sales_service" model="crm.team">
<field name="name">After Sales Service</field>
<field name="code">ASV</field>
</record>
</odoo>

View File

@@ -1,14 +1,14 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Eezee-It, MONK Software, Vauxoo
# © 2013 Camptocamp
# © 2009-2013 Akretion,
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import _, api, exceptions, fields, models
from odoo import _, api, exceptions, fields, models
class AccountInvoice(models.Model):
_inherit = "account.invoice"
claim_id = fields.Many2one('crm.claim', string='Claim')
@@ -33,14 +33,13 @@ class AccountInvoice(models.Model):
# For each lines replace quantity and add claim_line_id
inv_line = claim_line.invoice_line_id
clean_line = {}
for field_name, field in inv_line._all_columns.iteritems():
column_type = field.column._type
if column_type == 'many2one':
for field_name, field in inv_line._fields.iteritems():
if isinstance(field, fields.Many2one):
clean_line[field_name] = inv_line[field_name].id
elif column_type not in ('many2many', 'one2many'):
elif not isinstance(field, (fields.Many2many,
fields.One2many)):
clean_line[field_name] = inv_line[field_name]
elif field_name == 'invoice_line_tax_id':
tax_ids = inv_line[field_name].ids
clean_line[field_name] = [(6, 0, tax_ids)]
clean_line['quantity'] = claim_line.product_returned_quantity

View File

@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Vauxoo
# © 2013 Camptocamp
# © 2009-2013 Akretion,
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, models
from odoo import api, models
class AccountInvoiceLine(models.Model):

View File

@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Vauxoo
# © 2013 Camptocamp
# © 2009-2013 Akretion,
@@ -10,9 +11,9 @@ from datetime import datetime
from dateutil.relativedelta import relativedelta
from openerp import _, api, exceptions, fields, models
from openerp.tools import (DEFAULT_SERVER_DATE_FORMAT,
DEFAULT_SERVER_DATETIME_FORMAT)
from odoo import _, api, exceptions, fields, models
from odoo.tools import (DEFAULT_SERVER_DATE_FORMAT,
DEFAULT_SERVER_DATETIME_FORMAT)
from .invoice_no_date import InvoiceNoDate
from .product_no_supplier import ProductNoSupplier
@@ -24,7 +25,6 @@ class ClaimLine(models.Model):
_inherit = 'mail.thread'
_description = "List of product to return"
_rec_name = "display_name"
SUBJECT_LIST = [('none', 'Not specified'),
('legal', 'Legal retractation'),
@@ -46,6 +46,11 @@ class ClaimLine(models.Model):
('expired', _("Expired")),
('not_define', _("Not Defined"))]
@api.model
def get_warranty_return_partner(self):
return self.env['product.supplierinfo'].fields_get(
'warranty_return_partner')['warranty_return_partner']['selection']
number = fields.Char(
readonly=True,
default='/',
@@ -56,16 +61,15 @@ class ClaimLine(models.Model):
default=lambda self: self.env['res.company']._company_default_get(
'claim.line'))
date = fields.Date('Claim Line Date',
select=True,
index=True,
default=fields.date.today())
name = fields.Char('Description', default='none', required=True,
name = fields.Char('Description', default='none', required=False,
help="More precise description of the problem")
priority = fields.Selection([('0_not_define', 'Not Define'),
('1_normal', 'Normal'),
('2_high', 'High'),
('3_very_high', 'Very High')],
'Priority', default='0_not_define',
compute='_compute_priority',
store=True,
readonly=False,
help="Priority attention of claim line")
@@ -77,7 +81,7 @@ class ClaimLine(models.Model):
],
help="To describe the line product diagnosis")
claim_origin = fields.Selection(SUBJECT_LIST, 'Claim Subject',
required=True, help="To describe the "
required=False, help="To describe the "
"line product problem")
product_id = fields.Many2one('product.product', string='Product',
help="Returned product")
@@ -111,30 +115,25 @@ class ClaimLine(models.Model):
warning = fields.Selection(WARRANT_COMMENT,
'Warranty', readonly=True,
help="If warranty has expired")
display_name = fields.Char('Name', compute='_get_display_name')
@api.model
def get_warranty_return_partner(self):
return self.env['product.supplierinfo']._columns[
'warranty_return_partner'
].selection
display_name = fields.Char('Name', compute='_compute_display_name')
warranty_type = fields.Selection(
get_warranty_return_partner, readonly=True,
get_warranty_return_partner,
help="Who is in charge of the warranty return treatment towards "
"the end customer. Company will use the current company "
"delivery or default address and so on for supplier and brand "
"manufacturer. Does not necessarily mean that the warranty "
"to be applied is the one of the return partner (ie: can be "
"returned to the company and be under the brand warranty")
warranty_return_partner = \
fields.Many2one('res.partner', string='Warranty Address',
help="Where the customer has to "
"send back the product(s)")
warranty_return_partner = fields.Many2one('res.partner',
string='Warranty Address',
help="Where the customer has to "
"send back the product(s)")
claim_id = fields.Many2one('crm.claim', string='Related claim',
ondelete='cascade',
help="To link to the case.claim object")
state = fields.Selection([('draft', 'Draft'), ('refused', 'Refused'),
state = fields.Selection([('draft', 'Draft'),
('refused', 'Refused'),
('confirmed', 'Confirmed, waiting for product'),
('in_to_control', 'Received, to control'),
('in_to_treate', 'Controlled, to treate'),
@@ -278,6 +277,7 @@ class ClaimLine(models.Model):
'warning': warning}
def set_warranty_limit(self):
self.ensure_one()
claim = self.claim_id
@@ -402,7 +402,8 @@ class ClaimLine(models.Model):
return res
@api.multi
def _get_display_name(self):
@api.depends('claim_id.code', 'name')
def _compute_display_name(self):
for line_id in self:
line_id.display_name = "%s - %s" % (
line_id.claim_id.code, line_id.name)

View File

@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Eezee-It, MONK Software, Vauxoo
# © 2013 Camptocamp
# © 2009-2013 Akretion,
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import _, api, exceptions, fields, models
from odoo import _, api, exceptions, fields, models
from .invoice_no_date import InvoiceNoDate
from .product_no_supplier import ProductNoSupplier

View File

@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Eezee-It, MONK Software, Vauxoo
# © 2013 Camptocamp
# © 2009-2013 Akretion,

View File

@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2016 Cyril Gaudin (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import fields, models
from odoo import fields, models
class ProcurementGroup(models.Model):

View File

@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Vauxoo
# © 2015 Eezee-It, MONK Software
# © 2013 Camptocamp

View File

@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Eezee-It, MONK Software, Vauxoo
# © 2013 Camptocamp
# © 2009-2013 Akretion,
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, models
from odoo import api, models
class StockMove(models.Model):

View File

@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Eezee-It, MONK Software, Vauxoo
# © 2013 Camptocamp
# © 2009-2013 Akretion,
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import fields, models
from odoo import fields, models
class StockPicking(models.Model):

View File

@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# © 2017 Techspawn Solutions
# © 2015 Eezee-It, MONK Software, Vauxoo
# © 2013 Camptocamp
# © 2009-2013 Akretion,
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import fields, models
from odoo import fields, models
class SubstateSubstate(models.Model):

View File

@@ -1,7 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_substate_user_all_leads,substate.substate.user,model_substate_substate,base.group_sale_salesman_all_leads,1,1,1,0
access_claim_line_user_all_leads,claim.line.user,model_claim_line,base.group_sale_salesman_all_leads,1,1,1,0
access_substate_manager,substate.substate.manager,model_substate_substate,base.group_sale_manager,1,1,1,1
access_claim_line_manager,claim.line.manager,model_claim_line,base.group_sale_manager,1,1,1,1
access_substate_user,substate.substate.user,model_substate_substate,base.group_sale_salesman,1,1,1,0
access_claim_line_user,claim.line.user,model_claim_line,base.group_sale_salesman,1,1,1,0
access_substate_user_all_leads,substate.substate.user,model_substate_substate,sales_team.group_sale_salesman,1,1,1,0
access_claim_line_user_all_leads,claim.line.user,model_claim_line,sales_team.group_sale_salesman,1,1,1,0
access_substate_manager,substate.substate.manager,model_substate_substate,sales_team.group_sale_manager,1,1,1,1
access_claim_line_manager,claim.line.manager,model_claim_line,sales_team.group_sale_manager,1,1,1,1
access_substate_user,substate.substate.user,model_substate_substate,sales_team.group_sale_salesman,1,1,1,0
access_claim_line_user,claim.line.user,model_claim_line,sales_team.group_sale_salesman,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_substate_user_all_leads substate.substate.user model_substate_substate base.group_sale_salesman_all_leads sales_team.group_sale_salesman 1 1 1 0
3 access_claim_line_user_all_leads claim.line.user model_claim_line base.group_sale_salesman_all_leads sales_team.group_sale_salesman 1 1 1 0
4 access_substate_manager substate.substate.manager model_substate_substate base.group_sale_manager sales_team.group_sale_manager 1 1 1 1
5 access_claim_line_manager claim.line.manager model_claim_line base.group_sale_manager sales_team.group_sale_manager 1 1 1 1
6 access_substate_user substate.substate.user model_substate_substate base.group_sale_salesman sales_team.group_sale_salesman 1 1 1 0
7 access_claim_line_user claim.line.user model_claim_line base.group_sale_salesman sales_team.group_sale_salesman 1 1 1 0

View File

@@ -1,55 +0,0 @@
-
In order to test the refund creation from a claim
-
I create a customer invoice
-
!record {model: account.invoice, id: account_invoice_claim_refund}:
payment_term_id: account.account_payment_term_advance
partner_id: base.res_partner_3
name: 'Test Customer Invoice'
invoice_line_ids:
- product_id: product.product_product_5
quantity: 10.0
- product_id: product.product_product_4
quantity: 5.0
-
I confirm the invoice
-
!workflow {model: account.invoice, action: invoice_open, ref: account_invoice_claim_refund}
-
I create a claim
-
!record {model: crm.claim, id: claim_refund}:
name: 'Angry Customer'
claim_type: crm_claim_type.crm_claim_type_customer
partner_id: base.res_partner_3
invoice_id: account_invoice_claim_refund
stage_id: crm_claim.stage_claim1
-
I prepare the wizard context.
-
!python {model: account.invoice.refund}: |
claim_lines = self.pool.get('claim.line').search(cr, uid, [('claim_id','=',ref('claim_refund'))])
context.update({'active_model': 'crm_claim', 'active_id': ref('claim_refund'), 'claim_id': ref('claim_refund'), 'invoice_ids': [ref('account_invoice_claim_refund')] })
-
I create a refund wizard
-
!record {model: account.invoice.refund, id: wizard_claim_refund}:
filter_refund: refund
description: 'claim refund'
-
I launch the refund wizard
-
!python {model: account.invoice.refund}: |
self.compute_refund(cr, uid, [ref('wizard_claim_refund')], 'refund', context=context)
-
I check that a refund linked to the claim has been created.
-
!python {model: account.invoice}: |
refund = self.search(cr, uid, [('type', '=', 'out_refund'),('claim_id', '=', ref('claim_refund'))])
assert refund, "The refund is created"
refund_line_ids = self.pool.get('account.invoice.line').search(cr, uid, [('invoice_id','=',refund[0])])
assert len(refund_line_ids) == 2, "It contains 2 lines, as excepted"
refund_lines = self.pool.get('account.invoice.line').browse(cr, uid, refund_line_ids)
assert ref('product.product_product_4') in [refund_lines[0].product_id.id, refund_lines[1].product_id.id], "First line is checked"
assert ref('product.product_product_5') in [refund_lines[0].product_id.id, refund_lines[1].product_id.id], "Second line is checked"

View File

@@ -2,7 +2,7 @@
# © 2016 Cyril Gaudin (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests import TransactionCase
from odoo.tests import TransactionCase
class TestClaim(TransactionCase):

View File

@@ -3,7 +3,7 @@
# © 2014 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests import common
from odoo.tests import common
class TestPickingCreation(common.TransactionCase):
@@ -41,9 +41,9 @@ class TestPickingCreation(common.TransactionCase):
'price_unit': product.list_price
}) for product, qty in [
(self.env.ref('product.product_product_24'), 5),
(self.env.ref('product.product_product_25'), 3),
(self.env.ref('product.product_product_30'), 5),
(self.env.ref('product.product_product_33'), 2),
(self.env.ref('product.product_product_27'), 2),
]
]
})
@@ -161,7 +161,8 @@ class TestPickingCreation(common.TransactionCase):
claim_id = self.env['crm.claim'].browse(
self.ref('crm_claim.crm_claim_6')
)
self.invoice.confirm_paid()
self.invoice.action_invoice_open()
# self.invoice.action_invoice_paid()
claim_id.write({
'invoice_id': self.invoice.id
})

View File

@@ -1,18 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- INHERITED VIEW FOR THE OBJECT : account_invoice -->
<!-- INHERITED VIEW FOR THE OBJECT : account_invoice -->
<record id="invoice_form" model="ir.ui.view">
<field name="name">crm_claim_rma.invoice_form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field eval="16" name="priority"/>
<field name="priority" eval="16"/>
<field name="arch" type="xml">
<data>
<field name='origin' position="after">
<xpath expr="//page[@name='other_info']//field[@name='origin']" position="after">
<field name="claim_id" attrs="{'invisible':[('type','!=','out_refund')]}"/>
</field>
</xpath>
</data>
</field>
</record>
</odoo>

View File

@@ -110,7 +110,8 @@
<separator string="Problem" colspan="4"/>
<group col="6" colspan="4">
<field name="name" colspan="6"/>
<field name="product_id" readonly="1" colspan="6"/>
<!-- Read-only view deleted -->
<field name="product_id" colspan="6"/>
<field name="prodlot_id" colspan="6"/>
<field name="claim_origin" colspan="6"/>
<field name="claim_diagnosis" colspan="6"/>
@@ -119,26 +120,26 @@
<field name="unit_sale_price"/>
<field name="return_value"/>
</group>
<group>
<group>
<group string="Warranty">
<field name="guarantee_limit" readonly="1"/>
<field name="warning" readonly="1"/>
<field name="warranty_type" readonly="1"/>
<field name="guarantee_limit"/>
<field name="warning"/>
<!-- <field name="warranty_type"/> -->
<field name="warranty_return_partner"/>
</group>
<group string="Linked Document">
<field name="claim_id" readonly="1"/>
<field name="invoice_line_id" readonly="1"/>
<field name="invoice_line_id" />
<field name="refund_line_id" readonly="1"/>
<field name="move_in_id" readonly="1"/>
<field name="move_out_id" readonly="1"/>
</group>
</group>
</group>
<separator string="State" colspan="4"/>
<group col="6" colspan="4">
<field name="substate_id" widget='selection'/>
<field name="last_state_change"/>
</group>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
@@ -148,34 +149,6 @@
</field>
</record>
<!--
A second slightly modified form view to be used for the claim_line_ids
field in the crm.claim form view. Defining it here instead of directly
inside the field allows us to write only the changes and reference it
-->
<record id="crm_claim_line_view_form_embedded" model="ir.ui.view">
<field name="name">Claim line form view to be used inside claim tree</field>
<field name="mode">primary</field>
<field name="model">claim.line</field>
<field name="priority" eval="30"/>
<field name="inherit_id" ref="crm_claim_line_form_view"/>
<field name="arch" type="xml">
<field name="claim_id" position="attributes">
<attribute name="readonly">1</attribute>
</field>
<field name="product_id" position="attributes">
<attribute name="context">{'claim_id': parent.id, 'company_id': parent.company_id, 'warehouse_id':
parent.warehouse_id, 'claim_type': parent.claim_type, 'claim_date': parent.date}
</attribute>
</field>
<field name="invoice_line_id" position="attributes">
<attribute name="context">{'claim_id': parent.id, 'company_id': parent.company_id, 'warehouse_id':
parent.warehouse_id, 'claim_type': parent.claim_type, 'claim_date': parent.date}
</attribute>
</field>
</field>
</record>
<!-- Claim lines action -->
<record model="ir.actions.act_window" id="act_crm_case_claim_lines">
<field name="name">Claim lines</field>
@@ -193,7 +166,7 @@
<menuitem
name="Claim lines"
id="menu_crm_case_claims_claim_lines"
parent="base.menu_aftersale"
parent="crm_claim.menu_aftersale"
action="act_crm_case_claim_lines"
sequence="2"/>
</odoo>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- CLAIM VIEWS -->
<record model="ir.ui.view" id="crm_case_claims_tree_view">
<field name="name">CRM - Claims Tree</field>
@@ -11,6 +12,7 @@
</field>
</field>
</record>
<!-- Crm claim Search view -->
<record id="view_crm_case_claims_filter" model="ir.ui.view">
<field name="name">CRM - Claims Search</field>
@@ -25,7 +27,6 @@
</field>
</record>
<!-- Right side link to orders -->
<act_window
id="act_crm_claim_rma_sale_orders"
@@ -59,7 +60,6 @@
res_model="stock.picking"
src_model="crm.claim"/>
<record model="ir.ui.view" id="crm_claim_rma_form_view">
<field name="name">CRM - Claim product return Form</field>
<field name="model">crm.claim</field>
@@ -91,6 +91,7 @@
'claim_id': id,
}"/>
</xpath>
<xpath expr="//field[@name='team_id']/parent::group" position="replace">
<group colspan="4" col="4" groups="base.group_user">
<field name="warehouse_id"/>
@@ -106,9 +107,11 @@
<xpath expr="//field[@name='partner_id']" position="attributes">
<attribute name="required">1</attribute>
</xpath>
<xpath expr="//field[@name='partner_phone']" position="attributes">
<attribute name="required">1</attribute>
</xpath>
<xpath expr="//field[@name='email_from']" position="attributes">
<attribute name="required">1</attribute>
</xpath>
@@ -157,6 +160,7 @@
context="{'search_default_claim_id': active_id, 'search_default_user_id':False}"/>
</div>
</xpath>
<xpath expr="//field[@name='name']/parent::group" position="replace">
<div class="oe_title oe_left">
<h1>
@@ -224,7 +228,6 @@
</field>
</record>
<record model="ir.actions.act_window" id="crm_claim.crm_claim_category_claim0">
<field name="context">{"search_default_user_id":uid, "stage_type":'claim'}</field>
</record>
@@ -249,11 +252,9 @@
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim.crm_case_claims_form_view"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='date_deadline']" position="after">
<field name="rma_number"/>
</xpath>
</data>
</field>
</record>
@@ -277,5 +278,6 @@
<field name="rma_number"/>
</xpath>
</field>
</record>
</record>
</odoo>

View File

@@ -5,7 +5,7 @@
# © 2009-2013 Akretion,
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, fields, models
from odoo import api, fields, models
class AccountInvoiceRefund(models.TransientModel):

View File

@@ -6,8 +6,8 @@
import time
from openerp import models, fields, exceptions, api, _
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FORMAT
from odoo import models, fields, exceptions, api, _
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FORMAT
class ClaimMakePicking(models.TransientModel):
@@ -73,12 +73,11 @@ class ClaimMakePicking(models.TransientModel):
picking_type = self.env.context.get('picking_type')
move_field = 'move_in_id' if picking_type == 'in' else 'move_out_id'
domain = [('claim_id', '=', self.env.context['active_id'])]
lines = self.env['claim.line'].\
search(domain)
lines = self.env['claim.line'].search(domain)
if lines:
domain = domain + ['|', (move_field, '=', False),
(move_field + '.state', '=', 'cancel')]
lines = lines.search(domain)
lines = lines.filtered(lambda l: getattr(getattr(l, move_field),
'state') == 'cancel' or
not getattr(l, move_field))
if not lines:
raise exceptions.UserError(
_('A picking has already been created for this claim.')
@@ -132,7 +131,7 @@ class ClaimMakePicking(models.TransientModel):
def _get_picking_line_data(self, claim, picking, line):
return {
'name': line.product_id.name_template,
'name': line.product_id.name,
'priority': '0',
'date': time.strftime(DT_FORMAT),
'date_expected': time.strftime(DT_FORMAT),
@@ -232,7 +231,7 @@ class ClaimMakePicking(models.TransientModel):
for line in self.claim_line_ids:
procurement = self.env['procurement.order'].create({
'name': line.product_id.name_template,
'name': line.product_id.name,
'group_id': group.id,
'origin': claim.code,
'warehouse_id': self.delivery_warehouse_id.id,