[IMP] improved module crm_claim_rma

This commit is contained in:
Osval Reyes
2015-11-12 10:22:45 -04:30
committed by Cyril Gaudin
parent 252d472a20
commit a49ad0a201
37 changed files with 2014 additions and 1246 deletions

90
crm_claim_rma/README.rst Normal file
View File

@@ -0,0 +1,90 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
====================================================
Management of Return Merchandise Authorization (RMA)
====================================================
This module aims to improve the Claims by adding a way to manage the
product returns. It allows you to create and manage picking from a
claim. It also introduces a new object: the claim lines to better
handle that problematic. One Claim can have several lines that
concern the return of differents products. It's for every of them
that you'll be able to check the warranty (still running or not).
It mainly contains the following features:
* product returns (one by one, mass return by invoice)
* warranty control & return address (based on invoice date and product form)
* product picking in / out
* product refund
* access to related customer data (orders, invoices, refunds, picking
in/out) from a claim
* use the OpenERP chatter within team like in opportunity (reply to refer to
the team, not a person)
Using this module makes the logistic flow of return this way:
* Returning product goes into Stock or Supplier location with a incoming
shipment (depending on the settings of the supplier info in the
product form)
* You can make a delivery from the RMA to send a new product to the Customer
Features
--------
- New field priority in claim line
- Calculate priority of claim line depending of today date and claim date
- Grouping by priority in claim line
For further information, please visit:
* https://www.odoo.com/forum/help-1
Known issues / Roadmap
======================
* Currently, the warranty duration used is the one configured on the
products today, not the one which was configured when the product
has been sold.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/rma/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/rma/issues/new?body=module:%20crm_claim_rma%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors:
-------------
* Emmanuel Samyn <esamyn@gmail.com>
* Sébastien Beau <sebastien.beau@akretion.com.br>
* Benoît Guillot <benoit.guillot@akretion.com.br>
* Joel Grand-Guillaume <joel.grandguillaume@camptocamp.com>
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
* Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Yanina Aular <yanina.aular@vauxoo.com>
* Osval Reyes <osval@vauxoo.com>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.

View File

@@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Vauxoo
# Copyright 2015 Eezee-It
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Joel Grand-Guillaume
# Osval Reyes, Yanina Aular
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as

View File

