[ADD]add RMA (Return Merchandise Authorizationing) module
This commit is contained in:
parent
0ee5993e2e
commit
aa7a8326a3
4
addons/rma/__init__.py
Normal file
4
addons/rma/__init__.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import models
|
||||||
|
from . import wizard
|
39
addons/rma/__manifest__.py
Normal file
39
addons/rma/__manifest__.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
{
|
||||||
|
'name': 'Return Merchandise Authorizationing',
|
||||||
|
'version': '1.0',
|
||||||
|
'author': 'Flectra',
|
||||||
|
'website': 'https://flectrahq.com',
|
||||||
|
'description': """
|
||||||
|
Return Merchandise Authorizationing is part of the process of a
|
||||||
|
consumer returning a product to receive a refund, replacement or repair
|
||||||
|
during the product's warranty period.
|
||||||
|
""",
|
||||||
|
'category': 'Sales',
|
||||||
|
'depends': ['sale_management', 'stock', 'purchase'],
|
||||||
|
'data': [
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
'data/mail_message_subtype_data.xml',
|
||||||
|
'data/mail_template_data.xml',
|
||||||
|
'data/replacement_reason_data.xml',
|
||||||
|
'sequences/data_rma_order_sequence.xml',
|
||||||
|
'views/rma_request_view.xml',
|
||||||
|
'views/replacement_reason_view.xml',
|
||||||
|
'views/rma_line_view.xml',
|
||||||
|
'views/stock_production_lot_view.xml',
|
||||||
|
'views/stock_picking_view.xml',
|
||||||
|
'views/warranty_expire_line_view.xml',
|
||||||
|
'views/sales_team_view.xml',
|
||||||
|
'views/menuitems_view.xml',
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
'demo': [
|
||||||
|
'demo/product_demo.xml',
|
||||||
|
'demo/stock_demo.xml',
|
||||||
|
'demo/sale_order_demo.xml',
|
||||||
|
],
|
||||||
|
|
||||||
|
'application': True,
|
||||||
|
}
|
52
addons/rma/data/mail_message_subtype_data.xml
Normal file
52
addons/rma/data/mail_message_subtype_data.xml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra>
|
||||||
|
|
||||||
|
<record id="mt_request_create" model="mail.message.subtype">
|
||||||
|
<field name="name">Request Created</field>
|
||||||
|
<field name="hidden" eval="True"/>
|
||||||
|
<field name="res_model">rma.request</field>
|
||||||
|
<field name="default" eval="False"/>
|
||||||
|
<field name="description">Replacement Request is Created</field>
|
||||||
|
</record>
|
||||||
|
<record id="mt_salesteam_request" model="mail.message.subtype">
|
||||||
|
<field name="name">Request Created</field>
|
||||||
|
<field name="sequence">10</field>
|
||||||
|
<field name="res_model">rma.request</field>
|
||||||
|
<field name="default" eval="False"/>
|
||||||
|
<field name="parent_id" eval="ref('mt_request_create')"/>
|
||||||
|
<field name="relation_field">team_id</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="mt_request_confirm" model="mail.message.subtype">
|
||||||
|
<field name="name">Request Confirmed</field>
|
||||||
|
<field name="hidden" eval="True"/>
|
||||||
|
<field name="res_model">rma.request</field>
|
||||||
|
<field name="default" eval="False"/>
|
||||||
|
<field name="description">Replacement Request has been
|
||||||
|
Confirmed</field>
|
||||||
|
</record>
|
||||||
|
<record id="mt_salesteam_request_confirm" model="mail.message.subtype">
|
||||||
|
<field name="name">Request Confirmed</field>
|
||||||
|
<field name="sequence">11</field>
|
||||||
|
<field name="res_model">rma.request</field>
|
||||||
|
<field name="default" eval="False"/>
|
||||||
|
<field name="parent_id" eval="ref('mt_request_confirm')"/>
|
||||||
|
<field name="relation_field">team_id</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="mt_request_replaced" model="mail.message.subtype">
|
||||||
|
<field name="name">Replacement created</field>
|
||||||
|
<field name="hidden" eval="True"/>
|
||||||
|
<field name="res_model">rma.request</field>
|
||||||
|
<field name="default" eval="False"/>
|
||||||
|
<field name="description">Products have been replaced</field>
|
||||||
|
</record>
|
||||||
|
<record id="mt_salesteam_request_replaced" model="mail.message.subtype">
|
||||||
|
<field name="name">Replacement created</field>
|
||||||
|
<field name="sequence">12</field>
|
||||||
|
<field name="res_model">rma.request</field>
|
||||||
|
<field name="default" eval="False"/>
|
||||||
|
<field name="parent_id" eval="ref('mt_request_replaced')"/>
|
||||||
|
<field name="relation_field">team_id</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
63
addons/rma/data/mail_template_data.xml
Normal file
63
addons/rma/data/mail_template_data.xml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra noupdate="1">
|
||||||
|
|
||||||
|
<record id="email_template_notify_warranty_new" model="mail.template">
|
||||||
|
<field name="name">Warranty: Product Warranty email</field>
|
||||||
|
<field name="email_from">
|
||||||
|
${(object.user_id.email and '%s <%s>' % (object.user_id.name, object.user_id.email) or '')|safe}
|
||||||
|
</field>
|
||||||
|
<field name="subject">${object.name or 'n/a'}</field>
|
||||||
|
<field name="partner_to">${object.partner_id.id}</field>
|
||||||
|
<field name="model_id" ref="rma.model_rma_request"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="lang">${object.partner_id.lang}</field>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
% if object.warranty_expire_line:
|
||||||
|
<div>
|
||||||
|
<p>Dear ${object.partner_id.name}</p>
|
||||||
|
<p>We are sorry to hear about the problem you have had
|
||||||
|
with your product.
|
||||||
|
</p>
|
||||||
|
<p> We would like to be able to make the necessary
|
||||||
|
adjustment at no charge to you,
|
||||||
|
but unfortunately the warranty is expired of
|
||||||
|
following products:
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table border="1" width="100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Product</th>
|
||||||
|
<th>Lot</th>
|
||||||
|
<th>Quantity</th>
|
||||||
|
<th>Warranty Date</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
% for line in object.warranty_expire_line:
|
||||||
|
<tr>
|
||||||
|
<td>${line.product_id.name}</td>
|
||||||
|
<td>${line.lot_id.name}</td>
|
||||||
|
<td>${line.qty_expired}</td>
|
||||||
|
<td>${line.warranty_date}</td>
|
||||||
|
</tr>
|
||||||
|
% endfor
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
% else:
|
||||||
|
<div>
|
||||||
|
<p>Dear ${object.partner_id.name}</p>
|
||||||
|
<p>We are sorry to hear about the problem you have had
|
||||||
|
with your product.</p>
|
||||||
|
<p>We would like to be able to make the necessary
|
||||||
|
adjustment at no charge to you, We are going to
|
||||||
|
replace your product. We will deliver it to
|
||||||
|
you as possible.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
% endif
|
||||||
|
]]>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
50
addons/rma/data/replacement_reason_data.xml
Normal file
50
addons/rma/data/replacement_reason_data.xml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra noupdate="1">
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_1">
|
||||||
|
<field name="name">Better price available</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_2">
|
||||||
|
<field name="name">Incompatible or not useful</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_3">
|
||||||
|
<field name="name">Product damaged, but shipping box OK</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_4">
|
||||||
|
<field name="name">Item arrived too late</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_5">
|
||||||
|
<field name="name">Missing parts or accessories</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_6">
|
||||||
|
<field name="name">Both product and shipping box damaged</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_7">
|
||||||
|
<field name="name">Wrong item was sent</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_8">
|
||||||
|
<field name="name">No longer needed</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_9">
|
||||||
|
<field name="name">Item defective or doesn't work</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_10">
|
||||||
|
<field name="name">Didn't approve purchase</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_11">
|
||||||
|
<field name="name">Performace or quality not adequate</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="replacement.reason" id="data_replace_reason_12">
|
||||||
|
<field name="name">Inaccurate website description</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
30
addons/rma/demo/product_demo.xml
Normal file
30
addons/rma/demo/product_demo.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<flectra noupdate="1">
|
||||||
|
<record id="demo_product_1" model="product.product">
|
||||||
|
<field name="name">Demo Product1</field>
|
||||||
|
<field name="categ_id" ref="product.product_category_5"/>
|
||||||
|
<field name="standard_price">100.0</field>
|
||||||
|
<field name="list_price">200.0</field>
|
||||||
|
<field name="type">product</field>
|
||||||
|
<field name="uom_id" ref="product.product_uom_unit"/>
|
||||||
|
<field name="uom_po_id" ref="product.product_uom_unit"/>
|
||||||
|
<field name="description">Demo product1
|
||||||
|
</field>
|
||||||
|
<field name="default_code">DEMO-PROD1</field>
|
||||||
|
<field name="tracking">lot</field>
|
||||||
|
</record>
|
||||||
|
<record id="demo_product_2" model="product.product">
|
||||||
|
<field name="name">Demo Product2</field>
|
||||||
|
<field name="categ_id" ref="product.product_category_5"/>
|
||||||
|
<field name="standard_price">200.0</field>
|
||||||
|
<field name="list_price">250.0</field>
|
||||||
|
<field name="type">product</field>
|
||||||
|
<field name="uom_id" ref="product.product_uom_unit"/>
|
||||||
|
<field name="uom_po_id" ref="product.product_uom_unit"/>
|
||||||
|
<field name="description">Demo product2
|
||||||
|
</field>
|
||||||
|
<field name="default_code">DEMO-PROD2</field>
|
||||||
|
<field name="tracking">lot</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
53
addons/rma/demo/sale_order_demo.xml
Normal file
53
addons/rma/demo/sale_order_demo.xml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<flectra noupdate="1">
|
||||||
|
<record id="demo_sale_order_rma_request1" model="sale.order">
|
||||||
|
<field name="partner_id" ref="base.res_partner_4"/>
|
||||||
|
<field name="partner_invoice_id" ref="base.res_partner_address_13"/>
|
||||||
|
<field name="partner_shipping_id" ref="base.res_partner_address_13"/>
|
||||||
|
<field name="user_id" ref="base.user_root"/>
|
||||||
|
<field name="pricelist_id" ref="product.list0"/>
|
||||||
|
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||||
|
<field name="date_order" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="demo_sale_order_rma_request1_line_1"
|
||||||
|
model="sale.order.line">
|
||||||
|
<field name="order_id" ref="demo_sale_order_rma_request1"/>
|
||||||
|
<field name="name">Demo Product1</field>
|
||||||
|
<field name="product_id" ref="rma.demo_product_1"/>
|
||||||
|
<field name="product_uom_qty">5</field>
|
||||||
|
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||||
|
<field name="price_unit">150.00</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="demo_sale_order_rma_request2" model="sale.order">
|
||||||
|
<field name="partner_id" ref="base.res_partner_4"/>
|
||||||
|
<field name="partner_invoice_id" ref="base.res_partner_address_13"/>
|
||||||
|
<field name="partner_shipping_id" ref="base.res_partner_address_13"/>
|
||||||
|
<field name="user_id" ref="base.user_root"/>
|
||||||
|
<field name="pricelist_id" ref="product.list0"/>
|
||||||
|
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||||
|
<field name="date_order" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="demo_sale_order_rma_request2_line_1"
|
||||||
|
model="sale.order.line">
|
||||||
|
<field name="order_id" ref="demo_sale_order_rma_request2"/>
|
||||||
|
<field name="name">Demo Product1</field>
|
||||||
|
<field name="product_id" ref="rma.demo_product_1"/>
|
||||||
|
<field name="product_uom_qty">5</field>
|
||||||
|
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||||
|
<field name="price_unit">150.00</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="demo_sale_order_rma_request2_line_2"
|
||||||
|
model="sale.order.line">
|
||||||
|
<field name="order_id" ref="demo_sale_order_rma_request2"/>
|
||||||
|
<field name="name">Demo Product2</field>
|
||||||
|
<field name="product_id" ref="rma.demo_product_2"/>
|
||||||
|
<field name="product_uom_qty">10</field>
|
||||||
|
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||||
|
<field name="price_unit">200.00</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
19
addons/rma/demo/stock_demo.xml
Normal file
19
addons/rma/demo/stock_demo.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<flectra noupdate="1">
|
||||||
|
<record id="demo_stock_inventory_line_1" model="stock.inventory.line">
|
||||||
|
<field name="product_id" ref="rma.demo_product_1"/>
|
||||||
|
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||||
|
<field name="inventory_id" ref="stock.stock_inventory_0"/>
|
||||||
|
<field name="product_qty">20.0</field>
|
||||||
|
<field name="location_id" ref="stock.stock_location_14"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="demo_stock_inventory_line_2" model="stock.inventory.line">
|
||||||
|
<field name="product_id" ref="rma.demo_product_2"/>
|
||||||
|
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||||
|
<field name="inventory_id" ref="stock.stock_inventory_0"/>
|
||||||
|
<field name="product_qty">30.0</field>
|
||||||
|
<field name="location_id" ref="stock.stock_location_14"/>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
538
addons/rma/i18n/rma.pot
Normal file
538
addons/rma/i18n/rma.pot
Normal file
@ -0,0 +1,538 @@
|
|||||||
|
# Translation of Flectra Server.
|
||||||
|
# This file contains the translation of the following modules:
|
||||||
|
# * rma
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: Flectra Server 1.0alpha\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2017-12-25 11:22+0000\n"
|
||||||
|
"PO-Revision-Date: 2017-12-25 11:22+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"
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:mail.template,body_html:rma.email_template_notify_warranty_new
|
||||||
|
msgid "\n"
|
||||||
|
" % if object.warranty_expire_line:\n"
|
||||||
|
" <div>\n"
|
||||||
|
" <p>Dear ${object.partner_id.name}</p>\n"
|
||||||
|
" <p>We are sorry to hear about the problem you have had\n"
|
||||||
|
" with your product.\n"
|
||||||
|
" We would like to be able to make the necessary\n"
|
||||||
|
" adjustment at no charge to you,\n"
|
||||||
|
" but unfortunately the warranty is expired of\n"
|
||||||
|
" following products:\n"
|
||||||
|
" </p>\n"
|
||||||
|
" </div>\n"
|
||||||
|
"\n"
|
||||||
|
" <table border=\"1\" width=\"100%\">\n"
|
||||||
|
" <thead>\n"
|
||||||
|
" <tr>\n"
|
||||||
|
" <th>Product</th>\n"
|
||||||
|
" <th>Lot</th>\n"
|
||||||
|
" <th>Quantity</th>\n"
|
||||||
|
" <th>Warranty Date</th>\n"
|
||||||
|
" </tr>\n"
|
||||||
|
" </thead>\n"
|
||||||
|
" <tbody>\n"
|
||||||
|
" % for line in object.warranty_expire_line:\n"
|
||||||
|
" <tr>\n"
|
||||||
|
" <td>${line.product_id.name}</td>\n"
|
||||||
|
" <td>${line.lot_id.name}</td>\n"
|
||||||
|
" <td>${line.qty_expired}</td>\n"
|
||||||
|
" <td>${line.warranty_date}</td>\n"
|
||||||
|
" </tr>\n"
|
||||||
|
" % endfor\n"
|
||||||
|
" </tbody>\n"
|
||||||
|
" </table>\n"
|
||||||
|
" % else:\n"
|
||||||
|
" <div>\n"
|
||||||
|
" <p>Dear ${object.partner_id.name}</p>\n"
|
||||||
|
" <p>We are sorry to hear about the problem you have had\n"
|
||||||
|
" with your product.\n"
|
||||||
|
" We would like to be able to make the necessary\n"
|
||||||
|
" adjustment at no charge to you, We are going to\n"
|
||||||
|
" replace your product. We will deliver it to\n"
|
||||||
|
" you as possible.\n"
|
||||||
|
" </p>\n"
|
||||||
|
" </div>\n"
|
||||||
|
" % endif\n"
|
||||||
|
"\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:mail.template,subject:rma.email_template_notify_warranty_new
|
||||||
|
msgid "${object.name or 'n/a'}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: code:addons/rma/models/rma_request.py:147
|
||||||
|
#, python-format
|
||||||
|
msgid "Compose Email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_form
|
||||||
|
msgid "Confirm"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: selection:rma.request,state:0
|
||||||
|
msgid "Confirmed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_form
|
||||||
|
msgid "Create Replacement"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_replacement_reason_create_uid
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_create_uid
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_create_uid
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_create_uid
|
||||||
|
msgid "Created by"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_replacement_reason_create_date
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_create_date
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_create_date
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_create_date
|
||||||
|
msgid "Created on"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_partner_id
|
||||||
|
msgid "Customer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_qty_delivered
|
||||||
|
msgid "Delivered Quantity"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_picking_count
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_picking_ids
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_form
|
||||||
|
msgid "Delivery"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:product.product,name:rma.demo_product_1
|
||||||
|
#: model:product.template,name:rma.demo_product_1_product_template
|
||||||
|
#: model:stock.inventory.line,product_name:rma.demo_stock_inventory_line_1
|
||||||
|
msgid "Demo Product1"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:product.product,name:rma.demo_product_2
|
||||||
|
#: model:product.template,name:rma.demo_product_2_product_template
|
||||||
|
#: model:stock.inventory.line,product_name:rma.demo_stock_inventory_line_2
|
||||||
|
msgid "Demo Product2"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:product.product,description:rma.demo_product_1
|
||||||
|
#: model:product.template,description:rma.demo_product_1_product_template
|
||||||
|
msgid "Demo product1\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:product.product,description:rma.demo_product_2
|
||||||
|
#: model:product.template,description:rma.demo_product_2_product_template
|
||||||
|
msgid "Demo product2\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_replacement_reason_display_name
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_display_name
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_display_name
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_display_name
|
||||||
|
msgid "Display Name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: selection:rma.request,state:0
|
||||||
|
msgid "Draft"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_qty_expired
|
||||||
|
msgid "Expired Quantity"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
msgid "Group By"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_replacement_reason_id
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_id
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_id
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_id
|
||||||
|
msgid "ID"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_replacement_reason___last_update
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line___last_update
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request___last_update
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line___last_update
|
||||||
|
msgid "Last Modified on"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_replacement_reason_write_uid
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_write_uid
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_write_uid
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_write_uid
|
||||||
|
msgid "Last Updated by"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_replacement_reason_write_date
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_write_date
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_write_date
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_write_date
|
||||||
|
msgid "Last Updated on"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_warranty_date
|
||||||
|
msgid "Lot Warranty Date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model,name:rma.model_stock_production_lot
|
||||||
|
msgid "Lot/Serial"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
msgid "My Requests"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: code:addons/rma/wizard/stock_return_picking.py:62
|
||||||
|
#, python-format
|
||||||
|
msgid "No products to replace (only lines in Done state andnot fully replaced yet can be replaced)!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.actions.act_window,help:rma.replacement_request_action_reports
|
||||||
|
msgid "No replacement request."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_crm_team_replacements_count
|
||||||
|
msgid "Number of replacements"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
msgid "Partner"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_picking_id
|
||||||
|
msgid "Picking Number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_product_id
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_product_id
|
||||||
|
msgid "Product"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:mail.message.subtype,description:rma.mt_request_replaced
|
||||||
|
msgid "Products have been replaced"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model,name:rma.model_rma_line
|
||||||
|
msgid "RMA Line"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.actions.act_window,name:rma.act_open_rma_line_view
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_rma_line
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_line_form
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_form
|
||||||
|
msgid "RMA Lines"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_name
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_stock_picking_rma_id
|
||||||
|
msgid "RMA Order Number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.actions.act_window,name:rma.act_open_rma_request_view
|
||||||
|
#: model:ir.actions.act_window,name:rma.action_open_rma_request_replacementteam
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
msgid "RMA Request"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_rma_id
|
||||||
|
msgid "RMA Request Number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model,name:rma.model_rma_request
|
||||||
|
msgid "RMA Reuqest"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_rma_id
|
||||||
|
msgid "RMA Reuqest Number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_replacement_reason_name
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_reason_id
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_replacement_reason_form
|
||||||
|
msgid "Reason"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_remark
|
||||||
|
msgid "Remark"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.menu,name:rma.menu_request_rma
|
||||||
|
msgid "Replace Request"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_crm_team_use_replacement
|
||||||
|
#: model:ir.ui.menu,name:rma.rma_request_menu
|
||||||
|
#: model:ir.ui.view,arch_db:rma.crm_team_replacement_teams_view_kanban
|
||||||
|
#: model:ir.ui.view,arch_db:rma.replacement_view_kanban
|
||||||
|
#: selection:rma.request,type:0
|
||||||
|
msgid "Replacement"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
#: selection:rma.request,state:0
|
||||||
|
msgid "Replacement Created"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_qty_replaced
|
||||||
|
msgid "Replacement Quantity"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.actions.act_window,name:rma.act_open_replacement_reason_view
|
||||||
|
#: model:ir.model,name:rma.model_replacement_reason
|
||||||
|
#: model:ir.ui.menu,name:rma.menu_replacement_reason
|
||||||
|
msgid "Replacement Reason"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_line_graph
|
||||||
|
msgid "Replacement Request"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:mail.message.subtype,description:rma.mt_request_confirm
|
||||||
|
msgid "Replacement Request has been\n"
|
||||||
|
" Confirmed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:mail.message.subtype,description:rma.mt_request_create
|
||||||
|
msgid "Replacement Request is Created"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.actions.act_window,name:rma.replacement_request_action_reports
|
||||||
|
msgid "Replacement Requests"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:mail.message.subtype,name:rma.mt_request_replaced
|
||||||
|
#: model:mail.message.subtype,name:rma.mt_salesteam_request_replaced
|
||||||
|
msgid "Replacement created"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.crm_team_replacement_teams_view_kanban
|
||||||
|
msgid "Replacements"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: code:addons/rma/models/rma_line.py:35
|
||||||
|
#, python-format
|
||||||
|
msgid "Replacemet quantity of %s should not be greater than ordered quantity."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:mail.message.subtype,name:rma.mt_request_confirm
|
||||||
|
#: model:mail.message.subtype,name:rma.mt_salesteam_request_confirm
|
||||||
|
msgid "Request Confirmed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:mail.message.subtype,name:rma.mt_request_create
|
||||||
|
#: model:mail.message.subtype,name:rma.mt_salesteam_request
|
||||||
|
msgid "Request Created"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_date
|
||||||
|
msgid "Request Date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
msgid "Request Month"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_state
|
||||||
|
msgid "Request Status"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_type
|
||||||
|
msgid "Request Type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_form
|
||||||
|
msgid "Requests for RMA"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model,name:rma.model_stock_return_picking
|
||||||
|
msgid "Return Picking"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_sale_order_id
|
||||||
|
msgid "SO Number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
msgid "Sale Order"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model,name:rma.model_crm_team
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
msgid "Sales Channel"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_line_filter
|
||||||
|
msgid "Search RMA Line"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
msgid "Search RMA Request"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_form
|
||||||
|
msgid "Send By Email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_filter
|
||||||
|
msgid "State"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_move_line_id
|
||||||
|
msgid "Stock Move"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_warranty_expire_line_lot_id
|
||||||
|
msgid "Stock production lot"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_team_id
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_team_id
|
||||||
|
msgid "Team"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model,name:rma.model_stock_picking
|
||||||
|
msgid "Transfer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_line_uom_id
|
||||||
|
msgid "UOM"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_user_id
|
||||||
|
msgid "User"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.actions.act_window,name:rma.act_open_warranty_expire_line_view
|
||||||
|
#: model:ir.model,name:rma.model_warranty_expire_line
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_rma_request_warranty_expire_line
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_rma_request_form
|
||||||
|
#: model:ir.ui.view,arch_db:rma.view_warranty_expire_line_form
|
||||||
|
msgid "Warranty Expire Lines"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: model:ir.model.fields,field_description:rma.field_stock_production_lot_warranty_date
|
||||||
|
msgid "Warranty Expiry Date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: code:addons/rma/models/rma_line.py:30
|
||||||
|
#, python-format
|
||||||
|
msgid "You can only replace %s quantity for product %s as its warranty has been expired."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: code:addons/rma/models/rma_request.py:183
|
||||||
|
#, python-format
|
||||||
|
msgid "You cannot delete a request which is not in draft state."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: code:addons/rma/wizard/stock_return_picking.py:16
|
||||||
|
#, python-format
|
||||||
|
msgid "You may only replace single picking at a time!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: code:addons/rma/wizard/stock_return_picking.py:26
|
||||||
|
#, python-format
|
||||||
|
msgid "You may only return Done pickings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: rma
|
||||||
|
#: code:addons/rma/models/rma_request.py:174
|
||||||
|
#, python-format
|
||||||
|
msgid "You must select rma lines!"
|
||||||
|
msgstr ""
|
||||||
|
|
9
addons/rma/models/__init__.py
Normal file
9
addons/rma/models/__init__.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import rma_line
|
||||||
|
from . import warranty_expire_line
|
||||||
|
from . import rma_request
|
||||||
|
from . import stock_production_lot
|
||||||
|
from . import stock_picking
|
||||||
|
from . import sales_team
|
||||||
|
from . import replacement_reason
|
10
addons/rma/models/replacement_reason.py
Normal file
10
addons/rma/models/replacement_reason.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class ReplacementReason(models.Model):
|
||||||
|
_name = "replacement.reason"
|
||||||
|
_description = "Replacement Reason"
|
||||||
|
|
||||||
|
name = fields.Char(string='Reason')
|
40
addons/rma/models/rma_line.py
Normal file
40
addons/rma/models/rma_line.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra import api, fields, models, _
|
||||||
|
from flectra.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
|
class RMALine(models.Model):
|
||||||
|
_name = "rma.line"
|
||||||
|
_description = "RMA Line"
|
||||||
|
|
||||||
|
product_id = fields.Many2one('product.product', string='Product')
|
||||||
|
uom_id = fields.Many2one('product.uom', string='UOM')
|
||||||
|
qty_delivered = fields.Float(string='Delivered Quantity')
|
||||||
|
qty_replaced = fields.Float(string='Replacement Quantity')
|
||||||
|
rma_id = fields.Many2one('rma.request', string='RMA Request Number')
|
||||||
|
move_line_id = fields.Many2one('stock.move', string='Stock Move')
|
||||||
|
reason_id = fields.Many2one("replacement.reason", sting='Reason for RMA')
|
||||||
|
remark = fields.Text(sting='Remark')
|
||||||
|
team_id = fields.Many2one('crm.team', 'Team', related='rma_id.team_id')
|
||||||
|
|
||||||
|
@api.onchange('qty_replaced')
|
||||||
|
def _onchange_qty_replaced(self):
|
||||||
|
if self.product_id.tracking != 'none':
|
||||||
|
replaceable_qty = sum(line.qty_done for line in
|
||||||
|
self.move_line_id.move_line_ids if
|
||||||
|
line.lot_id.warranty_date and
|
||||||
|
line.lot_id.warranty_date >=
|
||||||
|
self.rma_id.date)
|
||||||
|
if self.qty_replaced > replaceable_qty:
|
||||||
|
raise UserError(_('You can only replace %s quantity for '
|
||||||
|
'product %s as its warranty has been '
|
||||||
|
'expired.') % (replaceable_qty,
|
||||||
|
self.product_id.name))
|
||||||
|
elif self.qty_replaced > self.qty_delivered:
|
||||||
|
raise UserError(_('Replacemet quantity of %s should not be '
|
||||||
|
'greater than ordered quantity.') %
|
||||||
|
(self.product_id.name))
|
||||||
|
|
||||||
|
if self.qty_replaced == 0:
|
||||||
|
raise UserError(_('Replacement quantity should not be 0.'))
|
186
addons/rma/models/rma_request.py
Normal file
186
addons/rma/models/rma_request.py
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra import api, fields, models, _
|
||||||
|
from flectra.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
|
class RmaRequest(models.Model):
|
||||||
|
_name = "rma.request"
|
||||||
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||||
|
_description = "RMA Request"
|
||||||
|
|
||||||
|
name = fields.Char(string='RMA Order Number')
|
||||||
|
sale_order_id = fields.Many2one('sale.order', string='SO Number')
|
||||||
|
picking_id = fields.Many2one('stock.picking', string='Picking Number')
|
||||||
|
date = fields.Date(string='Request Date',
|
||||||
|
default=fields.Date.context_today)
|
||||||
|
partner_id = fields.Many2one('res.partner', string='Customer')
|
||||||
|
type = fields.Selection([
|
||||||
|
('replacement', 'Replacement')
|
||||||
|
], string='Request Type')
|
||||||
|
rma_line = fields.One2many('rma.line', 'rma_id', string='RMA Lines')
|
||||||
|
warranty_expire_line = fields.One2many('warranty.expire.line', 'rma_id',
|
||||||
|
string='Warranty Expire Lines')
|
||||||
|
state = fields.Selection([
|
||||||
|
('draft', 'Draft'),
|
||||||
|
('confirmed', 'Confirmed'),
|
||||||
|
('replacement_created', 'Replacement Created'),
|
||||||
|
], string='Request Status', track_visibility='onchange', readonly=True,
|
||||||
|
copy=False, default='draft')
|
||||||
|
picking_count = fields.Integer(string='Delivery',
|
||||||
|
compute="_compute_picking")
|
||||||
|
picking_ids = fields.Many2many('stock.picking',
|
||||||
|
string='Delivery',
|
||||||
|
compute="_compute_picking")
|
||||||
|
user_id = fields.Many2one('res.users', string='User',
|
||||||
|
default=lambda self: self.env.user)
|
||||||
|
team_id = fields.Many2one('crm.team', string='Team')
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def _compute_picking(self):
|
||||||
|
for request in self:
|
||||||
|
picking_ids = self.env['stock.picking'].search([(
|
||||||
|
'rma_id', '=', request.id)])
|
||||||
|
request.picking_ids = picking_ids and picking_ids.ids or False
|
||||||
|
request.picking_count = len(picking_ids)
|
||||||
|
|
||||||
|
@api.onchange('sale_order_id')
|
||||||
|
def _get_partner(self):
|
||||||
|
if self.sale_order_id:
|
||||||
|
self.partner_id = self.sale_order_id.partner_id and \
|
||||||
|
self.sale_order_id.partner_id.id or False
|
||||||
|
self.team_id = self.sale_order_id.team_id and \
|
||||||
|
self.sale_order_id.team_id.id or False
|
||||||
|
|
||||||
|
@api.onchange('picking_id')
|
||||||
|
def _get_rma_lines(self):
|
||||||
|
if self.picking_id:
|
||||||
|
move_line_ids = self.env['stock.move'].search([(
|
||||||
|
'picking_id', '=', self.picking_id.id)])
|
||||||
|
move_lines = [(5, 0, 0)]
|
||||||
|
for line in move_line_ids:
|
||||||
|
move_lines.append((0, 0, {
|
||||||
|
'product_id': line.product_id.id,
|
||||||
|
'uom_id': line.product_uom.id,
|
||||||
|
'qty_delivered': line.quantity_done,
|
||||||
|
'qty_replaced': sum(line.qty_done for line in
|
||||||
|
line.move_line_ids if
|
||||||
|
line.lot_id.warranty_date and
|
||||||
|
line.lot_id.warranty_date >= self.date
|
||||||
|
),
|
||||||
|
'rma_id': self.id,
|
||||||
|
'move_line_id': line.id
|
||||||
|
}))
|
||||||
|
self.rma_line = move_lines
|
||||||
|
|
||||||
|
@api.onchange('rma_line', 'date')
|
||||||
|
def _get_warranty_lines(self):
|
||||||
|
warranty_lines = [(5, 0, 0)]
|
||||||
|
for line in self.rma_line:
|
||||||
|
if line.move_line_id and \
|
||||||
|
line.move_line_id.product_id.tracking != 'none':
|
||||||
|
for move_line in line.move_line_id.move_line_ids:
|
||||||
|
if move_line.lot_id.warranty_date and \
|
||||||
|
move_line.lot_id.warranty_date < self.date:
|
||||||
|
warranty_lines.append((0, 0, {
|
||||||
|
'product_id': move_line.product_id.id,
|
||||||
|
'lot_id': move_line.lot_id.id,
|
||||||
|
'warranty_date':
|
||||||
|
move_line.lot_id.warranty_date,
|
||||||
|
'qty_expired': sum(line.qty_done for line in
|
||||||
|
line.move_line_id.move_line_ids
|
||||||
|
if line.lot_id.warranty_date and
|
||||||
|
line.lot_id.
|
||||||
|
warranty_date < self.date),
|
||||||
|
'rma_id': self.id,
|
||||||
|
}))
|
||||||
|
self.warranty_expire_line = warranty_lines
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
vals.update({
|
||||||
|
'name': self.env['ir.sequence'].next_by_code(
|
||||||
|
'rma_order')
|
||||||
|
})
|
||||||
|
return super(RmaRequest, self).create(vals)
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def action_create_delivery(self):
|
||||||
|
self.ensure_one()
|
||||||
|
action = self.env.ref('stock.action_picking_tree_all')
|
||||||
|
result = action.read()[0]
|
||||||
|
if len(self.picking_ids) != 1:
|
||||||
|
result.update({
|
||||||
|
'domain': "[('id', 'in', " + str(self.picking_ids.ids) + ")]"
|
||||||
|
})
|
||||||
|
elif len(self.picking_ids) == 1:
|
||||||
|
res = self.env.ref('rma.view_picking_form', False)
|
||||||
|
result.update({
|
||||||
|
'views': [(res and res.id or False, 'form')],
|
||||||
|
'res_id': self.picking_ids.id
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def action_notify_warranty(self):
|
||||||
|
self.ensure_one()
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
try:
|
||||||
|
template_id = ir_model_data.get_object_reference(
|
||||||
|
'rma', 'email_template_notify_warranty_new')[1]
|
||||||
|
except ValueError:
|
||||||
|
template_id = False
|
||||||
|
try:
|
||||||
|
compose_form_id = ir_model_data.get_object_reference(
|
||||||
|
'mail', 'email_compose_message_wizard_form')[1]
|
||||||
|
except ValueError:
|
||||||
|
compose_form_id = False
|
||||||
|
ctx = dict(
|
||||||
|
default_model='rma.request',
|
||||||
|
default_res_id=self.id,
|
||||||
|
default_use_template=bool(template_id),
|
||||||
|
default_template_id=template_id,
|
||||||
|
default_composition_mode='comment',
|
||||||
|
force_email=True
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
'name': _('Compose Email'),
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'view_type': 'form',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'res_model': 'mail.compose.message',
|
||||||
|
'views': [(compose_form_id, 'form')],
|
||||||
|
'view_id': compose_form_id,
|
||||||
|
'target': 'new',
|
||||||
|
'context': ctx,
|
||||||
|
}
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def _track_subtype(self, init_values):
|
||||||
|
self.ensure_one()
|
||||||
|
if 'state' in init_values and self.state == 'draft' and self.rma_line:
|
||||||
|
return 'rma.mt_request_create'
|
||||||
|
elif 'state' in init_values and self.state == 'confirmed' and \
|
||||||
|
self.rma_line:
|
||||||
|
return 'rma.mt_request_confirm'
|
||||||
|
elif 'state' in init_values and self.state == 'replacement_created':
|
||||||
|
return 'rma.mt_request_replaced'
|
||||||
|
return super(RmaRequest, self)._track_subtype(init_values)
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def action_confirm_request(self):
|
||||||
|
self.ensure_one()
|
||||||
|
if not self.rma_line:
|
||||||
|
raise UserError(_('You must select rma lines!'))
|
||||||
|
for line in self.rma_line:
|
||||||
|
line._onchange_qty_replaced()
|
||||||
|
self.state = 'confirmed'
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def unlink(self):
|
||||||
|
for request in self:
|
||||||
|
if request.state != 'draft':
|
||||||
|
raise UserError(_(
|
||||||
|
'You cannot delete a request which is not in draft '
|
||||||
|
'state.'))
|
||||||
|
return super(RmaRequest, self).unlink()
|
19
addons/rma/models/sales_team.py
Normal file
19
addons/rma/models/sales_team.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class CrmTeam(models.Model):
|
||||||
|
_inherit = 'crm.team'
|
||||||
|
|
||||||
|
use_replacement = fields.Boolean(string='Replacement')
|
||||||
|
replacements_count = fields.Integer(
|
||||||
|
compute='_compute_replacements',
|
||||||
|
string='Number of replacements')
|
||||||
|
|
||||||
|
def _compute_replacements(self):
|
||||||
|
for replace in self:
|
||||||
|
if replace.use_replacement:
|
||||||
|
rma_ids = self.env['rma.request'].search([
|
||||||
|
('team_id.id', '=', replace.id)])
|
||||||
|
replace.replacements_count = len(rma_ids)
|
20
addons/rma/models/stock_picking.py
Normal file
20
addons/rma/models/stock_picking.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class StockPicking(models.Model):
|
||||||
|
_inherit = 'stock.picking'
|
||||||
|
|
||||||
|
rma_id = fields.Many2one('rma.request', string='RMA Order Number')
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
result = super(StockPicking, self).create(vals)
|
||||||
|
rma_id = False
|
||||||
|
if self._context.get('active_model') == 'stock.picking':
|
||||||
|
rma_id = result.rma_id and result.rma_id.id or False
|
||||||
|
elif self._context.get('active_model') == 'rma.request':
|
||||||
|
rma_id = self._context.get('active_id')
|
||||||
|
result.update({'rma_id': rma_id})
|
||||||
|
return result
|
8
addons/rma/models/stock_production_lot.py
Normal file
8
addons/rma/models/stock_production_lot.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class StockProductionLot(models.Model):
|
||||||
|
_inherit = 'stock.production.lot'
|
||||||
|
warranty_date = fields.Date(string='Warranty Expiry Date')
|
15
addons/rma/models/warranty_expire_line.py
Normal file
15
addons/rma/models/warranty_expire_line.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class WarrantyExpireLine(models.Model):
|
||||||
|
_name = "warranty.expire.line"
|
||||||
|
_description = "Warranty Expire Lines"
|
||||||
|
|
||||||
|
rma_id = fields.Many2one('rma.request', string='RMA Request Number')
|
||||||
|
product_id = fields.Many2one('product.product', string='Product')
|
||||||
|
lot_id = fields.Many2one('stock.production.lot',
|
||||||
|
string='Stock production lot')
|
||||||
|
qty_expired = fields.Float(string="Expired Quantity")
|
||||||
|
warranty_date = fields.Date('Lot Warranty Date')
|
5
addons/rma/security/ir.model.access.csv
Normal file
5
addons/rma/security/ir.model.access.csv
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_rma_request,access_rma_request,model_rma_request,,1,1,1,0
|
||||||
|
access_rma_line,access_rma_line,model_rma_line,,1,1,1,0
|
||||||
|
access_warranty_expire_line,access_warranty_expire_line,model_warranty_expire_line,,1,1,1,0
|
||||||
|
access_replacement_reason,access_replacement_reason,model_replacement_reason,,1,1,1,0
|
|
10
addons/rma/sequences/data_rma_order_sequence.xml
Normal file
10
addons/rma/sequences/data_rma_order_sequence.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra noupdate="1">
|
||||||
|
|
||||||
|
<record id="seq_rma_order" model="ir.sequence">
|
||||||
|
<field name="name">RMA Order Sequence</field>
|
||||||
|
<field name="code">rma_order</field>
|
||||||
|
<field name="prefix">RMA</field>
|
||||||
|
<field name="padding">4</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
BIN
addons/rma/static/description/icon.png
Normal file
BIN
addons/rma/static/description/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
3
addons/rma/tests/__init__.py
Normal file
3
addons/rma/tests/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import test_rma_request
|
172
addons/rma/tests/test_rma_request.py
Normal file
172
addons/rma/tests/test_rma_request.py
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra.tests.common import TransactionCase
|
||||||
|
from datetime import datetime
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
|
|
||||||
|
class TestSaleOrder(TransactionCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestSaleOrder, self).setUp()
|
||||||
|
|
||||||
|
self.demo_product1_id = self.env.ref('rma.demo_product_1')
|
||||||
|
self.demo_product2_id = self.env.ref('rma.demo_product_2')
|
||||||
|
|
||||||
|
self.product1_lot_id = self.env['stock.production.lot'].create({
|
||||||
|
'name': 'L001',
|
||||||
|
'product_id': self.demo_product1_id.id,
|
||||||
|
'warranty_date': datetime.now() + relativedelta(years=1)
|
||||||
|
})
|
||||||
|
self.change_prod1_qty_id = self.env[
|
||||||
|
'stock.change.product.qty'].create({
|
||||||
|
'product_id': self.demo_product1_id.id,
|
||||||
|
'new_quantity': 10,
|
||||||
|
'lot_id': self.product1_lot_id.id
|
||||||
|
})
|
||||||
|
self.change_prod1_qty_id.change_product_qty()
|
||||||
|
self.sale_order_id_1 = self.env.ref(
|
||||||
|
'rma.demo_sale_order_rma_request1')
|
||||||
|
|
||||||
|
self.product2_lot_id = self.env['stock.production.lot'].create({
|
||||||
|
'name': 'L002',
|
||||||
|
'product_id': self.demo_product2_id.id,
|
||||||
|
'warranty_date': datetime.now() - relativedelta(years=1)
|
||||||
|
})
|
||||||
|
self.change_prod2_qty_id = self.env[
|
||||||
|
'stock.change.product.qty'].create({
|
||||||
|
'product_id': self.demo_product2_id.id,
|
||||||
|
'new_quantity': 10,
|
||||||
|
'lot_id': self.product2_lot_id.id
|
||||||
|
})
|
||||||
|
self.change_prod2_qty_id.change_product_qty()
|
||||||
|
self.sale_order_id_2 = self.env.ref(
|
||||||
|
'rma.demo_sale_order_rma_request2')
|
||||||
|
|
||||||
|
def test_00_rma_request(self):
|
||||||
|
self.sale_order_id_1.action_confirm()
|
||||||
|
picking_ids = self.sale_order_id_1.picking_ids[0]
|
||||||
|
for move_line in picking_ids.move_lines[0].move_line_ids:
|
||||||
|
move_line.lot_id = self.product1_lot_id.id
|
||||||
|
move_line.qty_done = 5
|
||||||
|
picking_ids.button_validate()
|
||||||
|
picking_ids.action_done()
|
||||||
|
|
||||||
|
self.rma_id_1 = self.env['rma.request'].create({
|
||||||
|
'sale_order_id': self.sale_order_id_1.id,
|
||||||
|
'picking_id': picking_ids[0].id,
|
||||||
|
'date': datetime.now() - relativedelta(days=15),
|
||||||
|
'partner_id': self.sale_order_id_1.partner_id.id,
|
||||||
|
'type': 'replacement'
|
||||||
|
})
|
||||||
|
self.assertEquals(self.rma_id_1.state, 'draft')
|
||||||
|
|
||||||
|
self.rma_id_1._get_rma_lines()
|
||||||
|
self.assertTrue((len(self.rma_id_1.rma_line.ids)) != 0,
|
||||||
|
'You can not create replacement request!')
|
||||||
|
|
||||||
|
self.rma_id_1._get_warranty_lines()
|
||||||
|
self.assertEquals((len(self.rma_id_1.warranty_expire_line.ids)), 0,
|
||||||
|
'This Replacement request should not have expiry '
|
||||||
|
'product!')
|
||||||
|
|
||||||
|
for rma_line in self.rma_id_1.rma_line:
|
||||||
|
replaceable_qty = sum(line.qty_done for line in
|
||||||
|
rma_line.move_line_id.move_line_ids if
|
||||||
|
line.lot_id.warranty_date and
|
||||||
|
line.lot_id.warranty_date >=
|
||||||
|
self.rma_id_1.date)
|
||||||
|
self.assertTrue(rma_line.qty_replaced <= replaceable_qty,
|
||||||
|
"You can only replace %d quantity for %s" %
|
||||||
|
(replaceable_qty, rma_line.product_id.name))
|
||||||
|
|
||||||
|
self.rma_id_1.action_confirm_request()
|
||||||
|
self.assertEquals(self.rma_id_1.state, 'confirmed')
|
||||||
|
|
||||||
|
context = {"active_model": 'rma.request',
|
||||||
|
"active_ids": [self.rma_id_1.id], "active_id":
|
||||||
|
self.rma_id_1.id, "rma": True}
|
||||||
|
self.return_picking_id_1 = self.env[
|
||||||
|
'stock.return.picking'].with_context(context).create(dict(
|
||||||
|
picking_id=self.rma_id_1.picking_id.id,
|
||||||
|
))
|
||||||
|
self.return_picking_id_1.create_returns()
|
||||||
|
self.assertEquals(self.rma_id_1.state, 'replacement_created')
|
||||||
|
self.assertTrue(len(self.sale_order_id_1.picking_ids.ids) > 1,
|
||||||
|
'Product has not been replaced yet')
|
||||||
|
|
||||||
|
incoming_shipment = False
|
||||||
|
for pick in self.sale_order_id_1.picking_ids:
|
||||||
|
if pick.picking_type_code == 'incoming':
|
||||||
|
incoming_shipment = True
|
||||||
|
for move_line in pick.move_lines[0].move_line_ids:
|
||||||
|
move_line.lot_id = self.product1_lot_id.id
|
||||||
|
move_line.qty_done = 5
|
||||||
|
pick.button_validate()
|
||||||
|
pick.action_done()
|
||||||
|
self.assertTrue(incoming_shipment, 'Incoming shipment is not created')
|
||||||
|
|
||||||
|
def test_01_rma_request(self):
|
||||||
|
self.sale_order_id_2.action_confirm()
|
||||||
|
picking_ids = self.sale_order_id_2.picking_ids[0]
|
||||||
|
for move_line in picking_ids.move_lines[0].move_line_ids:
|
||||||
|
move_line.lot_id = self.product2_lot_id.id
|
||||||
|
move_line.qty_done = 10
|
||||||
|
for move_line in picking_ids.move_lines[1].move_line_ids:
|
||||||
|
move_line.lot_id = self.product1_lot_id.id
|
||||||
|
move_line.qty_done = 5
|
||||||
|
picking_ids.button_validate()
|
||||||
|
picking_ids.action_done()
|
||||||
|
|
||||||
|
self.rma_id_2 = self.env['rma.request'].create({
|
||||||
|
'sale_order_id': self.sale_order_id_2.id,
|
||||||
|
'picking_id': picking_ids[0].id,
|
||||||
|
'date': datetime.now() - relativedelta(days=10),
|
||||||
|
'partner_id': self.sale_order_id_2.partner_id.id,
|
||||||
|
'type': 'replacement'
|
||||||
|
})
|
||||||
|
self.assertEquals(self.rma_id_2.state, 'draft')
|
||||||
|
self.rma_id_2._get_rma_lines()
|
||||||
|
self.assertTrue((len(self.rma_id_2.rma_line.ids)) != 0,
|
||||||
|
'You can not create replacement request!')
|
||||||
|
|
||||||
|
self.rma_id_2._get_warranty_lines()
|
||||||
|
self.assertEquals((len(self.rma_id_2.warranty_expire_line.ids)), 1,
|
||||||
|
'Replacement request must have expiry product!')
|
||||||
|
|
||||||
|
for rma_line in self.rma_id_2.rma_line:
|
||||||
|
replaceable_qty = sum(line.qty_done for line in
|
||||||
|
rma_line.move_line_id.move_line_ids if
|
||||||
|
line.lot_id.warranty_date and
|
||||||
|
line.lot_id.warranty_date >=
|
||||||
|
self.rma_id_2.date)
|
||||||
|
self.assertTrue(rma_line.qty_replaced <= replaceable_qty,
|
||||||
|
"You can only return %d quantity for %s" %
|
||||||
|
(replaceable_qty, rma_line.product_id.name))
|
||||||
|
|
||||||
|
self.rma_id_2.state = 'confirmed'
|
||||||
|
self.assertEquals(self.rma_id_2.state, 'confirmed')
|
||||||
|
|
||||||
|
context = {"active_model": 'rma.request',
|
||||||
|
"active_ids": [self.rma_id_2.id], "active_id":
|
||||||
|
self.rma_id_2.id, "rma": True}
|
||||||
|
self.return_picking_id_2 = self.env[
|
||||||
|
'stock.return.picking'].with_context(context).create(dict(
|
||||||
|
picking_id=self.rma_id_2.picking_id.id,
|
||||||
|
))
|
||||||
|
self.return_picking_id_2.create_returns()
|
||||||
|
self.assertEquals(self.rma_id_2.state, 'replacement_created')
|
||||||
|
self.assertTrue(len(self.sale_order_id_2.picking_ids.ids) > 1,
|
||||||
|
'Product has not been replaced yet')
|
||||||
|
|
||||||
|
incoming_shipment = False
|
||||||
|
for pick in self.sale_order_id_2.picking_ids:
|
||||||
|
if pick.picking_type_code == 'incoming':
|
||||||
|
incoming_shipment = True
|
||||||
|
for move_line in pick.move_lines[0].move_line_ids:
|
||||||
|
move_line.lot_id = self.product1_lot_id.id
|
||||||
|
move_line.qty_done = 10
|
||||||
|
self.assertEquals(len(pick.move_lines[0].move_line_ids.ids), 1,
|
||||||
|
'Only one product can be returned')
|
||||||
|
pick.button_validate()
|
||||||
|
pick.action_done()
|
||||||
|
self.assertTrue(incoming_shipment, 'Incoming shipment is not created')
|
20
addons/rma/views/menuitems_view.xml
Normal file
20
addons/rma/views/menuitems_view.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<flectra>
|
||||||
|
<menuitem id="rma_request_menu"
|
||||||
|
name="Replacement"
|
||||||
|
parent="sale.sale_menu_root"
|
||||||
|
sequence="3"/>
|
||||||
|
|
||||||
|
<menuitem id="menu_request_rma"
|
||||||
|
name="Replace Request"
|
||||||
|
action="act_open_rma_request_view"
|
||||||
|
parent="rma_request_menu"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<menuitem id="menu_replacement_reason"
|
||||||
|
name="Replacement Reason"
|
||||||
|
action="act_open_replacement_reason_view"
|
||||||
|
parent="sale.menu_sale_config"
|
||||||
|
/>
|
||||||
|
</flectra>
|
41
addons/rma/views/replacement_reason_view.xml
Normal file
41
addons/rma/views/replacement_reason_view.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra>
|
||||||
|
<record id="view_replacement_reason_tree" model="ir.ui.view">
|
||||||
|
<field name="name">replacement.reason.tree</field>
|
||||||
|
<field name="model">replacement.reason</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="priority" eval="8"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree>
|
||||||
|
<field name="name"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_replacement_reason_form" model="ir.ui.view">
|
||||||
|
<field name="name">replacement.reason.form</field>
|
||||||
|
<field name="model">replacement.reason</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="priority" eval="8"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Reason">
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<field name="name"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window"
|
||||||
|
id="act_open_replacement_reason_view">
|
||||||
|
<field name="name">Replacement Reason</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">replacement.reason</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="domain">[]</field>
|
||||||
|
<field name="context">{}</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
73
addons/rma/views/rma_line_view.xml
Normal file
73
addons/rma/views/rma_line_view.xml
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra>
|
||||||
|
|
||||||
|
<record id="view_rma_line_form" model="ir.ui.view">
|
||||||
|
<field name="name">rma.line.form</field>
|
||||||
|
<field name="model">rma.line</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="priority" eval="8"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="RMA Lines">
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="product_id"/>
|
||||||
|
<field name="qty_delivered"/>
|
||||||
|
<field name="qty_replaced" required="1"/>
|
||||||
|
<field name="uom_id"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="rma_id"/>
|
||||||
|
<field name="reason_id" required="1" options="{'no_create': True}"/>
|
||||||
|
<field name="remark"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="act_open_rma_line_view">
|
||||||
|
<field name="name">RMA Lines</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">rma.line</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="domain">[]</field>
|
||||||
|
<field name="context">{}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_rma_line_filter" model="ir.ui.view">
|
||||||
|
<field name="name">rma.line.search.view</field>
|
||||||
|
<field name="model">rma.line</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="Search RMA Line">
|
||||||
|
<field name="team_id"/>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_rma_line_graph" model="ir.ui.view">
|
||||||
|
<field name="name">rma.line.graph</field>
|
||||||
|
<field name="model">rma.line</field>
|
||||||
|
<field name="priority" eval="8"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<graph string="Replacement Request">
|
||||||
|
<field name="product_id"/>
|
||||||
|
</graph>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="replacement_request_action_reports"
|
||||||
|
model="ir.actions.act_window">
|
||||||
|
<field name="name">Replacement Requests</field>
|
||||||
|
<field name="res_model">rma.line</field>
|
||||||
|
<field name="view_mode">graph,tree,form</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p>
|
||||||
|
No replacement request.
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
<field name="context">{'search_default_team_id': active_id}</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
186
addons/rma/views/rma_request_view.xml
Normal file
186
addons/rma/views/rma_request_view.xml
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra>
|
||||||
|
<record id="view_rma_request_tree" model="ir.ui.view">
|
||||||
|
<field name="name">rma.request.tree</field>
|
||||||
|
<field name="model">rma.request</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="priority" eval="8"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="sale_order_id"/>
|
||||||
|
<field name="partner_id"/>
|
||||||
|
<field name="type"/>
|
||||||
|
<field name="team_id"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_rma_request_form" model="ir.ui.view">
|
||||||
|
<field name="name">rma.request.form</field>
|
||||||
|
<field name="model">rma.request</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="priority" eval="8"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Requests for RMA">
|
||||||
|
<header>
|
||||||
|
<button name="action_notify_warranty"
|
||||||
|
string="Send By Email"
|
||||||
|
type="object" class="oe_highlight"/>
|
||||||
|
<button name="%(stock.act_stock_return_picking)d"
|
||||||
|
string="Create Replacement"
|
||||||
|
type="action" class="btn-primary"
|
||||||
|
attrs="{'invisible': [('state', 'in', ['draft', 'replacement_created'])]}"
|
||||||
|
context="{'rma': True}"
|
||||||
|
groups="stock.group_stock_manager"/>
|
||||||
|
<button name="action_confirm_request"
|
||||||
|
string="Confirm"
|
||||||
|
type="object" class="oe_highlight"
|
||||||
|
attrs="{'invisible': [('state', 'in', ['confirmed', 'replacement_created'])]}"/>
|
||||||
|
<field name="state" widget="statusbar"/>
|
||||||
|
</header>
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button type="object"
|
||||||
|
name="action_create_delivery"
|
||||||
|
class="oe_stat_button"
|
||||||
|
icon="fa-truck"
|
||||||
|
attrs="{'invisible': [('state', 'in', ['draft', 'confirmed'])]}">
|
||||||
|
<field name="picking_count"
|
||||||
|
widget="statinfo"
|
||||||
|
string="Delivery"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="name" readonly="1"
|
||||||
|
attrs="{'invisible': [('state', '=', 'draft')]}"
|
||||||
|
nolabel="1"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="sale_order_id" required="1"
|
||||||
|
attrs="{'readonly': [('state', '!=', 'draft')]}"
|
||||||
|
options="{'no_create': True}"
|
||||||
|
/>
|
||||||
|
<field name="partner_id" required="1"
|
||||||
|
options="{'no_create': True}"
|
||||||
|
attrs="{'readonly': [('state', '!=', 'draft')]}"
|
||||||
|
/>
|
||||||
|
<field name="picking_id" required="1"
|
||||||
|
options="{'no_create': True}"
|
||||||
|
domain="[('sale_id', '=', sale_order_id),
|
||||||
|
('state', '=', 'done'), ('picking_type_code', '=', 'outgoing')]"
|
||||||
|
attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||||
|
<field name="user_id" invisible="1"/>
|
||||||
|
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="date" required="1"
|
||||||
|
attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||||
|
<field name="team_id" required="1"
|
||||||
|
attrs="{'readonly': [('state', '!=', 'draft')]}"
|
||||||
|
options="{'no_create': True}"/>
|
||||||
|
<field name="type" required="1"
|
||||||
|
attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="RMA Lines">
|
||||||
|
<field name="rma_line"
|
||||||
|
attrs="{'readonly': [('state', '!=', 'draft')]}">
|
||||||
|
<tree editable="bottom" create="false">
|
||||||
|
<field name="product_id" readonly="1"
|
||||||
|
force_save="1"/>
|
||||||
|
<field name="uom_id" readonly="1"
|
||||||
|
force_save="1"/>
|
||||||
|
<field name="qty_delivered" readonly="1"
|
||||||
|
force_save="1"/>
|
||||||
|
<field name="qty_replaced" required="1"/>
|
||||||
|
<field name="reason_id" required="1"
|
||||||
|
options="{'no_create': True}"/>
|
||||||
|
<field name="remark"/>
|
||||||
|
<field name="rma_id" invisible="1"/>
|
||||||
|
<field name="move_line_id" invisible="1"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
<page string="Warranty Expire Lines">
|
||||||
|
<field name="warranty_expire_line"
|
||||||
|
attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
<div class="oe_chatter">
|
||||||
|
<field name="message_follower_ids" widget="mail_followers"
|
||||||
|
groups="base.group_user"/>
|
||||||
|
<field name="activity_ids" widget="mail_activity"/>
|
||||||
|
<field name="message_ids" widget="mail_thread"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_rma_request_filter" model="ir.ui.view">
|
||||||
|
<field name="name">rma.request.search.view</field>
|
||||||
|
<field name="model">rma.request</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="Search RMA Request">
|
||||||
|
<field name="name" string="RMA Request"
|
||||||
|
filter_domain="[('name','ilike',self)]"/>
|
||||||
|
<field name="partner_id" operator="child_of"/>
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="state"/>
|
||||||
|
<field name="team_id" string="Sales Channel"/>
|
||||||
|
<filter string="My Requests"
|
||||||
|
domain="[('user_id','=',uid)]"
|
||||||
|
name="my_rma_request_filter"/>
|
||||||
|
<filter string="Replacement Created"
|
||||||
|
domain="[('state','=','replacement_created')]"
|
||||||
|
name="rma_request_state_filter"/>
|
||||||
|
<separator/>
|
||||||
|
<group expand="1" string="Group By">
|
||||||
|
<filter string="Partner" name="Partner"
|
||||||
|
context="{'group_by':'partner_id'}"/>
|
||||||
|
<filter string="Sale Order"
|
||||||
|
context="{'group_by':'sale_order_id'}"/>
|
||||||
|
<filter string="State"
|
||||||
|
context="{'group_by':'state'}"/>
|
||||||
|
<separator/>
|
||||||
|
<filter string="Request Month"
|
||||||
|
context="{'group_by':'date:month'}"/>
|
||||||
|
</group>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="act_open_rma_request_view">
|
||||||
|
<field name="name">RMA Request</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">rma.request</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="domain">[]</field>
|
||||||
|
<field name="context">{}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window"
|
||||||
|
id="action_open_rma_request_replacementteam">
|
||||||
|
<field name="name">RMA Request</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">rma.request</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="domain">[]</field>
|
||||||
|
<field name="context">{
|
||||||
|
'search_default_team_id': [active_id],
|
||||||
|
'default_team_id': active_id,
|
||||||
|
}
|
||||||
|
</field>
|
||||||
|
<field name="search_view_id" ref="view_rma_request_filter"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</flectra>
|
79
addons/rma/views/sales_team_view.xml
Normal file
79
addons/rma/views/sales_team_view.xml
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra>
|
||||||
|
<record id="crm_team_replacement_teams_view_form" model="ir.ui.view">
|
||||||
|
<field name="name">replacement.team.form</field>
|
||||||
|
<field name="model">crm.team</field>
|
||||||
|
<field name="inherit_id" ref="sales_team.crm_team_view_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//div[@name='options_active']" position="inside">
|
||||||
|
<div class="o_row" style="display:inherit">
|
||||||
|
<field name="use_replacement"/>
|
||||||
|
<label for="use_replacement"/>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="crm_team_replacement_teams_view_kanban" model="ir.ui.view">
|
||||||
|
<field name="name">replacement.team.kanban</field>
|
||||||
|
<field name="model">crm.team</field>
|
||||||
|
<field name="inherit_id"
|
||||||
|
ref="sale.crm_team_salesteams_view_kanban"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<data>
|
||||||
|
<xpath expr="//div[hasclass('o_kanban_primary_left')]"
|
||||||
|
position="inside">
|
||||||
|
<div>
|
||||||
|
<button name="%(rma.action_open_rma_request_replacementteam)d"
|
||||||
|
type="action"
|
||||||
|
class="btn btn-primary mt8">Replacements
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//t[@name='second_options']"
|
||||||
|
position="after">
|
||||||
|
<div class="row" t-if="record.replacements_count.raw_value">
|
||||||
|
<div class="col-xs-8">
|
||||||
|
<a name="%(rma.action_open_rma_request_replacementteam)d"
|
||||||
|
type="action">
|
||||||
|
<field name="replacements_count"/>
|
||||||
|
<t t-if="record.replacements_count.raw_value == 1">
|
||||||
|
Replacement
|
||||||
|
</t>
|
||||||
|
<t t-else="">Replacements</t>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//div[hasclass('o_kanban_manage_view')]"
|
||||||
|
position="inside">
|
||||||
|
<div>
|
||||||
|
<a name="%(rma.action_open_rma_request_replacementteam)d"
|
||||||
|
type="action">Replacements
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</data>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="replacement_view_kanban" model="ir.ui.view">
|
||||||
|
<field name="name">replacement.kanban</field>
|
||||||
|
<field name="model">crm.team</field>
|
||||||
|
<field name="inherit_id"
|
||||||
|
ref="sales_team.crm_team_salesteams_view_kanban"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<data>
|
||||||
|
<xpath expr="//div[hasclass('o_kanban_manage_reports')]"
|
||||||
|
position="inside">
|
||||||
|
<div name="replacement_report">
|
||||||
|
<a name="%(rma.replacement_request_action_reports)d"
|
||||||
|
type="action" context="{'search_default_team_id': active_id}">
|
||||||
|
Replacement
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</data>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
15
addons/rma/views/stock_picking_view.xml
Normal file
15
addons/rma/views/stock_picking_view.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra>
|
||||||
|
|
||||||
|
<record id="view_stock_picking_form" model="ir.ui.view">
|
||||||
|
<field name="name">stock.picking.form</field>
|
||||||
|
<field name="model">stock.picking</field>
|
||||||
|
<field name="inherit_id" ref="stock.view_picking_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//page[@name='extra']/group/group" position="inside">
|
||||||
|
<field name="rma_id"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</flectra>
|
13
addons/rma/views/stock_production_lot_view.xml
Normal file
13
addons/rma/views/stock_production_lot_view.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra>
|
||||||
|
<record id="view_stock_production_lot_form_inherit" model="ir.ui.view">
|
||||||
|
<field name="name">stock.production.lot.form.inherit</field>
|
||||||
|
<field name="model">stock.production.lot</field>
|
||||||
|
<field name="inherit_id" ref="stock.view_production_lot_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//field[@name='ref']" position="after">
|
||||||
|
<field name="warranty_date" groups="stock.group_stock_manager"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
47
addons/rma/views/warranty_expire_line_view.xml
Normal file
47
addons/rma/views/warranty_expire_line_view.xml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<flectra>
|
||||||
|
<record id="view_warranty_expire_line_tree" model="ir.ui.view">
|
||||||
|
<field name="name">warranty.expire..line.tree</field>
|
||||||
|
<field name="model">warranty.expire.line</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="priority" eval="8"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree create="false" edit="false">
|
||||||
|
<field name="rma_id" invisible="1"/>
|
||||||
|
<field name="product_id"/>
|
||||||
|
<field name="lot_id"/>
|
||||||
|
<field name="qty_expired"/>
|
||||||
|
<field name="warranty_date"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_warranty_expire_line_form" model="ir.ui.view">
|
||||||
|
<field name="name">warranty.expire.line.form</field>
|
||||||
|
<field name="model">warranty.expire.line</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="priority" eval="8"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Warranty Expire Lines">
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<field name="product_id" readonly="1"/>
|
||||||
|
<field name="lot_id" readonly="1"/>
|
||||||
|
<field name="qty_expired" readonly="1"/>
|
||||||
|
<field name="warranty_date" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="act_open_warranty_expire_line_view">
|
||||||
|
<field name="name">Warranty Expire Lines</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">warranty.expire.line</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="domain">[]</field>
|
||||||
|
<field name="context">{}</field>
|
||||||
|
</record>
|
||||||
|
</flectra>
|
3
addons/rma/wizard/__init__.py
Normal file
3
addons/rma/wizard/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import stock_return_picking
|
98
addons/rma/wizard/stock_return_picking.py
Normal file
98
addons/rma/wizard/stock_return_picking.py
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra import api, models, _
|
||||||
|
from flectra.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
|
class ReturnPicking(models.TransientModel):
|
||||||
|
_inherit = 'stock.return.picking'
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def default_get(self, fields):
|
||||||
|
if self._context.get('rma') and self._context.get('active_model') ==\
|
||||||
|
'rma.request':
|
||||||
|
res = {}
|
||||||
|
if len(self.env.context.get('active_ids', list())) > 1:
|
||||||
|
raise UserError(_(
|
||||||
|
"You may only replace single picking at a time!"))
|
||||||
|
move_dest_exists = False
|
||||||
|
product_return_moves = []
|
||||||
|
rma_id = self.env['rma.request'].browse(
|
||||||
|
self.env.context.get('active_id'))
|
||||||
|
picking = rma_id.picking_id
|
||||||
|
if picking:
|
||||||
|
res.update({'picking_id': picking.id})
|
||||||
|
if picking.state != 'done':
|
||||||
|
raise UserError(_("You may only return Done pickings"))
|
||||||
|
|
||||||
|
for move_line in picking.move_lines:
|
||||||
|
qty = move_line.product_qty or 0.00
|
||||||
|
if move_line.move_line_ids:
|
||||||
|
product_ids = [line.product_id for line in
|
||||||
|
move_line.move_line_ids]
|
||||||
|
vals = {}
|
||||||
|
for rma_line in rma_id.rma_line:
|
||||||
|
vals.update({
|
||||||
|
rma_line.product_id.id: rma_line.qty_replaced,
|
||||||
|
})
|
||||||
|
for prod_id in product_ids:
|
||||||
|
if vals.get(prod_id.id):
|
||||||
|
qty = vals.get(prod_id.id)
|
||||||
|
if move_line.scrapped:
|
||||||
|
continue
|
||||||
|
if move_line.move_dest_ids:
|
||||||
|
move_dest_exists = True
|
||||||
|
quantity = qty - sum(
|
||||||
|
move_line.move_dest_ids.filtered(
|
||||||
|
lambda m: m.state in [
|
||||||
|
'partially_available', 'assigned', 'done']
|
||||||
|
).mapped('move_line_ids').mapped('product_qty'))
|
||||||
|
product = [line.product_id for line in rma_id.rma_line]
|
||||||
|
for pid in product:
|
||||||
|
if move_line.product_id.id == pid.id:
|
||||||
|
product_return_moves.append(
|
||||||
|
(0, 0,
|
||||||
|
{
|
||||||
|
'product_id': move_line.product_id.id,
|
||||||
|
'quantity': quantity,
|
||||||
|
'move_id': move_line.id
|
||||||
|
}))
|
||||||
|
|
||||||
|
if not product_return_moves:
|
||||||
|
raise UserError(_(
|
||||||
|
"No products to replace (only lines in Done state and"
|
||||||
|
"not fully replaced yet can be replaced)!"))
|
||||||
|
if 'product_return_moves' in fields:
|
||||||
|
res.update({'product_return_moves': product_return_moves})
|
||||||
|
if 'move_dest_exists' in fields:
|
||||||
|
res.update({'move_dest_exists': move_dest_exists})
|
||||||
|
if 'parent_location_id' in fields and picking.\
|
||||||
|
location_id.usage == 'internal':
|
||||||
|
res.update(
|
||||||
|
{
|
||||||
|
'parent_location_id':
|
||||||
|
picking.picking_type_id.warehouse_id and
|
||||||
|
picking.picking_type_id.warehouse_id.
|
||||||
|
view_location_id.id or picking.
|
||||||
|
location_id.location_id.id
|
||||||
|
})
|
||||||
|
if 'original_location_id' in fields:
|
||||||
|
res.update(
|
||||||
|
{'original_location_id': picking.location_id.id})
|
||||||
|
if 'location_id' in fields:
|
||||||
|
location_id = picking.location_id.id
|
||||||
|
if picking.picking_type_id.return_picking_type_id.\
|
||||||
|
default_location_dest_id.return_location:
|
||||||
|
location_id = picking.picking_type_id.\
|
||||||
|
return_picking_type_id.default_location_dest_id.id
|
||||||
|
res['location_id'] = location_id
|
||||||
|
return res
|
||||||
|
return super(ReturnPicking, self).default_get(fields)
|
||||||
|
|
||||||
|
def create_returns(self):
|
||||||
|
if self._context.get('rma') and self._context.get('active_model') == \
|
||||||
|
'rma.request':
|
||||||
|
rma_id = self.env['rma.request'].browse(
|
||||||
|
self.env.context.get('active_id'))
|
||||||
|
rma_id.state = 'replacement_created'
|
||||||
|
return super(ReturnPicking, self).create_returns()
|
Loading…
Reference in New Issue
Block a user