@@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Vauxoo
# Copyright 2015 Eezee-It
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume
# Benoît Guillot, Joel Grand-Guillaume,
# Osval Reyes, Yanina Aular
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -24,80 +26,43 @@
{
'name': 'RMA Claim (Product Return Management)',
'version': '8.0.1.2.0',
'version': '8.0.1.1.0',
'category': 'Generic Modules/CRM & SRM',
'description': """
Management of Return Merchandise Authorization (RMA)
====================================================
This module aims to improve the Claims by adding a way to manage the
product returns. It allows you to create and manage picking from a
claim. It also introduces a new object: the claim lines to better
handle that problematic. One Claim can have several lines that
concern the return of differents products. It's for every of them
that you'll be able to check the warranty (still running or not).
It mainly contains the following features:
* product returns (one by one, mass return by invoice)
* warranty control & return address (based on invoice date and product form)
* product picking in / out
* product refund
* access to related customer data (orders, invoices, refunds, picking
in/out) from a claim
* use the OpenERP chatter within team like in opportunity (reply to refer to
the team, not a person)
Using this module makes the logistic flow of return this way:
* Returning product goes into Stock or Supplier location with a incoming
shipment (depending on the settings of the supplier info in the
product form)
* You can make a delivery from the RMA to send a new product to the Customer
.. warning:: Currently, the warranty duration used is the one configured on the
products today, not the one which was configured when the product
has been sold.
Contributors:
-------------
* Emmanuel Samyn <esamyn@gmail.com>
* Sébastien Beau <sebastien.beau@akretion.com.br>
* Benoît Guillot <benoit.guillot@akretion.com.br>
* Joel Grand-Guillaume <joel.grandguillaume@camptocamp.com>
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
* Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Javier Carrasco <javier.carrasco@eezee-it.com>
""",
'author': "Akretion, Camptocamp, Eezee-it, MONK Software, "
'author': "Akretion, Camptocamp, Eezee-it, MONK Software, Vauxoo, "
"Odoo Community Association (OCA)",
'website': 'http://www.akretion.com, http://www.camptocamp.com, '
'http://www.eezee-it.com, http://www.wearemonk.com',
'http://www.eezee-it.com, http://www.wearemonk.com, '
'http://www.vauxoo.com',
'license': 'AGPL-3',
'depends': [
'purchase',
'sale',
'sales_team',
'stock',
'crm_claim',
'crm_claim_code',
'crm_claim_type',
'crm_claim_rma_code',
'crm_rma_location',
'product_warranty',
],
'data': [
'wizards/claim_make_picking.xml',
'views/crm_claim_rma.xml',
'data/ir_sequence_type.xml',
'data/crm_case_section.xml',
'data/crm_case_categ.xml',
'views/account_invoice.xml',
'wizards/claim_make_picking.xml',
'views/crm_claim.xml',
"views/claim_line.xml",
'views/res_partner.xml',
'data/crm_claim_rma.xml',
'views/stock_view.xml',
'security/ir.model.access.csv',
],
'test': ['test/test_invoice_refund.yml'],
'images': [
'images/product_return.png',
'images/claim.png',
'images/return_line.png',
'images/exchange.png',
'demo': [
'demo/account_invoice.xml',
'demo/account_invoice_line.xml',
'demo/crm_claim.xml',
'demo/claim_line.xml',
],
'test': [
'test/test_invoice_refund.yml'
],
'installable': False,
'auto_install': False,

View File

@@ -1,103 +1,76 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!-- Claims Sequence n° -->
<record id="seq_type_claim" model="ir.sequence.type">
<field name="name">CRM Claim</field>
<field name="code">crm.claim.rma</field>
</record>
<record id="seq_claim" model="ir.sequence">
<field name="name">CRM Claim</field>
<field name="code">crm.claim.rma</field>
<field eval="5" name="padding"/>
<field name="prefix">RMA-%(year)s/</field>
</record>
<!--
Claim sections
-->
<record model="crm.case.section" id="section_after_sales_service">
<field name="name">After Sales Service</field>
<field name="code">ASV</field>
<field name="parent_id" ref="sales_team.section_sales_department"/>
</record>
<!--
Claim categories
-->
<record model="crm.case.categ" id="categ_claim10">
<record id="categ_claim10" model="crm.case.categ">
<field name="name">No Inventory</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim11">
<field name="name">Customer Return</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim12">
<field name="name">Buyer Cancelled</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim13">
<field name="name">General Adjustement</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim14">
<field name="name">Could Not Ship</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim15">
<field name="name">Different Item</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim16">
<field name="name">Merchandise Not Received</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim17">
<field name="name">Merchandise Not As Described</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim18">
<field name="name">Pricing Error</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim19">
<field name="name">Shipping Address Undeliverable</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim20">
<field name="name">Delivered Late by Carrier</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_claim21">
<record id="categ_claim11" model="crm.case.categ">
<field name="name">Customer Return</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim12" model="crm.case.categ">
<field name="name">Buyer Cancelled</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim13" model="crm.case.categ">
<field name="name">General Adjustement</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim14" model="crm.case.categ">
<field name="name">Could Not Ship</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim15" model="crm.case.categ">
<field name="name">Different Item</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim16" model="crm.case.categ">
<field name="name">Merchandise Not Received</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim17" model="crm.case.categ">
<field name="name">Merchandise Not As Described</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim18" model="crm.case.categ">
<field name="name">Pricing Error</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim19" model="crm.case.categ">
<field name="name">Shipping Address Undeliverable</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim20" model="crm.case.categ">
<field name="name">Delivered Late by Carrier</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
<record id="categ_claim21" model="crm.case.categ">
<field name="name">Missed Fulfilment Promise</field>
<field name="section_id" ref="section_after_sales_service"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="section_after_sales_service" model="crm.case.section">
<field name="name">After Sales Service</field>
<field name="code">ASV</field>
<field name="parent_id" ref="sales_team.section_sales_department"/>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="seq_type_claim" model="ir.sequence.type">
<field name="name">CRM Claim</field>
<field name="code">crm.claim.rma</field>
</record>
<record id="seq_claim" model="ir.sequence">
<field name="name">CRM Claim</field>
<field name="code">crm.claim.rma</field>
<field eval="5" name="padding"/>
<field name="prefix">RMA-%(year)s/</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data noupdate="1">
<record id="crm_rma_invoice_001" model="account.invoice">
<field name="currency_id" ref="base.EUR"/>
<field name="company_id" ref="base.main_company"/>
<field name="journal_id" ref="account.sales_journal"/>
<field name="state">draft</field>
<field name="type">out_invoice</field>
<field name="account_id" ref="account.a_recv"/>
<field name="partner_id" ref="base.res_partner_9"/>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data noupdate="1">
<record id="crm_rma_invoice_1_line_1" model="account.invoice.line">
<field name="product_id" ref="product.product_product_8"/>
<field name="invoice_id" ref="crm_rma_invoice_001"/>
<field name="account_id" ref="account.a_sale"/>
<field name="name">iMac</field>
<field name="price_unit">1799</field>
<field name="quantity">3</field>
</record>
<record id="crm_rma_invoice_1_line_2" model="account.invoice.line">
<field name="product_id" ref="product.product_product_3"/>
<field name="invoice_id" ref="crm_rma_invoice_001"/>
<field name="account_id" ref="account.a_sale"/>
<field name="name">PC Assemble</field>
<field name="price_unit">450</field>
<field name="quantity">1</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<record id="claim_line_1" model="claim.line">
<field name="name">Claim Line 1 of Claim 6</field>
<field name="claim_id" ref="crm_claim.crm_claim_6"/>
<field name="claim_origin">legal</field>
<field name="invoice_line_id" ref="crm_rma_invoice_1_line_1"/>
<field name="product_id" ref="product.product_product_8"/>
<field name="product_returned_quantity">1</field>
<field name="unit_sale_price">1799</field>
<field name="location_dest_id" search="[('name','=','Stock'),('company_id', '=', 1)]" />
<field name="number">00013</field>
</record>
<record id="claim_line_2" model="claim.line">
<field name="name">Claim Line 2 of Claim 6</field>
<field name="claim_id" ref="crm_claim.crm_claim_6"/>
<field name="claim_origin">damaged</field>
<field name="invoice_line_id" ref="crm_rma_invoice_1_line_2"/>
<field name="product_id" ref="product.product_product_3"/>
<field name="product_returned_quantity">1</field>
<field name="unit_sale_price">450</field>
<field name="location_dest_id" search="[('name','=','Stock'),('company_id', '=', 1)]" />
<field name="number">00012</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data noupdate="1">
<record id="crm_claim.crm_claim_6" model="crm.claim">
<field name="invoice_id" ref="crm_rma_invoice_001"/>
<field name="delivery_address_id" ref="base.res_partner_9"/>
</record>
</data>
</openerp>

View File

@@ -75,7 +75,7 @@ msgid "Company"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Order cancellation"
msgstr ""
@@ -130,7 +130,7 @@ msgstr ""
#. module: crm_claim_rma
#: view:claim.line:0
msgid "Compute Waranty"
msgid "Compute Warranty"
msgstr ""
#. module: crm_claim_rma
@@ -211,7 +211,7 @@ msgid "To set the last state / substate change"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Not specified"
msgstr ""
@@ -252,7 +252,7 @@ msgid "Warehouse"
msgstr ""
#. module: crm_claim_rma
#: help:claim.line,claim_origine:0
#: help:claim.line,claim_origin:0
msgid "To describe the line product problem"
msgstr ""
@@ -267,7 +267,7 @@ msgid "More"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Legal retractation"
msgstr ""
@@ -286,8 +286,8 @@ msgid "The warranty limit is computed as: invoice date + warranty defined on sel
msgstr ""
#. module: crm_claim_rma
#: field:claim.line,claim_origine:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_line_claim_origine
#: field:claim.line,claim_origin:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_line_claim_origin
msgid "Claim Subject"
msgstr ""
@@ -366,12 +366,12 @@ msgid "Quotations and Sales"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Lost during transport"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Shipping error"
msgstr ""
@@ -563,13 +563,19 @@ msgid "Unit sale price of the product. Auto filled if retrun done by invoice sel
msgstr ""
#. module: crm_claim_rma
#: code:addons/crm_claim_rma/crm_claim_rma.py:313
#: code:addons/crm_claim_rma/crm_claim_rma.py:473
#, python-format
msgid "Please set product and invoice."
msgid "Please set invoice first"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: code:addons/crm_claim_rma/crm_claim_rma.py:470
#, python-format
msgid "Please set product first"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origin:0
msgid "Damaged delivered product"
msgstr ""
@@ -691,7 +697,7 @@ msgid "Merchandise Not As Described"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Exchange request"
msgstr ""
@@ -717,7 +723,7 @@ msgid "Current"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
#: selection:crm.claim,claim_type:0
msgid "Other"
msgstr ""
@@ -889,3 +895,17 @@ msgstr ""
msgid "The product has no supplier configured."
msgstr ""
#. module: crm_claim_rma
#: help:claim.line,number:0
msgid "Claim Line Identification Number"
msgstr "Número de idetifiación de la línea de reclamo"
#. module: crm_claim_rma
#: field:crm.claim,rma_number:0
msgid "RMA Number"
msgstr "Número RMA"
#. module: crm_claim_rma
#: help:crm.claim,rma_number:0
msgid "RMA Number provided by supplier"
msgstr "Número RMA asignado por el proveedor"

View File

@@ -1,20 +1,19 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * crm_claim_rma
# * crm_claim_rma
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.1\n"
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-12-20 18:21+0000\n"
"PO-Revision-Date: 2014-01-22 19:38+0000\n"
"Last-Translator: Pedro Manuel Baeza <pedro.baeza@gmail.com>\n"
"PO-Revision-Date: 2013-12-20 18:21+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-05-24 06:50+0000\n"
"X-Generator: Launchpad (build 17017)\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: crm_claim_rma
#: view:claim.line:0
@@ -73,10 +72,10 @@ msgstr "Linea de Abono"
#. module: crm_claim_rma
#: selection:claim.line,applicable_guarantee:0
msgid "Company"
msgstr "Compañia"
msgstr "Compañía"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Order cancellation"
msgstr "Cancelación de orden"
@@ -84,7 +83,7 @@ msgstr "Cancelación de orden"
#: field:claim_make_picking.wizard,claim_line_dest_location:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_make_picking_wizard_claim_line_dest_location
msgid "Dest. Location"
msgstr "Localizalización de destino"
msgstr "Localización de destino"
#. module: crm_claim_rma
#: code:addons/crm_claim_rma/crm_claim_rma.py:224
@@ -132,7 +131,7 @@ msgstr "¡Ya se ha creado un abono para esta reclamación!"
#. module: crm_claim_rma
#: view:claim.line:0
msgid "Compute Waranty"
msgid "Compute Warranty"
msgstr "Calcular garantía"
#. module: crm_claim_rma
@@ -183,7 +182,7 @@ msgstr "Devolución de cliente"
#. module: crm_claim_rma
#: model:ir.model,name:crm_claim_rma.model_stock_move
msgid "Stock Move"
msgstr "Movimientos de stock"
msgstr "Movimientos de Inventario"
#. module: crm_claim_rma
#: help:claim.line,product_returned_quantity:0
@@ -228,7 +227,7 @@ msgid "To set the last state / substate change"
msgstr "Para definir el último cambio de estado / sub-estado"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Not specified"
msgstr "No especificado"
@@ -269,7 +268,7 @@ msgid "Warehouse"
msgstr "Almacén"
#. module: crm_claim_rma
#: help:claim.line,claim_origine:0
#: help:claim.line,claim_origin:0
msgid "To describe the line product problem"
msgstr "Para describir el problema de la línea de producto"
@@ -285,7 +284,7 @@ msgid "More"
msgstr "Más"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Legal retractation"
msgstr "Retractación legal"
@@ -308,10 +307,10 @@ msgstr ""
"seleccionada en el producto seleccionado."
#. module: crm_claim_rma
#: field:claim.line,claim_origine:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_line_claim_origine
#: field:claim.line,claim_origin:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_line_claim_origin
msgid "Claim Subject"
msgstr "Objeto de la reclamación"
msgstr "Motivo de la reclamación"
#. module: crm_claim_rma
#: field:crm.claim,real_cost:0
@@ -388,12 +387,12 @@ msgid "Quotations and Sales"
msgstr "Presupuestos y pedidos"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Lost during transport"
msgstr "Perdido durante el transporte"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Shipping error"
msgstr "Error de envío"
@@ -455,7 +454,7 @@ msgstr "Documentos generados"
#. module: crm_claim_rma
#: help:claim.line,prodlot_id:0
msgid "The serial/lot of the returned product"
msgstr "Nº de serie/lote del producto devuelto"
msgstr "No de Serie/Lote del producto devuelto"
#. module: crm_claim_rma
#: view:crm.claim:0
@@ -583,8 +582,8 @@ msgstr "Fabricante"
#. module: crm_claim_rma
#: field:claim.line,prodlot_id:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_line_prodlot_id
msgid "Serial/Lot n°"
msgstr "N° de serie/lote:"
msgid "Serial/Lot number"
msgstr "No. de Serial/Lote"
#. module: crm_claim_rma
#: help:claim.line,unit_sale_price:0
@@ -600,13 +599,19 @@ msgstr ""
"descuento de facturas, puede ser 0 si el producto es gratuito, etc..."
#. module: crm_claim_rma
#: code:addons/crm_claim_rma/crm_claim_rma.py:313
#: code:addons/crm_claim_rma/crm_claim_rma.py:473
#, python-format
msgid "Please set product and invoice."
msgstr "Establezca por favor producto y factura."
msgid "Please set invoice first"
msgstr "Por favor, establezca la factura primero"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: code:addons/crm_claim_rma/crm_claim_rma.py:470
#, python-format
msgid "Please set product first"
msgstr "Por favor, establezca el producto primero"
#. module: crm_claim_rma
#: selection:claim.line,claim_origin:0
msgid "Damaged delivered product"
msgstr "Producto enviado dañado"
@@ -728,7 +733,7 @@ msgid "Merchandise Not As Described"
msgstr "El producto no se corresponde con la descripción"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Exchange request"
msgstr "Solicitar cambio"
@@ -754,7 +759,7 @@ msgid "Current"
msgstr "Actual"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
#: selection:crm.claim,claim_type:0
msgid "Other"
msgstr "Otro"
@@ -932,3 +937,132 @@ msgstr "Reclamaciones en proceso"
#, python-format
msgid "The product has no supplier configured."
msgstr "El producto no tiene proveedor configurado."
#. module: crm_claim_rma
#: view:crm.claim:0
#: field:crm.claim,pick:0
msgid "Pick the product in store"
msgstr "Buscar el producto en la tienda"
#. module: crm_claim_rma
#: view:crm.claim:0
#: field:crm.claim,delivery_address_id:0
msgid "Partner delivery address"
msgstr "Dirección de envío"
#. module: crm_claim_rma
#: view:crm.claim:crm_claim_rma.crm_claim_rma_form_view
#: model:ir.actions.act_window,name:crm_claim_rma.act_crm_claim_rma_purchase_orders
msgid "Purchases"
msgstr "Compras"
#. module: crm_claim_rma
#: view:crm.claim:crm_claim_rma.crm_claim_rma_form_view
#: model:ir.actions.act_window,name:crm_claim_rma.act_crm_claim_rma_invoice
msgid "Invoices"
msgstr "Facturas"
#. module: crm_claim_rma
#: view:crm.claim:crm_claim_rma.crm_claim_rma_form_view
#: model:ir.actions.act_window,name:crm_claim_rma.act_crm_claim_rma_picking_in
msgid "Returns"
msgstr "Devoluciones"
#. module: crm_claim_rma
#: view:crm.claim:crm_claim_rma.crm_claim_rma_form_view
#: model:ir.actions.act_window,name:crm_claim_rma.act_crm_claim_rma_sale_orders
msgid "Sales"
msgstr "Ventas"
#. module: crm_claim_rma
#: view:claim.line:crm_claim_rma.view_crm_claim_lines_filter
#: field:claim.line,priority:0
msgid "Priority"
msgstr "Prioridad"
#. module: crm_claim_rma
#: view:crm.claim:crm_claim_rma.crm_claim_rma_form_view
msgid "Product Returns"
msgstr "Productos Devueltos"
#. module: crm_claim_rma
#: view:crm.claim:0
#: field:crm.claim,pick:0
msgid "Pick the product in the store"
msgstr "Retirar el producto en recepción"
#. module: crm_claim_rma
#: field:claim.line,number:0
msgid "Number"
msgstr "Número"
#. module: crm_claim_rma
#: selection:claim.line,warning:0
msgid "Valid"
msgstr "Válida"
#. module: crm_claim_rma
#: selection:claim.line,warning:0
msgid "Expired"
msgstr "Expirada"
#. module: crm_claim_rma
#: selection:claim.line,warning:0
msgid "Not Defined"
msgstr "No Definida"
#. module: crm_claim_rma
#: selection:claim.line,warranty_type:0
msgid "Company"
msgstr "Compañía"
#. module: crm_claim_rma
#: selection:claim.line,warranty_type:0
msgid "Supplier"
msgstr "Proveedor"
#. module: crm_claim_rma
#: selection:claim.line,warranty_type:0
msgid "Other"
msgstr "Otro"
#. module: crm_claim_rma
#: field:crm.claim,pick:0
msgid "Pick the product in the store"
msgstr "Retirar el producto en recepción"
#. module: crm_claim_rma
#: field:crm.claim,name:0
msgid "Name"
msgstr "Reclamo"
#. module: crm_claim_rma
#: field:crm.claim,rma_number:0
msgid "Rma number"
msgstr "Número RMA"
#. module: crm_claim_rma
#: selection:claim.line,claim_origin:0
msgid "Imperfection"
msgstr "Imperfección"
#. module: crm_claim_rma
#: selection:claim.line,claim_origin:0
msgid "Physical Damage by Client"
msgstr "Daño físico por el cliente"
#. module: crm_claim_rma
#: selection:claim.line,claim_origin:0
msgid "Physical Damage by Company"
msgstr "Daño físico por la compañía"
#. module: crm_claim_rma
#: selection:claim.line,claim_origin:0
msgid "Perfect Conditions"
msgstr "Perfectas condiciones"
#. module: yoytec_customer_rma_workflow
#: field:claim.line,claim_diagnosis:0
msgid "Claim diagnosis"
msgstr "Diagnóstico del reclamo"

View File

@@ -0,0 +1,16 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * crm_claim_rma
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-07-17 18:30+0000\n"
"PO-Revision-Date: 2015-07-17 18:30+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

View File

@@ -0,0 +1,16 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * crm_claim_rma
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-07-17 18:30+0000\n"
"PO-Revision-Date: 2015-07-17 18:30+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

View File

@@ -0,0 +1,16 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * crm_claim_rma
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-07-17 18:30+0000\n"
"PO-Revision-Date: 2015-07-17 18:30+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

View File

@@ -77,7 +77,7 @@ msgid "Company"
msgstr "Société"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Order cancellation"
msgstr "Annulation de la commande"
@@ -132,7 +132,7 @@ msgstr "Un avoir a déjà été créé pour cette réclamation !"
#. module: crm_claim_rma
#: view:claim.line:0
msgid "Compute Waranty"
msgid "Compute Warranty"
msgstr ""
#. module: crm_claim_rma
@@ -220,7 +220,7 @@ msgid "To set the last state / substate change"
msgstr "Pour définir le derniere changement d'état ou de sous-état"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Not specified"
msgstr "Non spécifié"
@@ -261,7 +261,7 @@ msgid "Warehouse"
msgstr "Entrepôt"
#. module: crm_claim_rma
#: help:claim.line,claim_origine:0
#: help:claim.line,claim_origin:0
msgid "To describe the line product problem"
msgstr "Pour décrire le problème de la ligne de produit"
@@ -277,7 +277,7 @@ msgid "More"
msgstr "Plus"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Legal retractation"
msgstr "Rétracation légale"
@@ -300,8 +300,8 @@ msgstr ""
"dans le produit sélectionné."
#. module: crm_claim_rma
#: field:claim.line,claim_origine:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_line_claim_origine
#: field:claim.line,claim_origin:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_line_claim_origin
msgid "Claim Subject"
msgstr "Sujet de la réclamation"
@@ -380,12 +380,12 @@ msgid "Quotations and Sales"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Lost during transport"
msgstr "Perte pendant le transport"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Shipping error"
msgstr "Erreur d'expédition"
@@ -593,13 +593,19 @@ msgstr ""
"sur la facture,..."
#. module: crm_claim_rma
#: code:addons/crm_claim_rma/crm_claim_rma.py:313
#: code:addons/crm_claim_rma/crm_claim_rma.py:473
#, python-format
msgid "Please set product and invoice."
msgstr ""
msgid "Please set invoice first"
msgstr "S'il vous plaît d'abord définir le facture"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: code:addons/crm_claim_rma/crm_claim_rma.py:470
#, python-format
msgid "Please set product first"
msgstr "S'il vous plaît d'abord définir le produit"
#. module: crm_claim_rma
#: selection:claim.line,claim_origin:0
msgid "Damaged delivered product"
msgstr "Produit livré endommagé"
@@ -721,7 +727,7 @@ msgid "Merchandise Not As Described"
msgstr "Produit ne correspondant pas à sa description"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Exchange request"
msgstr "Demande d'échange"
@@ -747,7 +753,7 @@ msgid "Current"
msgstr "Actuel"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
#: selection:crm.claim,claim_type:0
msgid "Other"
msgstr "Autre"

View File

@@ -77,7 +77,7 @@ msgid "Company"
msgstr "Empresa"
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Order cancellation"
msgstr ""
@@ -132,7 +132,7 @@ msgstr ""
#. module: crm_claim_rma
#: view:claim.line:0
msgid "Compute Waranty"
msgid "Compute Warranty"
msgstr ""
#. module: crm_claim_rma
@@ -220,7 +220,7 @@ msgid "To set the last state / substate change"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Not specified"
msgstr ""
@@ -261,7 +261,7 @@ msgid "Warehouse"
msgstr ""
#. module: crm_claim_rma
#: help:claim.line,claim_origine:0
#: help:claim.line,claim_origin:0
msgid "To describe the line product problem"
msgstr ""
@@ -276,7 +276,7 @@ msgid "More"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Legal retractation"
msgstr ""
@@ -297,8 +297,8 @@ msgid ""
msgstr ""
#. module: crm_claim_rma
#: field:claim.line,claim_origine:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_line_claim_origine
#: field:claim.line,claim_origin:0
#: model:ir.model.fields,field_description:crm_claim_rma.field_claim_line_claim_origin
msgid "Claim Subject"
msgstr "Assunto da Solicitação"
@@ -377,12 +377,12 @@ msgid "Quotations and Sales"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Lost during transport"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Shipping error"
msgstr ""
@@ -582,13 +582,7 @@ msgid ""
msgstr ""
#. module: crm_claim_rma
#: code:addons/crm_claim_rma/crm_claim_rma.py:313
#, python-format
msgid "Please set product and invoice."
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Damaged delivered product"
msgstr ""
@@ -710,7 +704,7 @@ msgid "Merchandise Not As Described"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
msgid "Exchange request"
msgstr ""
@@ -736,7 +730,7 @@ msgid "Current"
msgstr ""
#. module: crm_claim_rma
#: selection:claim.line,claim_origine:0
#: selection:claim.line,claim_origin:0
#: selection:crm.claim,claim_type:0
msgid "Other"
msgstr ""

View File

@@ -1,3 +1,33 @@
from . import crm_claim_rma
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Vauxoo
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume,
# Osval Reyes
#
# 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 account_invoice
from . import stock
from . import account_invoice_line
from . import claim_line
from . import crm_claim
from . import invoice_no_date
from . import product_no_supplier
from . import stock_move
from . import stock_picking
from . import substate_substate

View File

@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Eezee-It, MONK Software
# Copyright 2015 Eezee-It, MONK Software, Vauxoo
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli
# Osval Reyes, Yanina Aular
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -22,21 +23,21 @@
#
##############################################################################
from openerp import models, fields, api, exceptions
from openerp.tools.translate import _
from openerp import _, api, exceptions, fields, models
class AccountInvoice(models.Model):
_inherit = "account.invoice"
claim_id = fields.Many2one('crm.claim', string='Claim')
@api.model
def _refund_cleanup_lines(self, lines):
"""
Override when from claim to update the quantity and link to the
claim line.
"""
# check if is an invoice_line and we are from a claim
if not (self.env.context.get('claim_line_ids') and lines and
lines[0]._name == 'account.invoice.line'):
@@ -59,14 +60,17 @@ class AccountInvoice(models.Model):
elif column_type not in ('many2many', '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
clean_line['claim_line_id'] = [claim_line.id]
new_lines.append(clean_line)
if not new_lines:
# TODO use custom states to show button of this wizard or
# not instead of raise an error
raise exceptions.Warning(
_('A refund has already been created for this claim !'))
return [(0, 0, l) for l in new_lines]
@@ -82,21 +86,3 @@ class AccountInvoice(models.Model):
result['claim_id'] = self.env.context['claim_id']
return result
class AccountInvoiceLine(models.Model):
_inherit = "account.invoice.line"
@api.model
@api.returns('self', lambda value: value.id)
def create(self, vals):
claim_line_id = vals.get('claim_line_id')
if claim_line_id:
del vals['claim_line_id']
line = super(AccountInvoiceLine, self).create(vals)
if claim_line_id:
claim_line = self.env['claim.line'].browse(claim_line_id)
claim_line.refund_line_id = line.id
return line

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Vauxoo
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume,
# Osval Reyes, Yanina Aular
#
# 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 import api, models
class AccountInvoiceLine(models.Model):
_inherit = "account.invoice.line"
@api.model
def create(self, vals):
claim_line_id = vals.get('claim_line_id')
if claim_line_id:
del vals['claim_line_id']
line = super(AccountInvoiceLine, self).create(vals)
if claim_line_id:
claim_line = self.env['claim.line'].browse(claim_line_id)
claim_line.refund_line_id = line.id
return line

View File

@@ -0,0 +1,432 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Vauxoo
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume,
# Osval Reyes, Yanina Aular
#
# 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/>.
#
##############################################################################
import calendar
import math
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 .invoice_no_date import InvoiceNoDate
from .product_no_supplier import ProductNoSupplier
class ClaimLine(models.Model):
_name = "claim.line"
_inherit = 'mail.thread'
_description = "List of product to return"
_rec_name = "display_name"
SUBJECT_LIST = [('none', 'Not specified'),
('legal', 'Legal retractation'),
('cancellation', 'Order cancellation'),
('damaged', 'Damaged delivered product'),
('error', 'Shipping error'),
('exchange', 'Exchange request'),
('lost', 'Lost during transport'),
('perfect_conditions',
'Perfect Conditions'),
('imperfection', 'Imperfection'),
('physical_damage_client',
'Physical Damage by Client'),
('physical_damage_company',
'Physical Damage by Company'),
('other', 'Other')]
WARRANT_COMMENT = [
('valid', _("Valid")),
('expired', _("Expired")),
('not_define', _("Not Defined"))]
number = fields.Char(
readonly=True,
default='/',
help='Claim Line Identification Number')
company_id = fields.Many2one(
'res.company', string='Company', readonly=False,
change_default=True,
default=lambda self: self.env['res.company']._company_default_get(
'claim.line'))
date = fields.Date('Claim Line Date',
select=True,
default=fields.date.today())
name = fields.Char('Description', default='none', required=True,
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='_set_priority',
store=True,
readonly=False,
help="Priority attention of claim line")
claim_diagnosis = fields.\
Selection([('damaged', 'Product Damaged'),
('repaired', 'Product Repaired'),
('good', 'Product in good condition'),
('hidden', 'Product with hidden physical damage'),
],
help="To describe the line product diagnosis")
claim_origin = fields.Selection(SUBJECT_LIST, 'Claim Subject',
required=True, help="To describe the "
"line product problem")
product_id = fields.Many2one('product.product', string='Product',
help="Returned product")
product_returned_quantity = \
fields.Float('Quantity', digits=(12, 2),
help="Quantity of product returned")
unit_sale_price = fields.Float(digits=(12, 2),
help="Unit sale price of the product. "
"Auto filled if retrun done "
"by invoice selection. Be careful "
"and check the automatic "
"value as don't take into account "
"previous refunds, invoice "
"discount, can be for 0 if product "
"for free,...")
return_value = fields.Float(compute='_compute_line_total_amount',
string='Total return',
help="Quantity returned * Unit sold price",)
prodlot_id = fields.Many2one('stock.production.lot',
string='Serial/Lot number',
help="The serial/lot of "
"the returned product")
applicable_guarantee = fields.Selection([('us', 'Company'),
('supplier', 'Supplier'),
('brand', 'Brand manufacturer')],
'Warranty type')
guarantee_limit = fields.Date('Warranty limit', readonly=True,
help="The warranty limit is "
"computed as: invoice date + warranty "
"defined on selected product.")
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'].get_warranty_return_partner()
warranty_type = fields.Selection(
get_warranty_return_partner, readonly=True,
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)")
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'),
('confirmed', 'Confirmed, waiting for product'),
('in_to_control', 'Received, to control'),
('in_to_treate', 'Controlled, to treate'),
('treated', 'Treated')],
string='State', default='draft')
substate_id = fields.Many2one('substate.substate', string='Sub state',
help="Select a sub state to precise the "
"standard state. Example 1: "
"state = refused; substate could "
"be warranty over, not in "
"warranty, no problem,... . "
"Example 2: state = to treate; "
"substate could be to refund, to "
"exchange, to repair,...")
last_state_change = fields.Date(string='Last change', help="To set the"
"last state / substate change")
invoice_line_id = fields.Many2one('account.invoice.line',
string='Invoice Line',
help='The invoice line related'
' to the returned product')
refund_line_id = fields.Many2one('account.invoice.line',
string='Refund Line',
help='The refund line related'
' to the returned product')
move_in_id = fields.Many2one('stock.move',
string='Move Line from picking in',
help='The move line related'
' to the returned product')
move_out_id = fields.Many2one('stock.move',
string='Move Line from picking out',
help='The move line related'
' to the returned product')
location_dest_id = fields.Many2one('stock.location',
string='Return Stock Location',
help='The return stock location'
' of the returned product')
claim_type = fields.Many2one(related='claim_id.claim_type',
string="Claim Line Type",
store=True, help="Claim classification")
invoice_date = fields.Datetime(related='invoice_line_id.invoice_id.'
'create_date',
help="Date of Claim Invoice")
# Method to calculate total amount of the line : qty*UP
@api.multi
def _compute_line_total_amount(self):
for line in self:
line.return_value = (line.unit_sale_price *
line.product_returned_quantity)
@api.multi
def copy(self, default=None):
self.ensure_one()
default = default or {}
std_default = {
'move_in_id': False,
'move_out_id': False,
'refund_line_id': False,
}
std_default.update(default)
return super(ClaimLine, self).copy(default=std_default)
@api.depends('invoice_date', 'date')
def _set_priority(self):
"""
To determine the priority of claim line
"""
for line_id in self:
if line_id.invoice_date:
days = fields.datetime.strptime(line_id.date, '%Y-%m-%d') - \
fields.datetime.strptime(line_id.invoice_date,
DEFAULT_SERVER_DATETIME_FORMAT)
if days.days <= 1:
line_id.priority = '3_very_high'
elif days.days <= 7:
line_id.priority = '2_high'
else:
line_id.priority = '1_normal'
def _get_subject(self, num):
if num > 0 and num <= len(self.SUBJECT_LIST):
return self.SUBJECT_LIST[num - 1][0]
else:
return self.SUBJECT_LIST[0][0]
@staticmethod
def warranty_limit(start, warranty_duration):
""" Take a duration in float, return the duration in relativedelta
``relative_delta(months=...)`` only accepts integers.
We have to extract the decimal part, and then, extend the delta with
days.
"""
decimal_part, months = math.modf(warranty_duration)
months = int(months)
# If we have a decimal part, we add the number them as days to
# the limit. We need to get the month to know the number of
# days.
delta = relativedelta(months=months)
monthday = start + delta
__, days_month = calendar.monthrange(monthday.year, monthday.month)
# ignore the rest of the days (hours) since we expect a date
days = int(days_month * decimal_part)
return start + relativedelta(months=months, days=days)
def _warranty_limit_values(self, invoice, claim_type, product, claim_date):
if not (invoice and claim_type and product and claim_date):
return {'guarantee_limit': False, 'warning': False}
invoice_date = invoice.create_date
if not invoice_date:
raise InvoiceNoDate
warning = 'not_define'
invoice_date = datetime.strptime(invoice_date,
DEFAULT_SERVER_DATETIME_FORMAT)
if isinstance(claim_type, self.env['crm.claim.type'].__class__):
claim_type = claim_type.id
if claim_type == self.env.ref('crm_claim_type.'
'crm_claim_type_supplier').id:
try:
warranty_duration = product.seller_ids[0].warranty_duration
except IndexError:
raise ProductNoSupplier
else:
warranty_duration = product.warranty
limit = self.warranty_limit(invoice_date, warranty_duration)
if warranty_duration > 0:
claim_date = datetime.strptime(claim_date,
DEFAULT_SERVER_DATETIME_FORMAT)
if limit < claim_date:
warning = 'expired'
else:
warning = 'valid'
return {'guarantee_limit': limit.strftime(DEFAULT_SERVER_DATE_FORMAT),
'warning': warning}
def set_warranty_limit(self):
self.ensure_one()
claim = self.claim_id
invoice_id = self.invoice_line_id and self.invoice_line_id.invoice_id \
or claim.invoice_id
try:
values = self._warranty_limit_values(
invoice_id, claim.claim_type,
self.product_id, claim.date)
except InvoiceNoDate:
raise exceptions.Warning(
_('Error'), _('Cannot find any date for invoice. '
'Must be a validated invoice.'))
except ProductNoSupplier:
raise exceptions.Warning(
_('Error'), _('The product has no supplier configured.'))
self.write(values)
return True
@api.model
def auto_set_warranty(self):
""" Set warranty automatically
if the user has not himself pressed on 'Calculate warranty state'
button, it sets warranty for him"""
for line in self:
if not line.warning:
line.set_warranty()
return True
@api.returns('stock.location')
def get_destination_location(self, product_id, warehouse_id):
"""
Compute and return the destination location to take
for a return. Always take 'Supplier' one when return type different
from company.
"""
location_dest_id = warehouse_id.lot_stock_id
if product_id.seller_ids:
seller = product_id.seller_ids[0]
if seller.warranty_return_partner != 'company' \
and seller.name and \
seller.name.property_stock_supplier:
location_dest_id = seller.name.property_stock_supplier
return location_dest_id
def _warranty_return_address_values(self, product, company, warehouse):
"""
Return the partner to be used as return destination and
the destination stock location of the line in case of return.
We can have various cases here:
- company or other: return to company partner or
crm_return_address_id if specified
- supplier: return to the supplier address
"""
if not (product and company and warehouse):
return {
'warranty_return_partner': False,
'warranty_type': False,
'location_dest_id': False
}
sellers = product.seller_ids
if sellers:
seller = sellers[0]
return_address_id = seller.warranty_return_address.id
return_type = seller.warranty_return_partner
else:
# when no supplier is configured, returns to the company
return_address = (company.crm_return_address_id or
company.partner_id)
return_address_id = return_address.id
return_type = 'company'
location_dest = self.get_destination_location(product, warehouse)
return {
'warranty_return_partner': return_address_id,
'warranty_type': return_type,
'location_dest_id': location_dest.id
}
def set_warranty_return_address(self):
self.ensure_one()
claim = self.claim_id
values = self._warranty_return_address_values(
self.product_id, claim.company_id, claim.warehouse_id)
self.write(values)
return True
@api.multi
def set_warranty(self):
"""
Calculate warranty limit and address
"""
for line_id in self:
if not line_id.product_id:
raise exceptions.Warning(
_('Error'), _('Please set product first'))
if not line_id.invoice_line_id:
raise exceptions.Warning(
_('Error'), _('Please set invoice first'))
line_id.set_warranty_limit()
line_id.set_warranty_return_address()
@api.model
def _get_sequence_number(self):
"""
@return the value of the sequence for the number field in the
claim.line model.
"""
return self.env['ir.sequence'].get('claim.line')
@api.model
def create(self, vals):
"""
@return write the identify number once the claim line is create.
"""
vals = vals or {}
if ('number' not in vals) or (vals.get('number', False) == '/'):
vals['number'] = self._get_sequence_number()
res = super(ClaimLine, self).create(vals)
return res
@api.multi
def _get_display_name(self):
res = []
for line_id in self:
res.append(
(line_id.id, "%s - %s" %
(line_id.claim_id.code, line_id.name)))
return res

View File

@@ -0,0 +1,198 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Eezee-It, MONK Software, Vauxoo
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli,
# Osval Reyes, Yanina Aular
#
# 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 import _, api, exceptions, fields, models
from .invoice_no_date import InvoiceNoDate
from .product_no_supplier import ProductNoSupplier
class CrmClaim(models.Model):
_inherit = 'crm.claim'
def _get_default_warehouse(self):
company_id = self.env.user.company_id.id
wh_obj = self.env['stock.warehouse']
wh = wh_obj.search([('company_id', '=', company_id)], limit=1)
if not wh:
raise exceptions.Warning(
_('There is no warehouse for the current user\'s company.'))
return wh
@api.multi
def name_get(self):
res = []
for claim in self:
code = claim.code and str(claim.code) or ''
res.append((claim.id, '[' + code + '] ' + claim.name))
return res
company_id = fields.Many2one(change_default=True,
default=lambda self:
self.env['res.company']._company_default_get(
'crm.claim'))
claim_line_ids = fields.One2many('claim.line', 'claim_id',
string='Return lines')
planned_revenue = fields.Float('Expected revenue')
planned_cost = fields.Float('Expected cost')
real_revenue = fields.Float()
real_cost = fields.Float()
invoice_ids = fields.One2many('account.invoice', 'claim_id', 'Refunds',
copy=False)
picking_ids = fields.One2many('stock.picking', 'claim_id', 'RMA',
copy=False)
invoice_id = fields.Many2one('account.invoice', string='Invoice',
help='Related original Cusotmer invoice')
pick = fields.Boolean('Pick the product in the store')
delivery_address_id = fields.Many2one('res.partner',
string='Partner delivery address',
help="This address will be used to "
"deliver repaired or replacement "
"products.")
sequence = fields.Integer(default=lambda *args: 1)
warehouse_id = fields.Many2one('stock.warehouse', string='Warehouse',
required=True,
default=_get_default_warehouse)
rma_number = fields.Char(size=128, help='RMA Number provided by supplier')
@api.model
def _get_claim_type_default(self):
claim_type = self.env['crm.claim.type'].search([])
return claim_type[0] if claim_type else self.env['crm.claim.type']
claim_type = \
fields.Many2one(default=_get_claim_type_default,
help="Claim classification",
required=True)
@api.onchange('invoice_id', 'warehouse_id', 'claim_type', 'date')
def _onchange_invoice_warehouse_type_date(self):
context = self.env.context
claim_line = self.env['claim.line']
invoice_lines = self.invoice_id.invoice_line
if not self.warehouse_id:
self.warehouse_id = self._get_default_warehouse()
claim_type = self.claim_type
claim_date = self.date
warehouse = self.warehouse_id
company = self.company_id
create_lines = context.get('create_lines')
def warranty_values(invoice, product):
values = {}
try:
warranty = claim_line._warranty_limit_values(
invoice, claim_type, product, claim_date)
except (InvoiceNoDate, ProductNoSupplier):
# we don't mind at this point if the warranty can't be
# computed and we don't want to block the user
values.update({'guarantee_limit': False, 'warning': False})
else:
values.update(warranty)
warranty_address = claim_line._warranty_return_address_values(
product, company, warehouse)
values.update(warranty_address)
return values
if create_lines: # happens when the invoice is changed
claim_lines = []
for invoice_line in invoice_lines:
location_dest = claim_line.get_destination_location(
invoice_line.product_id, warehouse)
line = {
'name': invoice_line.name,
'claim_origin': "none",
'invoice_line_id': invoice_line.id,
'product_id': invoice_line.product_id.id,
'product_returned_quantity': invoice_line.quantity,
'unit_sale_price': invoice_line.price_unit,
'location_dest_id': location_dest.id,
'state': 'draft',
}
line.update(warranty_values(invoice_line.invoice_id,
invoice_line.product_id))
claim_lines.append((0, 0, line))
value = self._convert_to_cache(
{'claim_line_ids': claim_lines}, validate=False)
self.update(value)
if self.invoice_id:
self.delivery_address_id = self.invoice_id.partner_id.id
@api.model
def message_get_reply_to(self):
""" Override to get the reply_to of the parent project. """
return [claim.section_id.message_get_reply_to()[0]
if claim.section_id else False
for claim in self.sudo()]
@api.multi
def message_get_suggested_recipients(self):
recipients = super(CrmClaim, self).message_get_suggested_recipients()
try:
for claim in self:
if claim.partner_id:
self._message_add_suggested_recipient(
recipients, claim,
partner=claim.partner_id, reason=_('Customer'))
elif claim.email_from:
self._message_add_suggested_recipient(
recipients, claim,
email=claim.email_from, reason=_('Customer Email'))
except exceptions.AccessError:
# no read access rights -> just ignore suggested recipients
# because this imply modifying followers
pass
return recipients
def _get_sequence_number(self, code_id):
claim_type_code = self.env['crm.claim.type'].\
browse(code_id).ir_sequence_id.code
sequence = self.env['ir.sequence']
return claim_type_code and sequence.get(claim_type_code) or '/'
@api.model
def create(self, values):
values = values or {}
if 'code' not in values or not values.get('code') \
or values.get('code') == '/':
values['code'] = self._get_sequence_number(values['claim_type'])
return super(CrmClaim, self).create(values)
@api.multi
def copy(self, default=None):
self.ensure_one()
default = default or {}
std_default = {
'code': '/'
}
std_default.update(default)
return super(CrmClaim, self).copy(default=std_default)

View File

@@ -1,527 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Eezee-It, MONK Software
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli
#
# 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/>.
#
##############################################################################
import math
import calendar
from datetime import datetime
from dateutil.relativedelta import relativedelta
from openerp import models, fields, api, exceptions
from openerp.tools.misc import (DEFAULT_SERVER_DATE_FORMAT,
DEFAULT_SERVER_DATETIME_FORMAT)
from openerp.tools.translate import _
class InvoiceNoDate(Exception):
""" Raised when a warranty cannot be computed for a claim line
because the invoice has no date. """
class ProductNoSupplier(Exception):
""" Raised when a warranty cannot be computed for a claim line
because the product has no supplier. """
class SubstateSubstate(models.Model):
""" To precise a state (state=refused; substates= reason 1, 2,...) """
_name = "substate.substate"
_description = "substate that precise a given state"
name = fields.Char(string='Sub state', required=True)
substate_descr = fields.Text(
string='Description',
help="To give more information about the sub state")
class ClaimLine(models.Model):
"""
Class to handle a product return line (corresponding to one invoice line)
"""
_name = "claim.line"
_description = "List of product to return"
# Comment written in a claim.line to know about the warranty status
WARRANT_COMMENT = {
'valid': "Valid",
'expired': "Expired",
'not_define': "Not Defined"}
# Method to calculate total amount of the line : qty*UP
@api.one
def _line_total_amount(self):
self.return_value = (self.unit_sale_price *
self.product_returned_quantity)
def get_warranty_return_partner(self):
return self.env['product.supplierinfo'].get_warranty_return_partner()
name = fields.Char(string='Description', required=True, default=None)
claim_origine = fields.Selection(
[('none', 'Not specified'),
('legal', 'Legal retractation'),
('cancellation', 'Order cancellation'),
('damaged', 'Damaged delivered product'),
('error', 'Shipping error'),
('exchange', 'Exchange request'),
('lost', 'Lost during transport'),
('other', 'Other')
],
string='Claim Subject', required=True,
help="To describe the line product problem")
claim_descr = fields.Text(
string='Claim description',
help="More precise description of the problem")
product_id = fields.Many2one(
'product.product', string='Product', help="Returned product")
product_returned_quantity = fields.Float(
string='Quantity', digits=(12, 2), help="Quantity of product returned")
unit_sale_price = fields.Float(
string='Unit sale price', digits=(12, 2),
help="Unit sale price of the product. Auto filled if retrun done "
"by invoice selection. Be careful and check the automatic "
"value as don't take into account previous refunds, invoice "
"discount, can be for 0 if product for free,...")
return_value = fields.Float(
string='Total return', compute='_line_total_amount',
help="Quantity returned * Unit sold price",)
prodlot_id = fields.Many2one(
'stock.production.lot',
string='Serial/Lot n°', help="The serial/lot of the returned product")
applicable_guarantee = fields.Selection(
[('us', 'Company'),
('supplier', 'Supplier'),
('brand', 'Brand manufacturer')],
string='Warranty type')
guarantee_limit = fields.Date(
string='Warranty limit',
readonly=True,
help="The warranty limit is computed as: invoice date + warranty "
"defined on selected product.")
warning = fields.Char(
string='Warranty',
readonly=True,
help="If warranty has expired")
warranty_type = fields.Selection(
get_warranty_return_partner,
string='Warranty type',
readonly=True,
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)")
claim_id = fields.Many2one(
'crm.claim',
string='Related claim',
help="To link to the case.claim object")
state = fields.Selection(
[('draft', 'Draft'),
('refused', 'Refused'),
('confirmed', 'Confirmed, waiting for product'),
('in_to_control', 'Received, to control'),
('in_to_treate', 'Controlled, to treate'),
('treated', 'Treated')],
string='State',
default="draft")
substate_id = fields.Many2one(
'substate.substate',
string='Sub state',
help="Select a sub state to precise the standard state. Example 1:"
" state = refused; substate could be warranty over, not in "
"warranty, no problem,... . Example 2: state = to treate; "
"substate could be to refund, to exchange, to repair,...")
last_state_change = fields.Date(
string='Last change',
help="To set the last state / substate change")
invoice_line_id = fields.Many2one(
'account.invoice.line',
string='Invoice Line',
help='The invoice line related to the returned product')
refund_line_id = fields.Many2one(
'account.invoice.line',
string='Refund Line',
copy=False,
help='The refund line related to the returned product')
move_in_id = fields.Many2one(
'stock.move',
string='Move Line from picking in',
copy=False,
help='The move line related to the returned product')
move_out_id = fields.Many2one(
'stock.move',
string='Move Line from picking out',
copy=False,
help='The move line related to the returned product')
location_dest_id = fields.Many2one(
'stock.location',
string='Return Stock Location',
help='The return stock location of the returned product')
@staticmethod
def warranty_limit(start, warranty_duration):
""" Take a duration in float, return the duration in relativedelta
``relative_delta(months=...)`` only accepts integers.
We have to extract the decimal part, and then, extend the delta with
days.
"""
decimal_part, months = math.modf(warranty_duration)
months = int(months)
# If we have a decimal part, we add the number them as days to
# the limit. We need to get the month to know the number of
# days.
delta = relativedelta(months=months)
monthday = start + delta
__, days_month = calendar.monthrange(monthday.year, monthday.month)
# ignore the rest of the days (hours) since we expect a date
days = int(days_month * decimal_part)
return start + relativedelta(months=months, days=days)
def _warranty_limit_values(self, invoice, claim_type, product, claim_date):
if not (invoice and claim_type and product and claim_date):
return {'guarantee_limit': False, 'warning': False}
date_invoice = invoice.date_invoice
if not date_invoice:
raise InvoiceNoDate
warning = 'not_define'
date_invoice = datetime.strptime(date_invoice,
DEFAULT_SERVER_DATE_FORMAT)
if isinstance(claim_type, self.env['crm.claim.type'].__class__):
claim_type = claim_type.id
if claim_type == self.env.ref('crm_claim_type.'
'crm_claim_type_supplier').id:
try:
warranty_duration = product.seller_ids[0].warranty_duration
except IndexError:
raise ProductNoSupplier
else:
warranty_duration = product.warranty
limit = self.warranty_limit(date_invoice, warranty_duration)
if warranty_duration > 0:
claim_date = datetime.strptime(claim_date,
DEFAULT_SERVER_DATETIME_FORMAT)
if limit < claim_date:
warning = 'expired'
else:
warning = 'valid'
return {'guarantee_limit': limit.strftime(DEFAULT_SERVER_DATE_FORMAT),
'warning': warning}
def set_warranty_limit(self):
self.ensure_one()
claim = self.claim_id
try:
values = self._warranty_limit_values(
claim.invoice_id, claim.claim_type,
self.product_id, claim.date)
except InvoiceNoDate:
raise exceptions.Warning(
_('Error'), _('Cannot find any date for invoice. '
'Must be a validated invoice.'))
except ProductNoSupplier:
raise exceptions.Warning(
_('Error'), _('The product has no supplier configured.'))
self.write(values)
return True
@api.multi
def auto_set_warranty(self):
""" Set warranty automatically
if the user has not himself pressed on 'Calculate warranty state'
button, it sets warranty for him"""
for line in self:
if not line.warning:
line.set_warranty()
return True
@api.returns('stock.location')
def get_destination_location(self, product, warehouse):
"""
Compute and return the destination location to take
for a return. Always take 'Supplier' one when return type different
from company.
"""
if isinstance(warehouse, int):
location_dest_id = self.env['stock.warehouse']\
.browse(warehouse).lot_stock_id
else:
location_dest_id = warehouse.lot_stock_id
if isinstance(product, int):
product = self.env['product.product']\
.browse(product)
try:
seller = product.seller_ids[0]
if seller.warranty_return_partner != 'company':
location_dest_id = seller.name.property_stock_supplier
finally:
return location_dest_id
@api.onchange('product_id', 'invoice_line_id')
def _onchange_product_invoice_line(self):
product = self.product_id
invoice_line = self.invoice_line_id
context = self.env.context
claim = context.get('claim_id')
company_id = context.get('company_id')
warehouse_id = context.get('warehouse_id')
claim_type = context.get('claim_type')
claim_date = context.get('claim_date')
# claim_exists = not isinstance(claim.id, NewId)
if not claim and not (company_id and warehouse_id and
claim_type and claim_date):
# if we have a claim_id, we get the info from there,
# otherwise we get it from the args (on creation typically)
return False
if not (product and invoice_line):
return False
invoice = invoice_line.invoice_id
claim_line_model = self.env['claim.line']
if claim:
claim = self.env['crm.claim'].browse(claim)
company = claim.company_id
warehouse = claim.warehouse_id
claim_type = claim.claim_type
claim_date = claim.date
else:
warehouse_obj = self.env['stock.warehouse']
company_obj = self.env['res.company']
company = company_obj.browse(company_id)
warehouse = warehouse_obj.browse(warehouse_id)
values = {}
try:
warranty = claim_line_model._warranty_limit_values(
invoice, claim_type, product, claim_date)
except (InvoiceNoDate, ProductNoSupplier):
# we don't mind at this point if the warranty can't be
# computed and we don't want to block the user
values.update({'guarantee_limit': False, 'warning': False})
else:
values.update(warranty)
warranty_address = claim_line_model._warranty_return_address_values(
product, company, warehouse)
values.update(warranty_address)
self.update(values)
def _warranty_return_address_values(self, product, company, warehouse):
"""
Return the partner to be used as return destination and
the destination stock location of the line in case of return.
We can have various cases here:
- company or other: return to company partner or
crm_return_address_id if specified
- supplier: return to the supplier address
"""
if not (product and company and warehouse):
return {
'warranty_return_partner': False,
'warranty_type': False,
'location_dest_id': False
}
sellers = product.seller_ids
if sellers:
seller = sellers[0]
return_address_id = seller.warranty_return_address.id
return_type = seller.warranty_return_partner
else:
# when no supplier is configured, returns to the company
return_address = (company.crm_return_address_id or
company.partner_id)
return_address_id = return_address.id
return_type = 'company'
location_dest = self.get_destination_location(product, warehouse)
return {
'warranty_return_partner': return_address_id,
'warranty_type': return_type,
'location_dest_id': location_dest.id
}
def set_warranty_return_address(self):
self.ensure_one()
claim = self.claim_id
values = self._warranty_return_address_values(
self.product_id, claim.company_id, claim.warehouse_id)
self.write(values)
return True
@api.one
def set_warranty(self):
""" Calculate warranty limit and address """
if not (self.product_id and self.invoice_line_id):
raise exceptions.Warning(
_('Error'), _('Please set product and invoice.'))
self.set_warranty_limit()
self.set_warranty_return_address()
# TODO add the option to split the claim_line in order to manage the same
# product separately
class CrmClaim(models.Model):
_inherit = 'crm.claim'
def _get_default_warehouse(self):
company_id = self.env.user.company_id.id
wh_obj = self.env['stock.warehouse']
wh = wh_obj.search([('company_id', '=', company_id)], limit=1)
if not wh:
raise exceptions.Warning(
_('There is no warehouse for the current user\'s company.'))
return wh
@api.one
def name_get(self):
return (self.id, u'[{}] {}'.format(self.code or '', self.name))
claim_line_ids = fields.One2many('claim.line', 'claim_id',
string='Claim lines')
planned_revenue = fields.Float(string='Expected revenue')
planned_cost = fields.Float(string='Expected cost')
real_revenue = fields.Float(string='Real revenue')
real_cost = fields.Float(string='Real cost')
invoice_ids = fields.One2many('account.invoice', 'claim_id',
string='Refunds',
copy=False)
picking_ids = fields.One2many('stock.picking', 'claim_id',
string='RMA',
copy=False)
invoice_id = fields.Many2one(
'account.invoice',
string='Invoice',
help='Related original Customer invoice')
delivery_address_id = fields.Many2one(
'res.partner',
string='Partner delivery address',
help="This address will be used to deliver repaired or replacement"
"products.")
warehouse_id = fields.Many2one(
'stock.warehouse',
string='Warehouse',
default=_get_default_warehouse,
required=True)
@api.onchange('invoice_id', 'warehouse_id', 'claim_type', 'date')
def _onchange_invoice_warehouse_type_date(self):
context = self.env.context
claim_line_obj = self.env['claim.line']
invoice_lines = self.invoice_id.invoice_line
claim_lines = []
if not self.warehouse_id:
self.warehouse_id = self._get_default_warehouse()
claim_type = self.claim_type
claim_date = self.date
warehouse = self.warehouse_id
company = self.company_id
create_lines = context.get('create_lines')
def warranty_values(invoice, product):
values = {}
try:
warranty = claim_line_obj._warranty_limit_values(
invoice, claim_type, product, claim_date)
except (InvoiceNoDate, ProductNoSupplier):
# we don't mind at this point if the warranty can't be
# computed and we don't want to block the user
values.update({'guarantee_limit': False, 'warning': False})
else:
values.update(warranty)
warranty_address = claim_line_obj._warranty_return_address_values(
product, company, warehouse)
values.update(warranty_address)
return values
if create_lines: # happens when the invoice is changed
for invoice_line in invoice_lines:
location_dest = claim_line_obj.get_destination_location(
invoice_line.product_id, warehouse)
line = {
'name': invoice_line.name,
'claim_origine': "none",
'invoice_line_id': invoice_line.id,
'product_id': invoice_line.product_id.id,
'product_returned_quantity': invoice_line.quantity,
'unit_sale_price': invoice_line.price_unit,
'location_dest_id': location_dest.id,
'state': 'draft',
}
line.update(warranty_values(invoice_line.invoice_id,
invoice_line.product_id))
claim_lines.append((0, 0, line))
value = self._convert_to_cache(
{'claim_line_ids': claim_lines}, validate=False)
self.update(value)
if self.invoice_id:
self.delivery_address_id = self.invoice_id.partner_id.id
@api.multi
def message_get_reply_to(self):
""" Override to get the reply_to of the parent project. """
result = {}
for claim in self.sudo():
section = claim.section_id
if section:
section_reply_to = section.message_get_reply_to()
result[claim.id] = section_reply_to[section.id]
else:
result[claim.id] = False
return result
@api.multi
def message_get_suggested_recipients(self):
recipients = super(CrmClaim, self).message_get_suggested_recipients()
try:
for claim in self:
if claim.partner_id:
self._message_add_suggested_recipient(
recipients, claim,
partner=claim.partner_id, reason=_('Customer'))
elif claim.email_from:
self._message_add_suggested_recipient(
recipients, claim,
email=claim.email_from, reason=_('Customer Email'))
except exceptions.AccessError:
# no read access rights -> just ignore suggested recipients
# because this imply modifying followers
pass
return recipients

View File

@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Eezee-It, MONK Software, Vauxoo
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli,
# Osval Reyes
#
# 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/>.
#
##############################################################################
class InvoiceNoDate(Exception):
"""
Raised when a warranty cannot be computed for a claim line
because the invoice has no date.
"""

View File

@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Vauxoo
# Copyright 2015 Eezee-It, MONK Software
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli
# Osval Reyes <osval@vauxoo.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/>.
#
##############################################################################
class ProductNoSupplier(Exception):
"""
Raised when a warranty cannot be computed for a claim line
because the product has no supplier.
"""

View File

@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Eezee-It, MONK Software
# Copyright 2015 Eezee-It, MONK Software, Vauxoo
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli,
# Osval Reyes
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -21,28 +22,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, api
class StockPicking(models.Model):
_inherit = "stock.picking"
claim_id = fields.Many2one('crm.claim', string='Claim')
@api.model
@api.returns('self', lambda value: value.id)
def create(self, vals):
if ('name' not in vals) or (vals.get('name') == '/'):
vals['name'] = self.env['ir.sequence'].get(self._name)
return super(StockPicking, self).create(vals)
from openerp import api, models
class StockMove(models.Model):
_inherit = "stock.move"
_name = 'stock.move'
_inherit = ['stock.move', 'mail.thread']
@api.model
@api.returns('self', lambda value: value.id)
def create(self, vals):
"""
In case of a wrong picking out, We need to create a new stock_move in a

View File

@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Eezee-It, MONK Software, Vauxoo
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli,
# Osval Reyes
#
# 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 import api, fields, models
class StockPicking(models.Model):
_inherit = "stock.picking"
claim_id = fields.Many2one('crm.claim', 'Claim')
@api.model
def create(self, vals):
if ('name' not in vals) or (vals.get('name') == '/'):
vals['name'] = self.env['ir.sequence'].get(self._name)
return super(StockPicking, self).create(vals)

View File

@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Eezee-It, MONK Software, Vauxoo
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli,
# Osval Reyes
#
# 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 import fields, models
class SubstateSubstate(models.Model):
"""
To precise a state (state=refused; substates= reason 1, 2,...)
"""
_name = "substate.substate"
_description = "substate that precise a given state"
name = fields.Char('Sub state', required=True)
substate_descr = fields.Text('Description',
help="To give more "
"information about the sub state")

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","substate.substate.user","model_substate_substate","base.group_sale_salesman_all_leads","True","True","True",
"access_claim_line_user","claim.line.user","model_claim_line","base.group_sale_salesman_all_leads","True","True","True",
"access_substate_manager","substate.substate.manager","model_substate_substate","base.group_sale_manager","True","True","True","True"
"access_claim_line_manager","claim.line.manager","model_claim_line","base.group_sale_manager","True","True","True","True"
"access_substate_user","substate.substate.user","model_substate_substate","base.group_sale_salesman","True","True","True",
"access_claim_line_user","claim.line.user","model_claim_line","base.group_sale_salesman","True","True","True",
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_substate_user,substate.substate.user,model_substate_substate,base.group_sale_salesman_all_leads,1,1,1,0
access_claim_line_user,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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_substate_user substate.substate.user model_substate_substate base.group_sale_salesman_all_leads True 1 True 1 True 1 0
3 access_claim_line_user claim.line.user model_claim_line base.group_sale_salesman_all_leads True 1 True 1 True 1 0
4 access_substate_manager substate.substate.manager model_substate_substate base.group_sale_manager True 1 True 1 True 1 True 1
5 access_claim_line_manager claim.line.manager model_claim_line base.group_sale_manager True 1 True 1 True 1 True 1
6 access_substate_user substate.substate.user model_substate_substate base.group_sale_salesman True 1 True 1 True 1 0
7 access_claim_line_user claim.line.user model_claim_line base.group_sale_salesman True 1 True 1 True 1 0

View File

@@ -31,6 +31,7 @@ class TestPickingCreation(common.TransactionCase):
super(TestPickingCreation, self).setUp()
self.wizard_make_picking = self.env['claim_make_picking.wizard']
self.stockpicking = self.env['stock.picking']
claim = self.env['crm.claim']
self.product_id = self.env.ref('product.product_product_4')
@@ -143,13 +144,45 @@ class TestPickingCreation(common.TransactionCase):
self.warehouse_id.lot_stock_id,
"Incorrect destination location")
def test_copy(self):
new_claim = self.claim_id.copy()
self.assertNotEqual(new_claim.code, self.claim_id.code)
def create_invoice(self):
sale_order_id = self.env['sale.order'].create({
'partner_id': self.ref('base.res_partner_9'),
'client_order_ref': 'TEST_SO',
'order_policy': 'manual',
'order_line': [(0, 0, {
'product_id': self.ref('product.product_product_8'),
'product_uom_qty': 2
})]
})
sale_order_id.action_button_confirm()
sale_order_id.action_invoice_create()
self.assertTrue(sale_order_id.invoice_ids)
invoice_id = sale_order_id.invoice_ids
invoice_id.signal_workflow('invoice_open')
return invoice_id
def test_mail_thread_recipient(self):
recipients = self.claim_id.message_get_suggested_recipients()
recipients = recipients[self.claim_id.id]
recipient_ids = [r[0] for r in recipients]
self.assertEqual(recipient_ids,
[self.claim_id.partner_id.id])
def test_03_invoice_refund(self):
claim_id = self.env['crm.claim'].browse(
self.ref('crm_claim.crm_claim_6'))
invoice_id = self.env['account.invoice'].browse(
self.ref('account.invoice_5'))
claim_id.write({
'invoice_id': invoice_id.id
})
claim_id.with_context({'create_lines': True}).\
_onchange_invoice_warehouse_type_date()
invoice_refund_wizard_id = self.env['account.invoice.refund'].\
with_context({
'active_ids': [claim_id.invoice_id.id],
'claim_line_ids':
[[4, cl.id, False] for cl in claim_id.claim_line_ids],
}).create({
'description': "Testing Invoice Refund for Claim"
})
res = invoice_refund_wizard_id.invoice_refund()
self.assertTrue(res)
self.assertEquals(res['res_model'], 'account.invoice')
self.assertEquals(eval(res['context'])['type'], 'out_refund')

View File

@@ -0,0 +1,196 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="view_crm_claim_lines_filter" model="ir.ui.view">
<field name="name">CRM - Claims Search</field>
<field name="model">claim.line</field>
<field name="arch" type="xml">
<search string="Search Claims">
<filter icon="terp-check" string="Current" name="current"
domain="[('state','in',('draft', 'refused', 'treated'))]"
separator="1" help="Draft and Open Claims" />
<filter icon="terp-camera_test"
string="In Progress"
domain="[('state','in',('confirmed','in_to_control','in_to_treate'))]"
separator="1" help="In Progress Claims"/>
<separator orientation="vertical"/>
<field name="number"/>
<field name="state" select='1'/>
<field name="substate_id" select='1'/>
<field name="name" select='1'/>
<field name="warning" select='1'/>
<field name="invoice_line_id" select='1' readonly='1'/>
<field name="product_id" select='1'/>
<field name="prodlot_id" select='1'/>
<field name="move_in_id"/>
<newline/>
<group expand="0" string="More">
<field name="last_state_change" select='1'/>
<field name="guarantee_limit" select='1'/>
<field name="return_value" select='1'/>
<field name="name" select='1'/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Invoice" icon="terp-dolar"
domain="[]" help="Invoice"
context="{'group_by':'invoice_id'}" />
<filter string="Product" icon="terp-product"
domain="[]" help="Product"
context="{'group_by':'product_id'}" />
<separator orientation="vertical"/>
<filter string="Substate" icon="terp-stage"
domain="[]" context="{'group_by':'substate_id'}" />
<filter string="Claim n°" icon="terp-emblem-documents"
domain="[]" context="{'group_by':'claim_id'}" />
<filter string="Priority"
name="group_by_priority"
domain="[]"
context="{'group_by':'priority'}"
help="Priority"/>
<filter string="State"
name="group_by_state"
domain="[]"
context="{'group_by':'state'}"
help="Grouping by state"/>
</group>
</search>
</field>
</record>
<record model="ir.ui.view" id="crm_claim_line_tree_view">
<field name="name">CRM - Claims Tree</field>
<field name="model">claim.line</field>
<field name="arch" type="xml">
<tree string="Claim lines">
<field name="claim_id" invisible="1"/>
<field name="number"/>
<field name="state"/>
<field name="substate_id"/>
<field name="product_id"/>
<field name="name"/>
<field name="prodlot_id"/>
<field name="warning"/>
<field name="warranty_type"/>
<field name="warranty_return_partner"/>
<button name="set_warranty" string="Compute Warranty" type="object" icon="gtk-justify-fill"/>
<field name="product_returned_quantity"/>
<field name="claim_origin"/>
<field name="claim_diagnosis"/>
<field name="refund_line_id"/>
<field name="move_in_id"/>
<field name="move_out_id"/>
<field name="priority"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="crm_claim_line_form_view">
<field name="name">CRM - Claim product return line Form</field>
<field name="model">claim.line</field>
<field name="arch" type="xml">
<form string="Claim Line" version="7.0">
<header>
<button name="set_warranty" string="Calculate warranty state" type="object" class="oe_highlight"/>
<field name="state"
widget="statusbar"/>
</header>
<sheet string="Claims">
<div class="oe_title" colspan="4">
<group>
<h1><field name="number" class="oe_inline"/></h1>
</group>
<field name="claim_type" nolabel="1"/>
</div>
<separator string="Problem" colspan="4"/>
<group col="6" colspan="4">
<field name="name" colspan="6"/>
<field name="product_id" readonly="1" colspan="6"/>
<field name="prodlot_id" readonly="1" colspan="6"/>
<field name="claim_origin" colspan="6"/>
<field name="claim_diagnosis" colspan="6"/>
<field name="priority" colspan="6"/>
<field name="product_returned_quantity" invisible="1"/>
<field name="unit_sale_price"/>
<field name="return_value"/>
</group>
<group>
<group string="Warranty">
<field name="guarantee_limit" readonly="1"/>
<field name="warning" readonly="1"/>
<field name="warranty_type" readonly="1"/>
<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="refund_line_id" readonly="1"/>
<field name="move_in_id" readonly="1"/>
<field name="move_out_id" readonly="1"/>
</group>
</group>
<separator string="State" colspan="4"/>
<group col="6" colspan="4">
<field name="substate_id" widget='selection'/>
<field name="last_state_change"/>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</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>
<field name="res_model">claim.line</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="crm_claim_line_tree_view"/>
<field name="search_view_id" ref="view_crm_claim_lines_filter"/>
<field name="context">{'search_default_group_by_priority': True,
'search_default_group_by_state': True}
</field>
</record>
<!-- Menu -->
<menuitem
name="Claim lines"
id="menu_crm_case_claims_claim_lines"
parent="base.menu_aftersale"
action="act_crm_case_claim_lines"
sequence="2"/>
</data>
</openerp>

View File

@@ -0,0 +1,289 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<!-- CLAIM VIEWS -->
<record model="ir.ui.view" id="crm_case_claims_tree_view">
<field name="name">CRM - Claims Tree</field>
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim.crm_case_claims_tree_view"/>
<field name="arch" type="xml">
<field name="stage_id" position="after">
<field name="section_id"/>
</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>
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim.view_crm_case_claims_filter"/>
<field name="arch" type="xml">
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}" position="before">
<filter string="Sales Team" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'section_id'}"/>
</filter>
</field>
</record>
<!-- Right side link to orders -->
<act_window
id="act_crm_claim_rma_sale_orders"
name="Quotations and Sales"
res_model="sale.order"
src_model="crm.claim"/>
<act_window
id="act_crm_claim_rma_purchase_orders"
name="Purchases"
res_model="purchase.order"
src_model="crm.claim"/>
<act_window
domain="[('type', 'in', ('in_invoice', 'out_invoice'))]"
id="act_crm_claim_rma_invoice"
name="Invoices"
res_model="account.invoice"
src_model="crm.claim"/>
<act_window
id="act_crm_claim_rma_refunds"
name="Refunds"
res_model="account.invoice"
src_model="crm.claim"
domain="[('type', 'in', ('in_refund', 'out_refund'))]"/>
<act_window
id="act_crm_claim_rma_picking_in"
name="Incoming Shipment and Returns"
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>
<field name="inherit_id" ref="crm_claim.crm_case_claims_form_view"/>
<field name="arch" type="xml">
<!-- Header/workflow Buttons -->
<xpath expr="//field[@name='stage_id']" position="before">
<button name="%(action_claim_picking_in)d"
string="New Products Return"
class="oe_inline"
type="action" target="new"
context="{'warehouse_id': warehouse_id,
'partner_id': partner_id}"/>
<button name="%(action_claim_picking_out)d"
class="oe_inline"
string="New Delivery"
type="action" target="new"
context="{'warehouse_id': warehouse_id,
'partner_id': partner_id}"/>
<button name="%(account.action_account_invoice_refund)d"
class="oe_inline"
type='action' string='New Refund'
context="{
'invoice_ids': [invoice_id],
'claim_line_ids': claim_line_ids,
'description': name,
'claim_id': id,
}"/>
</xpath>
<xpath expr="//sheet/group[2]" position="replace">
<group colspan="4" col="4" groups="base.group_user">
<field name="warehouse_id" />
<field name="date"/>
<field name="user_id" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_salesman_all_leads']}"/>
<field name="priority" widget="priority"/>
<field name="date_deadline"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</group>
</xpath>
<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>
<!-- Smart buttons -->
<xpath expr="//sheet[@string='Claims']/group[1]" position="after">
<div class="oe_right oe_button_box" name="buttons">
<button class="oe_inline oe_stat_button"
name="%(act_crm_claim_rma_sale_orders)d" type="action"
icon="fa-strikethrough"
string="Sales"
attrs="{'invisible': ['|',('partner_id','=', False)]}"
context="{'search_default_partner_id': [partner_id],
'search_default_user_id':False}" />
<button class="oe_inline oe_stat_button"
name="%(act_crm_claim_rma_purchase_orders)d"
type="action"
icon="fa-shopping-cart"
string="Purchases"
attrs="{'invisible': ['|',('partner_id','=', False)]}"
context="{'search_default_partner_id': [partner_id],
'search_default_user_id':False}"
/>
<button class="oe_inline oe_stat_button"
name="%(act_crm_claim_rma_invoice)d"
type="action"
string="Invoices"
icon="fa-pencil-square"
attrs="{'invisible': ['|',('partner_id','=', False)]}"
context="{'search_default_partner_id': [partner_id],
'group_by':'type',
'search_default_user_id':False}" />
<button class="oe_inline oe_stat_button"
name="%(act_crm_claim_rma_refunds)d"
type="action"
string="Refunds"
icon="fa-file-text"
attrs="{'invisible': ['|',('partner_id','=', False),
('claim_type','in', ['customer','other'])]}"
context="{'search_default_partner_id': [partner_id],
'group_by':'type',
'search_default_user_id':False}" />
<button class="oe_inline oe_stat_button"
icon="fa-reply"
name="%(act_crm_claim_rma_picking_in)d"
type="action"
string="Returns"
attrs="{'invisible': ['|',('partner_id','=', False),
('claim_type','in', ['supplier','other'])]}"
context="{'search_default_claim_id': active_id,
'search_default_user_id':False}"/>
</div>
</xpath>
<xpath expr="//sheet[@string='Claims']/group[1]" position="replace">
<div class="oe_title oe_left">
<h1><field name="code"/></h1>
<div class="oe_edit_only">
<label for="name"/>
</div>
<h1><small><field name="name"/></small></h1>
</div>
</xpath>
<xpath expr="//page[@string='Claim Description']//group[1]"
position="inside">
<field name="pick" string="Pick the product in the store"/>
<field name="delivery_address_id"
string="Partner delivery address"
domain="[('id','child_of',partner_id)]"
attrs="{'invisible': ['|',('pick','=', True)],
'required': [('pick','=', False)]}"
context="{'tree_view_ref': 'crm_claim_rma.view_partner_contact_tree',
'search_default_parent_id': partner_id}"/>
<field name="invoice_id" domain="['|',('commercial_partner_id','=',partner_id),('partner_id','=',partner_id)]" context="{'create_lines': True}"/>
</xpath>
<xpath expr="//page[@string='Claim Description']//group[1]"
position="after">
<div name="serial">
<!-- Place for mass return button from crm_rma_lot_mass_return -->
</div>
<separator colspan="2" string="Product Returns"/>
<field name="claim_line_ids">
<tree string="Returned lines" create="false">
<field name="claim_id" invisible="1"/>
<field name="state"/>
<field name="product_id"/>
<field name="name"/>
<field name="prodlot_id"/>
<field name="invoice_line_id">
<attribute name="readonly">1</attribute>
</field>
<field name="warning"/>
<field name="warranty_type"/>
<button name="set_warranty" string="Compute Warranty"
type="object" icon="gtk-justify-fill"/>
<field name="claim_origin"/>
<field name="claim_diagnosis"/>
</tree>
</field>
</xpath>
<!-- Remove domain and widget attributes -->
<field name="categ_id" widget="selection" position="replace">
<field name="categ_id"/>
</field>
<!-- New tabs for products return and generated documents -->
<page string="Follow Up" position="before">
<page string="Generated Documents">
<separator colspan="2" string="Refunds"/>
<field name="invoice_ids" colspan="4" readonly="1"/>
<separator colspan="2" string="Receptions / Deliveries"/>
<field name="picking_ids" colspan="4" readonly="1"/>
</page>
</page>
</field>
</record>
<record model="ir.actions.act_window" id="crm_claim.crm_case_categ_claim0">
<field name="context">{"search_default_user_id":uid, "stage_type":'claim'}</field>
</record>
<!-- substates action -->
<record id="act_crm_claim_substates" model="ir.actions.act_window">
<field name="name">Claim line substates</field>
<field name="res_model">substate.substate</field>
<field name="view_type">form</field>
</record>
<menuitem
name="Claim line substates"
id="menu_crm_case_claims_claim_line_substates"
parent="crm_claim.menu_config_claim"
action="act_crm_claim_substates"
sequence="2"/>
<!-- Update account invoice !-->
<record id="crm_claim_rma_form" model="ir.ui.view">
<field name="name">CRM Claim RMA</field>
<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>
<record id="search_crm_claim_rma_number" model="ir.ui.view">
<field name="name">CRM - Claims Search</field>
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim.view_crm_case_claims_filter"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="after">
<field name="rma_number"/>
</xpath>
</field>
</record>
<record id="tree_crm_claim_rma_number" model="ir.ui.view">
<field name="name">CRM - Claims Tree</field>
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim.crm_case_claims_tree_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="after">
<field name="rma_number"/>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="crm_case_claims_form_view">
<field name="name">CRM - Claims Form</field>
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim_type.crm_case_claims_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='claim_type']" position="attributes">
<attribute name="context">{'create_lines': False}</attribute>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -1,409 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- Claim line views -->
<!-- SEARCH -->
<record id="view_crm_claim_lines_filter" model="ir.ui.view">
<field name="name">CRM - Claims Search</field>
<field name="model">claim.line</field>
<field name="arch" type="xml">
<search string="Search Claims">
<filter icon="terp-check" string="Current" name="current"
domain="[('state','in',('draft', 'refused', 'treated'))]"
separator="1" help="Draft and Open Claims" />
<filter icon="terp-camera_test"
string="In Progress"
domain="[('state','in',('confirmed','in_to_control','in_to_treate'))]"
separator="1" help="In Progress Claims"/>
<separator orientation="vertical"/>
<field name="state" select='1'/>
<field name="substate_id" select='1'/>
<field name="name" select='1'/>
<field name="warning" select='1'/>
<field name="invoice_line_id" select='1'/>
<field name="product_id" select='1'/>
<field name="prodlot_id" select='1'/>
<newline/>
<group expand="0" string="More">
<field name="last_state_change" select='1'/>
<field name="guarantee_limit" select='1'/>
<field name="return_value" select='1'/>
<field name="name" select='1'/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Invoice" icon="terp-dolar"
domain="[]" help="Invoice"
context="{'group_by':'invoice_id'}"/>
<filter string="Product" icon="terp-product"
domain="[]" help="Product"
context="{'group_by':'product_id'}"/>
<separator orientation="vertical"/>
<filter string="Substate" icon="terp-stage"
domain="[]" context="{'group_by':'substate_id'}"/>
<filter string="Claim n°" icon="terp-emblem-documents"
domain="[]" context="{'group_by':'claim_id'}"/>
</group>
</search>
</field>
</record>
<!-- TREE -->
<record model="ir.ui.view" id="crm_claim_line_tree_view">
<field name="name">CRM - Claims Tree</field>
<field name="model">claim.line</field>
<field name="arch" type="xml">
<tree string="Claim lines">
<field name="claim_id" invisible="1"/>
<field name="state"/>
<field name="substate_id"/>
<field name="product_id"/>
<field name="name"/>
<field name="prodlot_id"/>
<field name="warning"/>
<field name="warranty_type"/>
<field name="warranty_return_partner"/>
<button name="set_warranty" string="Compute Waranty" type="object" icon="gtk-justify-fill"/>
<field name="product_returned_quantity"/>
<field name="claim_origine"/>
<field name="refund_line_id"/>
<field name="move_in_id"/>
<field name="move_out_id"/>
</tree>
</field>
</record>
<!-- FORM -->
<record model="ir.ui.view" id="crm_claim_line_form_view">
<field name="name">CRM - Claim product return line Form</field>
<field name="model">claim.line</field>
<field name="arch" type="xml">
<form string="Claim Line" version="7.0">
<header>
<button name="set_warranty" string="Calculate warranty state" type="object" class="oe_highlight"/>
</header>
<sheet string="Claims">
<div class="oe_title">
<group>
<label for="name" class="oe_edit_only"/>
<h1><field name="name"/></h1>
</group>
</div>
<group>
<group string="Returned good">
<field name="product_returned_quantity"/>
<field name="product_id" />
<field name="prodlot_id"/>
<field name="unit_sale_price"/>
<field name="return_value"/>
</group>
<group string="Linked Document">
<field name="claim_id"/>
<field name="invoice_line_id"/>
<field name="refund_line_id"/>
<field name="move_in_id"/>
<field name="move_out_id"/>
</group>
</group>
<group>
<group string="Problem">
<field name="claim_origine" nolabel="1" colspan="4"/>
<field name="claim_descr" nolabel="1" colspan="4"/>
</group>
<group string="Warranty">
<field name="guarantee_limit"/>
<field name="warning"/>
<field name="warranty_return_partner"/>
<field name="warranty_type"/>
</group>
</group>
<separator string="State" colspan="4"/>
<group col="6" colspan="4">
<field name="state"/>
<field name="substate_id" widget='selection'/>
<field name="last_state_change"/>
</group>
</sheet>
</form>
</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 VIEWS -->
<record model="ir.ui.view" id="crm_case_claims_tree_view">
<field name="name">CRM - Claims Tree</field>
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim.crm_case_claims_tree_view"/>
<field name="arch" type="xml">
<field name="stage_id" position="after">
<field name="section_id"/>
</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>
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim.view_crm_case_claims_filter"/>
<field name="arch" type="xml">
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}" position="before">
<filter string="Sales Team" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'section_id'}"/>
</filter>
</field>
</record>
<!-- Right side link to orders -->
<act_window
id="act_crm_claim_rma_sale_orders"
name="Quotations and Sales"
res_model="sale.order"
src_model="crm.claim"/>
<!-- Right side link to invoices -->
<act_window
domain="[('type', '=', 'out_invoice')]"
id="act_crm_claim_rma_invoice_out"
name="Customer Invoices"
res_model="account.invoice"
src_model="crm.claim"/>
<!-- Right side link to invoices -->
<act_window
domain="[('type', '=', 'in_invoice')]"
id="act_crm_claim_rma_invoice_in"
name="Supplier Invoices"
res_model="account.invoice"
src_model="crm.claim"/>
<!-- Right side link to refunds -->
<act_window
domain="[('type', '=', 'out_refund')]"
id="act_crm_claim_rma_refunds_out"
name="Customer Refunds"
res_model="account.invoice"
src_model="crm.claim"/>
<!-- Right side link to refunds -->
<act_window
domain="[('type', '=', 'in_refund')]"
id="act_crm_claim_rma_refunds_in"
name="Supplier Refunds"
res_model="account.invoice"
src_model="crm.claim"/>
<!-- Right side link to picking in -->
<act_window
domain="[('picking_type_id.code', '=', 'incoming')]"
id="act_crm_claim_rma_picking_in"
name="Incoming Shipment and Returns"
res_model="stock.picking"
src_model="crm.claim"/>
<!-- Right side link to picking out -->
<act_window
domain="[('picking_type_id.code', '=', 'outgoing')]"
id="act_crm_claim_rma_picking_out"
name="Deliveries"
res_model="stock.picking"
src_model="crm.claim"/>
<record model="ir.actions.act_window" id="crm_claim.crm_case_categ_claim0">
<field name="context">{"search_default_user_id":uid, "stage_type":'claim'}</field>
</record>
<!-- Claim lines action -->
<record model="ir.actions.act_window" id="act_crm_case_claim_lines">
<field name="name">Claim lines</field>
<field name="res_model">claim.line</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="crm_claim_line_tree_view"/>
<field name="search_view_id" ref="view_crm_claim_lines_filter"/>
</record>
<!-- substates action -->
<record id="act_crm_claim_substates" model="ir.actions.act_window">
<field name="name">Claim line substates</field>
<field name="res_model">substate.substate</field>
<field name="view_type">form</field>
</record>
<!-- Menu -->
<menuitem
name="Claim lines"
id="menu_crm_case_claims_claim_lines"
parent="base.menu_aftersale"
action="act_crm_case_claim_lines"
sequence="2"/>
<menuitem
name="Claim line substates"
id="menu_crm_case_claims_claim_line_substates"
parent="crm_claim.menu_config_claim"
action="act_crm_claim_substates"
sequence="2"/>
<record model="ir.ui.view" id="crm_case_claims_form_view">
<field name="name">CRM - Claims Form</field>
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim_type.crm_case_claims_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='claim_type']" position="attributes">
<attribute name="context">{'create_lines': False}</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="crm_claim_rma_form_view">
<field name="name">CRM - Claims Form</field>
<field name="model">crm.claim</field>
<field name="inherit_id" ref="crm_claim.crm_case_claims_form_view"/>
<field name="arch" type="xml">
<!-- Header/workflow Buttons -->
<field name="stage_id" position="before">
<button
name="%(action_claim_picking_in)d"
type="action" string="New Products Return"
attrs="{'invisible': [('partner_id','=', False)]}"
context="{'warehouse_id': warehouse_id, 'partner_id': partner_id}"/>
<button
name="%(action_claim_picking_out)d"
type="action"
string="New Delivery"
attrs="{'invisible': [('partner_id','=', False)]}"
context="{'warehouse_id': warehouse_id, 'partner_id': partner_id}"/>
<button
name="%(account.action_account_invoice_refund)d"
type='action'
string='New Refund'
attrs="{'invisible': [('invoice_id','=', False)]}"
context="{'invoice_ids': [invoice_id], 'claim_line_ids': claim_line_ids, 'description': name, 'claim_id': id}"/>
</field>
<field name="date_deadline" position="after">
<field name="warehouse_id" context="{'create_lines': False}"/>
</field>
<field name="date" position="replace"/>
<field name="user_id" position="before">
<field name="date" context="{'create_lines': False}"/>
</field>
<!-- Smart buttons -->
<xpath expr="//sheet[@string='Claims']/group[1]" position="after">
<div class="oe_right oe_button_box" style="width: 300px;" name="buttons">
<button name="%(act_crm_claim_rma_sale_orders)d" type="action"
string="Quotation/Sales"
icon="fa-strikethrough"
class="oe_stat_button"
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in',
[%(crm_claim_type.crm_claim_type_supplier)d,%(crm_claim_type.crm_claim_type_other)d])]}"
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"/>
<button name="%(act_crm_claim_rma_invoice_out)d" type="action"
string="Invoices"
icon="fa-pencil-square-o"
class="oe_stat_button"
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in',
[%(crm_claim_type.crm_claim_type_supplier)d,%(crm_claim_type.crm_claim_type_other)d])]}"
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"/>
<button name="%(act_crm_claim_rma_refunds_out)d" type="action"
string="Refunds"
icon="fa-file-text-o"
class="oe_stat_button"
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in',
[%(crm_claim_type.crm_claim_type_supplier)d,%(crm_claim_type.crm_claim_type_other)d])]}"
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"/>
<button name="%(act_crm_claim_rma_invoice_in)d" type="action"
string="Invoices"
icon="fa-pencil-square-o"
class="oe_stat_button"
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in',
[%(crm_claim_type.crm_claim_type_customer)d,%(crm_claim_type.crm_claim_type_other)d])]}"
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"/>
<button name="%(act_crm_claim_rma_refunds_in)d" type="action"
string="Refunds"
icon="fa-file-text-o"
class="oe_stat_button"
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in',
[%(crm_claim_type.crm_claim_type_customer)d,%(crm_claim_type.crm_claim_type_other)d])]}"
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"/>
<button name="%(act_crm_claim_rma_picking_in)d" type="action"
string="Products"
icon="fa-reply"
class="oe_stat_button"
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in',
[%(crm_claim_type.crm_claim_type_customer)d,%(crm_claim_type.crm_claim_type_other)d])]}"
context="{'search_default_claim_id': active_id,'search_default_user_id':False}"/>
<button name="%(act_crm_claim_rma_picking_out)d" type="action"
string="Deliveries"
icon="fa-truck"
class="oe_stat_button"
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in',
[%(crm_claim_type.crm_claim_type_supplier)d,%(crm_claim_type.crm_claim_type_other)d])]}"
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"/>
</div>
</xpath>
<xpath expr="//sheet[@string='Claims']/group[1]" position="replace">
<div class="oe_title oe_left">
<h1><field name="code"/></h1>
<div class="oe_edit_only">
<label for="name"/>
</div>
<h1><small><field name="name"/></small></h1>
</div>
</xpath>
<!-- Remove domain and widget attributes -->
<field name="categ_id" widget="selection" position="replace">
<field name="categ_id" context="{'object_name': 'crm.claim'}"/>
</field>
<!-- New tabs for products return and generated documents -->
<page string="Follow Up" position="before">
<page string="Product Return">
<group name="Product Return">
<separator string="Product Return" colspan="4"/>
<group>
<field name="company_id" invisible="1"/>
<field name="invoice_id" domain="['|',('commercial_partner_id','=',partner_id),('partner_id','=',partner_id)]" context="{'create_lines': True}"/>
<field name="delivery_address_id" context="{'tree_view_ref': 'crm_claim_rma.view_partner_contact_tree', 'search_default_parent_id': partner_id}"/>
</group>
<div name="serial">
<!-- Place for mass return button from crm_rma_lot_mass_return -->
</div>
<field
name="claim_line_ids"
nolabel="1"
context="{'default_claim_id': active_id, 'form_view_ref': 'crm_claim_rma.crm_claim_line_view_form_embedded'}"/>
</group>
</page>
<page string="Generated Documents">
<separator colspan="2" string="Refunds"/>
<field name="invoice_ids" colspan="4" readonly="1"/>
<separator colspan="2" string="Receptions / Deliveries"/>
<field name="picking_ids" colspan="4" readonly="1"/>
</page>
</page>
</field>
</record>
</data>
</openerp>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<!-- Address list with details to help shipping address selection -->
@@ -8,15 +8,15 @@
<field name="arch" type="xml">
<tree string="Contacts">
<field name="name"/>
<field name="function" invisible="1"/>
<field name="function" invisible="True"/>
<field name="street"/>
<field name="zip"/>
<field name="city"/>
<field name="email"/>
<field name="user_id" invisible="1"/>
<field name="is_company" invisible="1"/>
<field name="user_id" invisible="True"/>
<field name="is_company" invisible="True"/>
<field name="country_id"/>
<field name="parent_id" invisible="1"/>
<field name="parent_id" invisible="True"/>
</tree>
</field>
</record>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- INHERITED VIEW FOR THE OBJECT : stock_picking -->
<record id="picking_in_form" model="ir.ui.view">
<field name="name">crm_claim_rma.picking_in_form</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='move_type']" position="after">
<field name="claim_id" />
</xpath>
</field>
</record>
<record id="stock_move_mail_thread" model="ir.ui.view">
<field name="name">stock_move_mail_thread</field>
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_move_form" />
<field name="arch" type="xml">
<xpath expr="//sheet" position="after">
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</xpath>
</field>
</record>
<!-- SEARCH -->
<record id="view_picking_internal_search_claim_id" model="ir.ui.view">
<field name="name">stock.picking.internal.search</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_internal_search"/>
<field name="arch" type="xml">
<xpath expr="//search[@string='Picking Lists']">
<field name="claim_id" help="Moves created from claims"/>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Vauxoo
# Copyright 2015 Eezee-It, MONK Software
# Copyright 2013 Camptocamp
# Copyright 2009-2013 Akretion,
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli
# Benoît Guillot, Joel Grand-Guillaume, Leonardo Donelli,
# Osval Reyes
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -22,7 +24,7 @@
#
##############################################################################
from openerp import models, fields, api
from openerp import api, fields, models
class AccountInvoiceRefund(models.TransientModel):
@@ -33,8 +35,9 @@ class AccountInvoiceRefund(models.TransientModel):
description = fields.Char(default=_default_description)
@api.one
@api.multi
def compute_refund(self, mode='refund'):
self.ensure_one()
invoice_ids = self.env.context.get('invoice_ids', [])
if invoice_ids:
self = self.with_context(active_ids=invoice_ids)

View File

@@ -102,24 +102,18 @@ class ClaimMakePicking(models.TransientModel):
picking_type = self.env.context.get('picking_type')
if isinstance(picking_type, int):
picking_obj = self.env['stock.picking.type']
if picking_obj.\
browse(picking_type).\
code == 'incoming':
if picking_obj.browse(picking_type).code == 'incoming':
picking_type = 'in'
else:
picking_type = 'out'
move_field = ('move_in_id'
if picking_type == 'in'
else 'move_out_id')
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)
if lines:
domain = domain + [
'|', (move_field, '=', False),
(move_field+'.state', '=', 'cancel')
]
domain = domain + ['|', (move_field, '=', False),
(move_field + '.state', '=', 'cancel')]
lines = lines.search(domain)
if not lines:
raise exceptions.Warning(
@@ -258,10 +252,9 @@ class ClaimMakePicking(models.TransientModel):
domain = ("[('picking_type_id', '=', %s), ('partner_id', '=', %s)]" %
(picking_type.id, partner_id))
view_obj = self.env['ir.ui.view']
view_id = view_obj.search([('model', '=', 'stock.picking'),
('type', '=', 'form'),
])[0]
view_id = self.env['ir.ui.view'].search(
[('model', '=', 'stock.picking'),
('type', '=', 'form')])[0]
return {
'name': self._get_picking_name(),
'view_type': 'form',