mirror of
https://github.com/OCA/rma.git
synced 2025-02-16 17:11:47 +02:00
Merge pull request #4 from LeartS/port_crm_claim_rma_fixes
Improvements to the port of crm_claim_rma
This commit is contained in:
@@ -22,7 +22,5 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import wizard
|
||||
from . import crm_claim_rma
|
||||
from . import account_invoice
|
||||
from . import stock
|
||||
from . import models
|
||||
from . import wizards
|
||||
|
||||
@@ -71,30 +71,33 @@ Contributors:
|
||||
* Javier Carrasco <javier.carrasco@eezee-it.com>
|
||||
|
||||
""",
|
||||
'author': "Akretion, Camptocamp, Eezee-it, "
|
||||
'author': "Akretion, Camptocamp, Eezee-it, MONK Software"
|
||||
"Odoo Community Association (OCA)",
|
||||
'website': 'http://www.akretion.com, http://www.camptocamp.com, '
|
||||
'http://www.eezee-it.com',
|
||||
'http://www.eezee-it.com, http://www.wearemonk.com',
|
||||
'license': 'AGPL-3',
|
||||
'depends': ['sale',
|
||||
'stock',
|
||||
'crm_claim',
|
||||
'crm_claim_code',
|
||||
'product_warranty',
|
||||
],
|
||||
'data': ['wizard/claim_make_picking_view.xml',
|
||||
'crm_claim_rma_view.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'account_invoice_view.xml',
|
||||
'res_partner_view.xml',
|
||||
'crm_claim_rma_data.xml',
|
||||
],
|
||||
'depends': [
|
||||
'sale',
|
||||
'stock',
|
||||
'crm_claim',
|
||||
'crm_claim_code',
|
||||
'product_warranty',
|
||||
],
|
||||
'data': [
|
||||
'wizards/claim_make_picking.xml',
|
||||
'views/crm_claim_rma.xml',
|
||||
'views/account_invoice.xml',
|
||||
'views/res_partner.xml',
|
||||
'data/crm_claim_rma.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',
|
||||
],
|
||||
'images': [
|
||||
'images/product_return.png',
|
||||
'images/claim.png',
|
||||
'images/return_line.png',
|
||||
'images/exchange.png',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
|
||||
@@ -1,416 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Return line -->
|
||||
<!-- 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="Returned 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>
|
||||
|
||||
<!-- 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>
|
||||
|
||||
<record model="ir.ui.view" id="crm_case_claims_form_view_replace">
|
||||
<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">
|
||||
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'crm.claim')]" position="replace">
|
||||
<field name="categ_id" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<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">
|
||||
<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>
|
||||
<group>
|
||||
<!-- Place for mass return button from crm_rma_lot_mass_return -->
|
||||
</group>
|
||||
<field name="claim_line_ids" nolabel="1" colspan="4" editable="top">
|
||||
<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" context="{'claim_id': parent.id, 'company_id': parent.company_id, 'warehouse_id': parent.warehouse_id, 'claim_type': parent.claim_type, 'claim_date': parent.date}"/>
|
||||
<field name="prodlot_id"/>
|
||||
<field name="unit_sale_price"/>
|
||||
<field name="return_value"/>
|
||||
</group>
|
||||
<group string="Linked Document">
|
||||
<field name="invoice_line_id" context="{'claim_id': parent.id, 'company_id': parent.company_id, 'warehouse_id': parent.warehouse_id, 'claim_type': parent.claim_type, 'claim_date': parent.date}"/>
|
||||
<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>
|
||||
</group>
|
||||
<group col="4" colspan="4" attrs="{'invisible':[('stage_id', 'not in', [%(crm_claim.stage_claim1)d, %(crm_claim.stage_claim5)d])]}">
|
||||
<separator string="Actions" colspan="4"/>
|
||||
<button name="%(action_claim_picking_in)d"
|
||||
string="New Products Return"
|
||||
type="action" target="new"
|
||||
context="{'warehouse_id': warehouse_id,
|
||||
'partner_id': partner_id}"
|
||||
class="oe_highlight"/>
|
||||
|
||||
<button name="%(action_claim_picking_out)d"
|
||||
string="New Delivery"
|
||||
type="action" target="new"
|
||||
context="{'warehouse_id': warehouse_id,
|
||||
'partner_id': partner_id}"
|
||||
class="oe_highlight"/>
|
||||
|
||||
<button name="%(account.action_account_invoice_refund)d"
|
||||
type='action' string='New Refund'
|
||||
context="{
|
||||
'invoice_ids': [invoice_id],
|
||||
'claim_line_ids': claim_line_ids,
|
||||
'description': name,
|
||||
'claim_id': id}"
|
||||
class="oe_highlight"/>
|
||||
</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>
|
||||
|
||||
|
||||
<!-- 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.ui.view" id="crm_claim_rma_form_view2">
|
||||
<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">
|
||||
<field name="date_deadline" position="after">
|
||||
<field name="claim_type" context="{'create_lines': False}" />
|
||||
<field name="warehouse_id" context="{'create_lines': False}"/>
|
||||
</field>
|
||||
<field name="date" position="replace">
|
||||
</field>
|
||||
<field name="user_id" position="before">
|
||||
<field name="name" />
|
||||
<field name="date" context="{'create_lines': False}"/>
|
||||
</field>
|
||||
<xpath expr="//sheet[@string='Claims']/group[1]" position="inside">
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<button name="%(act_crm_claim_rma_sale_orders)d" type="action"
|
||||
string="Sales"
|
||||
icon="fa-strikethrough"
|
||||
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in', ['supplier','other'])]}"
|
||||
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"
|
||||
class="oe_inline oe_stat_button"/>
|
||||
|
||||
<button name="%(act_crm_claim_rma_invoice_out)d" type="action"
|
||||
string="Invoices"
|
||||
icon="fa-pencil-square-o"
|
||||
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in', ['supplier','other'])]}"
|
||||
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"
|
||||
class="oe_inline oe_stat_button"/>
|
||||
|
||||
<button name="%(act_crm_claim_rma_refunds_out)d" type="action"
|
||||
string="Refunds"
|
||||
icon="fa-file-text-o"
|
||||
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in', ['supplier','other'])]}"
|
||||
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"
|
||||
class="oe_inline oe_stat_button"/>
|
||||
|
||||
<button name="%(act_crm_claim_rma_invoice_in)d" type="action"
|
||||
string="Invoices"
|
||||
icon="fa-pencil-square-o"
|
||||
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in', ['customer','other'])]}"
|
||||
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"
|
||||
class="oe_inline oe_stat_button"/>
|
||||
|
||||
<button name="%(act_crm_claim_rma_refunds_in)d" type="action"
|
||||
string="Refunds"
|
||||
icon="fa-file-text-o"
|
||||
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in', ['customer','other'])]}"
|
||||
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"
|
||||
class="oe_inline oe_stat_button"/>
|
||||
|
||||
<button name="%(act_crm_claim_rma_picking_in)d" type="action"
|
||||
string="Products"
|
||||
icon="fa-reply"
|
||||
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in', ['supplier','other'])]}"
|
||||
context="{'search_default_claim_id': active_id,'search_default_user_id':False}"
|
||||
class="oe_inline oe_stat_button"/>
|
||||
|
||||
<button name="%(act_crm_claim_rma_picking_out)d" type="action"
|
||||
string="Deliveries"
|
||||
icon="fa-truck"
|
||||
attrs="{'invisible': ['|',('partner_id','=', False),('claim_type','in', ['supplier','other'])]}"
|
||||
context="{'search_default_partner_id': [partner_id],'search_default_user_id':False}"
|
||||
class="oe_inline oe_stat_button"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</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>
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
<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>
|
||||
|
||||
<!-- return 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="Return lines" id="menu_crm_case_claims_claim_lines"
|
||||
parent="base.menu_aftersale" action="act_crm_case_claim_lines" sequence="2"/>
|
||||
<menuitem name="Returned line substates" id="menu_crm_case_claims_claim_line_substates"
|
||||
parent="crm_claim.menu_config_claim" action="act_crm_claim_substates" sequence="2"/>
|
||||
</data>
|
||||
</openerp>
|
||||
3
crm_claim_rma/models/__init__.py
Normal file
3
crm_claim_rma/models/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from . import crm_claim_rma
|
||||
from . import account_invoice
|
||||
from . import stock
|
||||
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# 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
|
||||
# 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
|
||||
@@ -22,33 +22,35 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.models import Model, api, _
|
||||
from openerp import fields
|
||||
from openerp import models, fields, api, exceptions
|
||||
from openerp.tools.translate import _
|
||||
|
||||
|
||||
class AccountInvoice(Model):
|
||||
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."""
|
||||
new_lines = []
|
||||
inv_line_obj = self.env['account.invoice.line']
|
||||
claim_line_obj = self.env['claim.line']
|
||||
|
||||
"""
|
||||
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'):
|
||||
return super(AccountInvoice, self)._refund_cleanup_lines(lines)
|
||||
|
||||
for __, claim_line_id, __ in self.env.context.get('claim_line_ids'):
|
||||
line = claim_line_obj.browse(claim_line_id)
|
||||
if not line.refund_line_id:
|
||||
# start by browsing all the lines so that Odoo will correctly prefetch
|
||||
line_ids = [l[1] for l in self.env.context['claim_line_ids']]
|
||||
claim_lines = self.env['claim.line'].browse(line_ids)
|
||||
|
||||
new_lines = []
|
||||
for claim_line in claim_lines:
|
||||
if not claim_line.refund_line_id:
|
||||
# For each lines replace quantity and add claim_line_id
|
||||
inv_line = inv_line_obj.browse(line.invoice_line_id.id)
|
||||
inv_line = claim_line.invoice_line_id
|
||||
clean_line = {}
|
||||
for field_name, field in inv_line._all_columns.iteritems():
|
||||
column_type = field.column._type
|
||||
@@ -57,17 +59,15 @@ class AccountInvoice(Model):
|
||||
elif column_type not in ('many2many', 'one2many'):
|
||||
clean_line[field_name] = inv_line[field_name]
|
||||
elif field_name == 'invoice_line_tax_id':
|
||||
tax_list = []
|
||||
for tax in inv_line[field_name]:
|
||||
tax_list.append(tax.id)
|
||||
clean_line[field_name] = [(6, 0, tax_list)]
|
||||
clean_line['quantity'] = line['product_returned_quantity']
|
||||
clean_line['claim_line_id'] = [claim_line_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 Warning(
|
||||
raise exceptions.Warning(
|
||||
_('A refund has already been created for this claim !'))
|
||||
return [(0, 0, l) for l in new_lines]
|
||||
|
||||
@@ -79,24 +79,23 @@ class AccountInvoice(Model):
|
||||
journal_id=journal_id)
|
||||
|
||||
if self.env.context.get('claim_id'):
|
||||
result['claim_id'] = self.env.context.get('claim_id')
|
||||
result['claim_id'] = self.env.context['claim_id']
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class AccountInvoiceLine(Model):
|
||||
class AccountInvoiceLine(models.Model):
|
||||
_inherit = "account.invoice.line"
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
claim_line_id = False
|
||||
if vals.get('claim_line_id'):
|
||||
claim_line_id = vals['claim_line_id']
|
||||
claim_line_id = vals.get('claim_line_id')
|
||||
if claim_line_id:
|
||||
del vals['claim_line_id']
|
||||
|
||||
line_id = super(AccountInvoiceLine, self).create(vals)
|
||||
line = super(AccountInvoiceLine, self).create(vals)
|
||||
if claim_line_id:
|
||||
claim_line = self.env['claim.line'].browse(claim_line_id)
|
||||
claim_line.write({'refund_line_id': line_id.id})
|
||||
claim_line.refund_line_id = line.id
|
||||
|
||||
return line_id
|
||||
return line
|
||||
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# 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
|
||||
# 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
|
||||
@@ -21,18 +21,16 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.models import Model, api, _
|
||||
from openerp import fields
|
||||
from openerp.tools import (DEFAULT_SERVER_DATE_FORMAT,
|
||||
DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
from openerp.exceptions import except_orm, Warning
|
||||
|
||||
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
|
||||
@@ -44,7 +42,7 @@ class ProductNoSupplier(Exception):
|
||||
because the product has no supplier. """
|
||||
|
||||
|
||||
class SubstateSubstate(Model):
|
||||
class SubstateSubstate(models.Model):
|
||||
""" To precise a state (state=refused; substates= reason 1, 2,...) """
|
||||
_name = "substate.substate"
|
||||
_description = "substate that precise a given state"
|
||||
@@ -55,7 +53,7 @@ class SubstateSubstate(Model):
|
||||
help="To give more information about the sub state")
|
||||
|
||||
|
||||
class ClaimLine(Model):
|
||||
class ClaimLine(models.Model):
|
||||
"""
|
||||
Class to handle a product return line (corresponding to one invoice line)
|
||||
"""
|
||||
@@ -88,9 +86,7 @@ class ClaimLine(Model):
|
||||
return super(ClaimLine, self).copy_data(default=std_default)
|
||||
|
||||
def get_warranty_return_partner(self):
|
||||
seller = self.env['product.supplierinfo']
|
||||
result = seller.get_warranty_return_partner()
|
||||
return result
|
||||
return self.env['product.supplierinfo'].get_warranty_return_partner()
|
||||
|
||||
name = fields.Char(string='Description', required=True, default=None)
|
||||
claim_origine = fields.Selection(
|
||||
@@ -203,7 +199,6 @@ class ClaimLine(Model):
|
||||
``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)
|
||||
@@ -229,11 +224,10 @@ class ClaimLine(Model):
|
||||
date_invoice = datetime.strptime(date_invoice,
|
||||
DEFAULT_SERVER_DATE_FORMAT)
|
||||
if claim_type == 'supplier':
|
||||
suppliers = product.seller_ids
|
||||
if not suppliers:
|
||||
try:
|
||||
warranty_duration = product.seller_ids[0].warranty_duration
|
||||
except IndexError:
|
||||
raise ProductNoSupplier
|
||||
supplier = suppliers[0]
|
||||
warranty_duration = supplier.warranty_duration
|
||||
else:
|
||||
warranty_duration = product.warranty
|
||||
|
||||
@@ -250,20 +244,17 @@ class ClaimLine(Model):
|
||||
'warning': warning}
|
||||
|
||||
def set_warranty_limit(self):
|
||||
self.ensure_one()
|
||||
claim = self.claim_id
|
||||
invoice = claim.invoice_id
|
||||
claim_type = claim.claim_type
|
||||
claim_date = claim.date
|
||||
product = self.product_id
|
||||
try:
|
||||
values = self._warranty_limit_values(invoice, claim_type, product,
|
||||
claim_date)
|
||||
values = self._warranty_limit_values(
|
||||
claim.invoice_id, claim.claim_type, self.product_id, claim.date)
|
||||
except InvoiceNoDate:
|
||||
raise Warning(
|
||||
raise exceptions.Warning(
|
||||
_('Error'), _('Cannot find any date for invoice. '
|
||||
'Must be a validated invoice.'))
|
||||
except ProductNoSupplier:
|
||||
raise Warning(
|
||||
raise exceptions.Warning(
|
||||
_('Error'), _('The product has no supplier configured.'))
|
||||
|
||||
self.write(values)
|
||||
@@ -279,19 +270,20 @@ class ClaimLine(Model):
|
||||
line.set_warranty()
|
||||
return True
|
||||
|
||||
@api.returns('stock.location')
|
||||
def get_destination_location(self, product, warehouse):
|
||||
"""Compute and return the destination location ID to take
|
||||
"""
|
||||
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.lot_stock_id.id
|
||||
if product:
|
||||
sellers = product.seller_ids
|
||||
if sellers:
|
||||
seller = sellers[0]
|
||||
return_type = seller.warranty_return_partner
|
||||
if return_type != 'company':
|
||||
location_dest_id = seller.name.property_stock_supplier.id
|
||||
return location_dest_id
|
||||
from company.
|
||||
"""
|
||||
location_dest_id = warehouse.lot_stock_id
|
||||
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):
|
||||
@@ -315,7 +307,7 @@ class ClaimLine(Model):
|
||||
return False
|
||||
|
||||
invoice = invoice_line.invoice_id
|
||||
claim_line_obj = self.env['claim.line']
|
||||
claim_line_model = self.env['claim.line']
|
||||
|
||||
if claim:
|
||||
claim = self.env['crm.claim'].browse(claim)
|
||||
@@ -331,7 +323,7 @@ class ClaimLine(Model):
|
||||
|
||||
values = {}
|
||||
try:
|
||||
warranty = claim_line_obj._warranty_limit_values(
|
||||
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
|
||||
@@ -339,27 +331,27 @@ class ClaimLine(Model):
|
||||
values.update({'guarantee_limit': False, 'warning': False})
|
||||
else:
|
||||
values.update(warranty)
|
||||
|
||||
warranty_address = claim_line_obj._warranty_return_address_values(
|
||||
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
|
||||
"""
|
||||
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 case here:
|
||||
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}
|
||||
return {
|
||||
'warranty_return_partner': False,
|
||||
'warranty_type': False,
|
||||
'location_dest_id': False
|
||||
}
|
||||
sellers = product.seller_ids
|
||||
if sellers:
|
||||
seller = sellers[0]
|
||||
@@ -371,35 +363,34 @@ class ClaimLine(Model):
|
||||
company.partner_id)
|
||||
return_address_id = return_address.id
|
||||
return_type = 'company'
|
||||
location_dest_id = self.get_destination_location(product, warehouse)
|
||||
return {'warranty_return_partner': return_address_id,
|
||||
'warranty_type': return_type,
|
||||
'location_dest_id': location_dest_id}
|
||||
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
|
||||
product = self.product_id
|
||||
company = claim.company_id
|
||||
warehouse = claim.warehouse_id
|
||||
values = self._warranty_return_address_values(
|
||||
product, company, warehouse)
|
||||
self.product_id, claim.company_id, claim.warehouse_id)
|
||||
self.write(values)
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
@api.one
|
||||
def set_warranty(self):
|
||||
""" Calculate warranty limit and address """
|
||||
for claim_line in self:
|
||||
if not (claim_line.product_id and claim_line.invoice_line_id):
|
||||
raise Warning(
|
||||
_('Error'), _('Please set product and invoice.'))
|
||||
claim_line.set_warranty_limit()
|
||||
claim_line.set_warranty_return_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(Model):
|
||||
class CrmClaim(models.Model):
|
||||
_inherit = 'crm.claim'
|
||||
|
||||
def _get_default_warehouse(self):
|
||||
@@ -407,19 +398,16 @@ class CrmClaim(Model):
|
||||
wh_obj = self.env['stock.warehouse']
|
||||
wh = wh_obj.search([('company_id', '=', company_id)], limit=1)
|
||||
if not wh:
|
||||
raise Warning(
|
||||
raise exceptions.Warning(
|
||||
_('There is no warehouse for the current user\'s company.'))
|
||||
return wh
|
||||
|
||||
@api.multi
|
||||
@api.one
|
||||
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
|
||||
return (self.id, '[{}] {}'.format(self.code or '', self.name))
|
||||
|
||||
def copy_data(self, cr, uid, id, default=None, context=None):
|
||||
@api.model
|
||||
def copy_data(self, default=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
std_default = {
|
||||
@@ -428,8 +416,7 @@ class CrmClaim(Model):
|
||||
'code': self.env['ir.sequence'].get('crm.claim'),
|
||||
}
|
||||
std_default.update(default)
|
||||
return super(CrmClaim, self).copy_data(cr, uid, id, std_default,
|
||||
context=context)
|
||||
return super(CrmClaim, self).copy_data(std_default)
|
||||
|
||||
claim_type = fields.Selection(
|
||||
[('customer', 'Customer'),
|
||||
@@ -441,7 +428,7 @@ class CrmClaim(Model):
|
||||
help="Customer: from customer to company.\n "
|
||||
"Supplier: from company to supplier.")
|
||||
claim_line_ids = fields.One2many('claim.line', 'claim_id',
|
||||
string='Return lines')
|
||||
string='Claim lines')
|
||||
planned_revenue = fields.Float(string='Expected revenue')
|
||||
planned_cost = fields.Float(string='Expected cost')
|
||||
real_revenue = fields.Float(string='Real revenue')
|
||||
@@ -498,7 +485,7 @@ class CrmClaim(Model):
|
||||
|
||||
if create_lines: # happens when the invoice is changed
|
||||
for invoice_line in invoice_lines:
|
||||
location_dest_id = claim_line_obj.get_destination_location(
|
||||
location_dest = claim_line_obj.get_destination_location(
|
||||
invoice_line.product_id, warehouse)
|
||||
line = {
|
||||
'name': invoice_line.name,
|
||||
@@ -507,7 +494,7 @@ class CrmClaim(Model):
|
||||
'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,
|
||||
'location_dest_id': location_dest.id,
|
||||
'state': 'draft',
|
||||
}
|
||||
line.update(warranty_values(invoice_line.invoice_id,
|
||||
@@ -531,8 +518,7 @@ class CrmClaim(Model):
|
||||
|
||||
@api.model
|
||||
def message_get_suggested_recipients(self):
|
||||
recipients = super(CrmClaim, self
|
||||
).message_get_suggested_recipients()
|
||||
recipients = super(CrmClaim, self).message_get_suggested_recipients()
|
||||
try:
|
||||
for claim in self:
|
||||
if claim.partner_id:
|
||||
@@ -543,7 +529,7 @@ class CrmClaim(Model):
|
||||
self._message_add_suggested_recipient(
|
||||
recipients, claim,
|
||||
email=claim.email_from, reason=_('Customer Email'))
|
||||
except except_orm:
|
||||
except exceptions.AccessError:
|
||||
# no read access rights -> just ignore suggested recipients
|
||||
# because this imply modifying followers
|
||||
pass
|
||||
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# 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
|
||||
# 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
|
||||
@@ -22,40 +22,35 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.models import Model, api
|
||||
from openerp.fields import Many2one
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
class StockPicking(Model):
|
||||
class StockPicking(models.Model):
|
||||
_inherit = "stock.picking"
|
||||
|
||||
claim_id = Many2one('crm.claim', string='Claim')
|
||||
claim_id = fields.Many2one('crm.claim', string='Claim')
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if ('name' not in vals) or (vals.get('name') == '/'):
|
||||
sequence_obj = self.env['ir.sequence']
|
||||
seq_obj_name = self._name
|
||||
vals['name'] = sequence_obj.get(seq_obj_name)
|
||||
|
||||
picking = super(StockPicking, self).create(vals)
|
||||
return picking
|
||||
vals['name'] = self.env['ir.sequence'].get(self._name)
|
||||
return super(StockPicking, self).create(vals)
|
||||
|
||||
|
||||
# This part concern the case of a wrong picking out. We need to create a new
|
||||
# stock_move in a picking already open.
|
||||
# In order to don't have to confirm the stock_move we override the create and
|
||||
# confirm it at the creation only for this case
|
||||
class StockMove(Model):
|
||||
class StockMove(models.Model):
|
||||
_inherit = "stock.move"
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
"""
|
||||
In case of a wrong picking out, We need to create a new stock_move in a
|
||||
picking already open.
|
||||
To avoid having to confirm the stock_move, we override the create and
|
||||
confirm it at the creation only for this case.
|
||||
"""
|
||||
move = super(StockMove, self).create(vals)
|
||||
if vals.get('picking_id'):
|
||||
picking_obj = self.env['stock.picking']
|
||||
picking = picking_obj.browse(vals['picking_id'])
|
||||
picking = self.env['stock.picking'].browse(vals['picking_id'])
|
||||
if picking.claim_id and picking.picking_type_id.code == 'incoming':
|
||||
move.write({'state': 'confirmed'})
|
||||
|
||||
return move
|
||||
@@ -18,4 +18,4 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import test_lp_1282584
|
||||
from . import test_picking_creation
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Yannick Vaucher
|
||||
# Copyright 2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.tests.common import TransactionCase
|
||||
|
||||
|
||||
class test_lp_1282584(TransactionCase):
|
||||
""" Test wizard open the right type of view
|
||||
|
||||
The wizard can generate picking.in and picking.out
|
||||
Let's ensure it open the right view for each picking type
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(test_lp_1282584, self).setUp()
|
||||
|
||||
self.wizard_make_picking_obj = self.env['claim_make_picking.wizard']
|
||||
line_obj = self.env['claim.line']
|
||||
claim_obj = self.env['crm.claim']
|
||||
|
||||
self.product = self.env.ref('product.product_product_4')
|
||||
|
||||
self.partner = self.env.ref('base.res_partner_12')
|
||||
|
||||
# Create the claim with a claim line
|
||||
self.claim = claim_obj.create(
|
||||
{
|
||||
'name': 'TEST CLAIM',
|
||||
'code': 'TEST CLAIM',
|
||||
'claim_type': 'customer',
|
||||
'delivery_address_id': self.partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.warehouse = self.claim.warehouse_id
|
||||
self.claim_line = line_obj.create(
|
||||
{
|
||||
'name': 'TEST CLAIM LINE',
|
||||
'claim_origine': 'none',
|
||||
'product_id': self.product.id,
|
||||
'claim_id': self.claim.id,
|
||||
'location_dest_id': self.warehouse.lot_stock_id.id
|
||||
}
|
||||
)
|
||||
|
||||
def test_00(self):
|
||||
""" Test wizard opened view model for a new product return """
|
||||
context = {
|
||||
'active_id': self.claim.id,
|
||||
'partner_id': self.partner.id,
|
||||
'warehouse_id': self.warehouse.id,
|
||||
'picking_type': 'in',
|
||||
}
|
||||
|
||||
wizard = self.wizard_make_picking_obj.with_context(context).create({})
|
||||
|
||||
res = wizard.action_create_picking()
|
||||
self.assertEquals(res.get('res_model'), 'stock.picking',
|
||||
"Wrong model defined")
|
||||
|
||||
def test_01(self):
|
||||
""" Test wizard opened view model for a new delivery """
|
||||
|
||||
wizard_change_product_qty_obj = self.env['stock.change.product.qty']
|
||||
context = {'active_id': self.product.id}
|
||||
wizard_change_product_qty = wizard_change_product_qty_obj.create({
|
||||
'product_id': self.product.id,
|
||||
'new_quantity': 12
|
||||
})
|
||||
|
||||
wizard_change_product_qty.with_context(context).change_product_qty()
|
||||
|
||||
context = {
|
||||
'active_id': self.claim.id,
|
||||
'partner_id': self.partner.id,
|
||||
'warehouse_id': self.warehouse.id,
|
||||
'picking_type': 'out',
|
||||
}
|
||||
|
||||
wizard = self.wizard_make_picking_obj.with_context(context).create({})
|
||||
|
||||
res = wizard.action_create_picking()
|
||||
self.assertEquals(res.get('res_model'), 'stock.picking',
|
||||
"Wrong model defined")
|
||||
113
crm_claim_rma/tests/test_picking_creation.py
Normal file
113
crm_claim_rma/tests/test_picking_creation.py
Normal file
@@ -0,0 +1,113 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Yannick Vaucher
|
||||
# Copyright 2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.tests import common
|
||||
|
||||
|
||||
class test_picking_creation(common.TransactionCase):
|
||||
""" Test the correct pickings are created by the wizard. """
|
||||
|
||||
def setUp(self):
|
||||
super(test_picking_creation, self).setUp()
|
||||
|
||||
self.WizardMakePicking = self.env['claim_make_picking.wizard']
|
||||
self.StockPicking = self.env['stock.picking']
|
||||
ClaimLine = self.env['claim.line']
|
||||
Claim = self.env['crm.claim']
|
||||
|
||||
self.product_id = self.env.ref('product.product_product_4')
|
||||
|
||||
self.partner_id = self.env.ref('base.res_partner_12')
|
||||
|
||||
self.customer_location_id = self.env.ref(
|
||||
'stock.stock_location_customers')
|
||||
|
||||
# Create the claim with a claim line
|
||||
self.claim_id = Claim.create(
|
||||
{
|
||||
'name': 'TEST CLAIM',
|
||||
'number': 'TEST CLAIM',
|
||||
'claim_type': 'customer',
|
||||
'delivery_address_id': self.partner_id.id,
|
||||
})
|
||||
|
||||
self.warehouse_id = self.claim_id.warehouse_id
|
||||
self.claim_line_id = ClaimLine.create(
|
||||
{
|
||||
'name': 'TEST CLAIM LINE',
|
||||
'claim_origine': 'none',
|
||||
'product_id': self.product_id.id,
|
||||
'claim_id': self.claim_id.id,
|
||||
'location_dest_id': self.warehouse_id.lot_stock_id.id,
|
||||
})
|
||||
|
||||
def test_00_new_product_return(self):
|
||||
"""Test wizard creates a correct picking for product return
|
||||
|
||||
"""
|
||||
wizard = self.WizardMakePicking.with_context({
|
||||
'active_id': self.claim_id.id,
|
||||
'partner_id': self.partner_id.id,
|
||||
'warehouse_id': self.warehouse_id.id,
|
||||
'picking_type': 'in',
|
||||
}).create({})
|
||||
wizard.action_create_picking()
|
||||
|
||||
self.assertEquals(len(self.claim_id.picking_ids), 1,
|
||||
"Incorrect number of pickings created")
|
||||
picking = self.claim_id.picking_ids[0]
|
||||
|
||||
self.assertEquals(picking.location_id, self.customer_location_id,
|
||||
"Incorrect source location")
|
||||
self.assertEquals(picking.location_dest_id,
|
||||
self.warehouse_id.lot_stock_id,
|
||||
"Incorrect destination location")
|
||||
|
||||
def test_01_new_delivery(self):
|
||||
"""Test wizard creates a correct picking for a new delivery
|
||||
|
||||
"""
|
||||
|
||||
WizardChangeProductQty = self.env['stock.change.product.qty']
|
||||
wizard_chg_qty = WizardChangeProductQty.with_context({
|
||||
'active_id': self.product_id.id,
|
||||
}).create({
|
||||
'product_id': self.product_id.id,
|
||||
'new_quantity': 12,
|
||||
})
|
||||
|
||||
wizard_chg_qty.change_product_qty()
|
||||
|
||||
wizard = self.WizardMakePicking.with_context({
|
||||
'active_id': self.claim_id.id,
|
||||
'partner_id': self.partner_id.id,
|
||||
'warehouse_id': self.warehouse_id.id,
|
||||
'picking_type': 'out',
|
||||
}).create({})
|
||||
wizard.action_create_picking()
|
||||
|
||||
self.assertEquals(len(self.claim_id.picking_ids), 1,
|
||||
"Incorrect number of pickings created")
|
||||
picking = self.claim_id.picking_ids[0]
|
||||
|
||||
self.assertEquals(picking.location_id, self.warehouse_id.lot_stock_id,
|
||||
"Incorrect source location")
|
||||
self.assertEquals(picking.location_dest_id, self.customer_location_id,
|
||||
"Incorrect destination location")
|
||||
392
crm_claim_rma/views/crm_claim_rma.xml
Normal file
392
crm_claim_rma/views/crm_claim_rma.xml
Normal file
@@ -0,0 +1,392 @@
|
||||
<?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>
|
||||
|
||||
<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 -->
|
||||
<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="claim_type" context="{'create_lines': False}"/>
|
||||
<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', ['supplier','other'])]}"
|
||||
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', ['supplier','other'])]}"
|
||||
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', ['supplier','other'])]}"
|
||||
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', ['customer','other'])]}"
|
||||
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', ['customer','other'])]}"
|
||||
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', ['supplier','other'])]}"
|
||||
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', ['supplier','other'])]}"
|
||||
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"/>
|
||||
</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>
|
||||
<group>
|
||||
<!-- Place for mass return button from crm_rma_lot_mass_return -->
|
||||
</group>
|
||||
<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>
|
||||
|
||||
<!-- 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"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -15,7 +15,6 @@
|
||||
<field name="email"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="is_company" invisible="1"/>
|
||||
<!--<field name="country" invisible="1"/>-->
|
||||
<field name="country_id"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
</tree>
|
||||
@@ -1,279 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# 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.models import api, TransientModel, _
|
||||
from openerp.fields import Many2many, Many2one
|
||||
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp.exceptions import Warning
|
||||
from openerp import workflow
|
||||
from openerp import workflow
|
||||
|
||||
import time
|
||||
|
||||
|
||||
class ClaimMakePicking(TransientModel):
|
||||
_name = 'claim_make_picking.wizard'
|
||||
_description = 'Wizard to create pickings from claim lines'
|
||||
|
||||
# Get default source location
|
||||
def _get_source_loc(self):
|
||||
loc_id = False
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
warehouse_obj = self.env['stock.warehouse']
|
||||
warehouse_id = context.get('warehouse_id')
|
||||
picking_type = context.get('picking_type')
|
||||
partner_id = context.get('partner_id')
|
||||
if picking_type == 'out':
|
||||
loc_id = warehouse_obj.browse(
|
||||
warehouse_id).lot_stock_id.id
|
||||
elif partner_id:
|
||||
loc_id = self.env['res.partner'].browse(
|
||||
partner_id).property_stock_customer.id
|
||||
|
||||
return loc_id
|
||||
|
||||
def _get_common_dest_location_from_line(self, line_ids):
|
||||
"""Return the ID of the common location between all lines. If no common
|
||||
destination was found, return False"""
|
||||
loc_id = False
|
||||
line_obj = self.env['claim.line']
|
||||
line_location = []
|
||||
|
||||
for line in line_obj.browse(line_ids):
|
||||
if line.location_dest_id.id not in line_location:
|
||||
line_location.append(line.location_dest_id.id)
|
||||
|
||||
if len(line_location) == 1:
|
||||
loc_id = line_location[0]
|
||||
|
||||
return loc_id
|
||||
|
||||
# Get default destination location
|
||||
def _get_dest_loc(self):
|
||||
"""Return the location_id to use as destination.
|
||||
If it's an outoing shippment: take the customer stock property
|
||||
If it's an incoming shippment take the location_dest_id common to all
|
||||
lines, or if different, return None."""
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
loc_id = False
|
||||
picking_type = context.get('picking_type')
|
||||
partner_id = context.get('partner_id')
|
||||
if picking_type == 'out' and partner_id:
|
||||
loc_id = self.env['res.partner'].browse(
|
||||
partner_id).property_stock_customer.id
|
||||
elif picking_type == 'in' and partner_id:
|
||||
# Add the case of return to supplier !
|
||||
line_ids = self._get_claim_lines()
|
||||
loc_id = self._get_common_dest_location_from_line(line_ids)
|
||||
|
||||
return loc_id
|
||||
|
||||
def _get_claim_lines(self):
|
||||
# TODO use custom states to show buttons of this wizard or not instead
|
||||
# of raise an error
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
line_obj = self.env['claim.line']
|
||||
if context.get('picking_type') == 'out':
|
||||
move_field = 'move_out_id'
|
||||
else:
|
||||
move_field = 'move_in_id'
|
||||
|
||||
good_lines = []
|
||||
lines = line_obj.search(
|
||||
[('claim_id', '=', context['active_id'])])
|
||||
for line in lines:
|
||||
if not line[move_field] or line[move_field].state == 'cancel':
|
||||
good_lines.append(line.id)
|
||||
|
||||
if not good_lines:
|
||||
raise Warning(
|
||||
_('Error'),
|
||||
_('A picking has already been created for this claim.'))
|
||||
|
||||
return good_lines
|
||||
|
||||
claim_line_source_location = Many2one(
|
||||
'stock.location', string='Source Location', required=True,
|
||||
default=_get_source_loc,
|
||||
help="Location where the returned products are from.")
|
||||
claim_line_dest_location = Many2one(
|
||||
'stock.location', string='Dest. Location', required=True,
|
||||
default=_get_dest_loc,
|
||||
help="Location where the system will stock the returned products.")
|
||||
claim_line_ids = Many2many(
|
||||
'claim.line',
|
||||
'claim_line_picking',
|
||||
'claim_picking_id',
|
||||
'claim_line_id',
|
||||
string='Claim lines', default=_get_claim_lines)
|
||||
|
||||
def _get_common_partner_from_line(self, line_ids):
|
||||
"""Return the ID of the common partner between all lines. If no common
|
||||
partner was found, return False"""
|
||||
partner_id = False
|
||||
line_obj = self.env['claim.line']
|
||||
line_partner = []
|
||||
for line in line_obj.browse(line_ids):
|
||||
if (line.warranty_return_partner
|
||||
and line.warranty_return_partner.id
|
||||
not in line_partner):
|
||||
line_partner.append(line.warranty_return_partner.id)
|
||||
|
||||
if len(line_partner) == 1:
|
||||
partner_id = line_partner[0]
|
||||
|
||||
return partner_id
|
||||
|
||||
@api.multi
|
||||
def action_cancel(self):
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
@api.multi
|
||||
def action_create_picking(self):
|
||||
picking_obj = self.env['stock.picking']
|
||||
picking_type_obj = self.env['stock.picking.type']
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
view_obj = self.env['ir.ui.view']
|
||||
name = 'RMA picking out'
|
||||
if context.get('picking_type') == 'out':
|
||||
picking_type_code = 'outgoing'
|
||||
write_field = 'move_out_id'
|
||||
note = 'RMA picking out'
|
||||
else:
|
||||
picking_type_code = 'incoming'
|
||||
write_field = 'move_in_id'
|
||||
|
||||
if context.get('picking_type'):
|
||||
note = 'RMA picking ' + str(context.get('picking_type'))
|
||||
name = note
|
||||
|
||||
picking_type_id = picking_type_obj.search([
|
||||
('code', '=', picking_type_code),
|
||||
('default_location_dest_id', '=',
|
||||
self.claim_line_dest_location.id)], limit=1).id
|
||||
|
||||
model = 'stock.picking'
|
||||
view_id = view_obj.search([
|
||||
('model', '=', model),
|
||||
('type', '=', 'form')], limit=1).id
|
||||
|
||||
claim = self.env['crm.claim'].browse(context['active_id'])
|
||||
partner_id = claim.delivery_address_id.id
|
||||
claim_lines = self.claim_line_ids
|
||||
|
||||
# In case of product return, we don't allow one picking for various
|
||||
# product if location are different
|
||||
# or if partner address is different
|
||||
if context.get('product_return'):
|
||||
common_dest_loc_id = self._get_common_dest_location_from_line(
|
||||
claim_lines.ids)
|
||||
if not common_dest_loc_id:
|
||||
raise Warning(
|
||||
_('Error'),
|
||||
_('A product return cannot be created for various '
|
||||
'destination locations, please choose line with a '
|
||||
'same destination location.'))
|
||||
|
||||
claim_lines.auto_set_warranty()
|
||||
common_dest_partner_id = self._get_common_partner_from_line(
|
||||
claim_lines.ids)
|
||||
|
||||
if not common_dest_partner_id:
|
||||
raise Warning(
|
||||
_('Error'),
|
||||
_('A product return cannot be created for various '
|
||||
'destination addresses, please choose line with a '
|
||||
'same address.'))
|
||||
|
||||
partner_id = common_dest_partner_id
|
||||
|
||||
# create picking
|
||||
picking = picking_obj.create(
|
||||
{'origin': claim.code,
|
||||
'picking_type_id': picking_type_id,
|
||||
'move_type': 'one', # direct
|
||||
'state': 'draft',
|
||||
'date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
'partner_id': partner_id,
|
||||
'invoice_state': "none",
|
||||
'company_id': claim.company_id.id,
|
||||
'location_id': self.claim_line_source_location.id,
|
||||
'location_dest_id': self.claim_line_dest_location.id,
|
||||
'note': note,
|
||||
'claim_id': claim.id,
|
||||
})
|
||||
|
||||
# Create picking lines
|
||||
fmt = DEFAULT_SERVER_DATETIME_FORMAT
|
||||
for line in self.claim_line_ids:
|
||||
move_id = self.env['stock.move'].create({
|
||||
'name': line.product_id.name_template,
|
||||
'priority': '0',
|
||||
'date': time.strftime(fmt),
|
||||
'date_expected': time.strftime(fmt),
|
||||
'product_id': line.product_id.id,
|
||||
'product_uom_qty': line.product_returned_quantity,
|
||||
'product_uom': line.product_id.product_tmpl_id.uom_id.id,
|
||||
'partner_id': partner_id,
|
||||
'picking_id': picking.id,
|
||||
'state': 'draft',
|
||||
'price_unit': line.unit_sale_price,
|
||||
'company_id': claim.company_id.id,
|
||||
'location_id': self.claim_line_source_location.id,
|
||||
'location_dest_id': self.claim_line_dest_location.id,
|
||||
'note': note}).id
|
||||
|
||||
line.write({write_field: move_id})
|
||||
|
||||
wf_service = workflow
|
||||
if picking:
|
||||
cr, uid = self.env.cr, self.env.uid
|
||||
wf_service.trg_validate(uid, 'stock.picking',
|
||||
picking.id, 'button_confirm', cr)
|
||||
picking.action_assign()
|
||||
domain = ("[('picking_type_id.code', '=', '%s'), "
|
||||
"('partner_id', '=', %s)]" % (picking_type_code, partner_id))
|
||||
|
||||
return {
|
||||
'name': '%s' % name,
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'view_id': view_id,
|
||||
'domain': domain,
|
||||
'res_model': model,
|
||||
'res_id': picking.id,
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# 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
|
||||
# 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
|
||||
@@ -22,31 +22,20 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.models import api, TransientModel
|
||||
from openerp.fields import Char
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
class AccountInvoiceRefund(TransientModel):
|
||||
class AccountInvoiceRefund(models.TransientModel):
|
||||
_inherit = "account.invoice.refund"
|
||||
|
||||
def _get_description(self):
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
def _default_description(self):
|
||||
return self.env.context.get('description', '')
|
||||
|
||||
description = context.get('description') or ''
|
||||
return description
|
||||
|
||||
description = Char(default=_get_description)
|
||||
description = fields.Char(default=_default_description)
|
||||
|
||||
@api.one
|
||||
def compute_refund(self, mode='refund'):
|
||||
context = self.env.context.copy()
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
if context.get('invoice_ids'):
|
||||
context['active_ids'] = context.get('invoice_ids')
|
||||
|
||||
self = self.with_context(context)
|
||||
invoice_ids = self.env.context.get('invoice_ids', [])
|
||||
if invoice_ids:
|
||||
self = self.with_context(active_ids=invoice_ids)
|
||||
return super(AccountInvoiceRefund, self).compute_refund(mode=mode)
|
||||
236
crm_claim_rma/wizards/claim_make_picking.py
Normal file
236
crm_claim_rma/wizards/claim_make_picking.py
Normal file
@@ -0,0 +1,236 @@
|
||||
# -*- 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 time
|
||||
|
||||
from openerp import models, fields, exceptions, api, workflow, _
|
||||
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FORMAT
|
||||
|
||||
|
||||
class ClaimMakePicking(models.TransientModel):
|
||||
_name = 'claim_make_picking.wizard'
|
||||
_description = 'Wizard to create pickings from claim lines'
|
||||
|
||||
@api.returns('stock.location')
|
||||
def _get_common_dest_location_from_line(self, lines):
|
||||
"""
|
||||
If all the lines have the same destination location return that,
|
||||
else return an empty recordset
|
||||
"""
|
||||
dests = lines.mapped('location_dest_id')
|
||||
return dests[0] if len(dests) == 1 else self.env['stock.location']
|
||||
|
||||
@api.returns('res.partner')
|
||||
def _get_common_partner_from_line(self, lines):
|
||||
"""
|
||||
If all the lines have the same warranty return partner return that,
|
||||
else return an empty recordset
|
||||
"""
|
||||
partners = lines.mapped('warranty_return_partner')
|
||||
return partners[0] if len(partners) == 1 else self.env['res.partner']
|
||||
|
||||
def _default_claim_line_source_location_id(self):
|
||||
picking_type = self.env.context.get('picking_type')
|
||||
partner_id = self.env.context.get('partner_id')
|
||||
warehouse_id = self.env.context.get('warehouse_id')
|
||||
|
||||
if picking_type == 'out' and warehouse_id:
|
||||
return self.env['stock.warehouse'].browse(warehouse_id).lot_stock_id
|
||||
|
||||
if partner_id:
|
||||
partner = self.env['res.partner'].browse(partner_id)
|
||||
return partner.property_stock_customer
|
||||
|
||||
# return empty recordset, see https://github.com/odoo/odoo/issues/4384
|
||||
return self.env['stock.location']
|
||||
|
||||
def _default_claim_line_dest_location_id(self):
|
||||
"""Return the location_id to use as destination.
|
||||
|
||||
If it's an outoing shipment: take the customer stock property
|
||||
If it's an incoming shipment take the location_dest_id common to all
|
||||
lines, or if different, return None.
|
||||
"""
|
||||
picking_type = self.env.context.get('picking_type')
|
||||
partner_id = self.env.context.get('partner_id')
|
||||
|
||||
if picking_type == 'out' and partner_id:
|
||||
return self.env['res.partner'].browse(
|
||||
partner_id).property_stock_customer
|
||||
|
||||
if picking_type == 'in' and partner_id:
|
||||
# Add the case of return to supplier !
|
||||
lines = self._default_claim_line_ids()
|
||||
return self._get_common_dest_location_from_line(lines)
|
||||
|
||||
# return empty recordset, see https://github.com/odoo/odoo/issues/4384
|
||||
return self.env['stock.location']
|
||||
|
||||
@api.returns('claim.line')
|
||||
def _default_claim_line_ids(self):
|
||||
# TODO use custom states to show buttons of this wizard or not instead
|
||||
# of raise an error
|
||||
move_field = ('move_out_id'
|
||||
if self.env.context.get('picking_type') == 'out'
|
||||
else 'move_in_id')
|
||||
domain = [
|
||||
('claim_id', '=', self.env.context['active_id']),
|
||||
'|', (move_field, '=', False), (move_field+'.state', '=', 'cancel')
|
||||
]
|
||||
lines = self.env['claim.line'].search(domain)
|
||||
if not lines:
|
||||
raise exceptions.Warning(
|
||||
_('Error'),
|
||||
_('A picking has already been created for this claim.'))
|
||||
return lines
|
||||
|
||||
claim_line_source_location_id = fields.Many2one(
|
||||
'stock.location', string='Source Location', required=True,
|
||||
default=_default_claim_line_source_location_id,
|
||||
help="Location where the returned products are from.")
|
||||
claim_line_dest_location_id = fields.Many2one(
|
||||
'stock.location', string='Dest. Location', required=True,
|
||||
default=_default_claim_line_dest_location_id,
|
||||
help="Location where the system will stock the returned products.")
|
||||
claim_line_ids = fields.Many2many(
|
||||
'claim.line',
|
||||
'claim_line_picking',
|
||||
'claim_picking_id',
|
||||
'claim_line_id',
|
||||
string='Claim lines', default=_default_claim_line_ids)
|
||||
|
||||
def _get_picking_name(self):
|
||||
return 'RMA picking {}'.format(
|
||||
self.env.context.get('picking_type', 'in'))
|
||||
|
||||
def _get_picking_note(self):
|
||||
return self._get_picking_name()
|
||||
|
||||
def _get_picking_data(self, claim, picking_type, partner_id):
|
||||
return {
|
||||
'origin': claim.code,
|
||||
'picking_type_id': picking_type.id,
|
||||
'move_type': 'one', # direct
|
||||
'state': 'draft',
|
||||
'date': time.strftime(DT_FORMAT),
|
||||
'partner_id': partner_id,
|
||||
'invoice_state': "none",
|
||||
'company_id': claim.company_id.id,
|
||||
'location_id': self.claim_line_source_location_id.id,
|
||||
'location_dest_id': self.claim_line_dest_location_id.id,
|
||||
'note': self._get_picking_note(),
|
||||
'claim_id': claim.id,
|
||||
}
|
||||
|
||||
def _get_picking_line_data(self, claim, picking, line):
|
||||
return {
|
||||
'name': line.product_id.name_template,
|
||||
'priority': '0',
|
||||
'date': time.strftime(DT_FORMAT),
|
||||
'date_expected': time.strftime(DT_FORMAT),
|
||||
'product_id': line.product_id.id,
|
||||
'product_uom_qty': line.product_returned_quantity,
|
||||
'product_uom': line.product_id.product_tmpl_id.uom_id.id,
|
||||
'partner_id': claim.delivery_address_id.id,
|
||||
'picking_id': picking.id,
|
||||
'state': 'draft',
|
||||
'price_unit': line.unit_sale_price,
|
||||
'company_id': claim.company_id.id,
|
||||
'location_id': self.claim_line_source_location_id.id,
|
||||
'location_dest_id': self.claim_line_dest_location_id.id,
|
||||
'note': self._get_picking_note(),
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def action_create_picking(self):
|
||||
|
||||
picking_type_code = 'incoming'
|
||||
write_field = 'move_out_id'
|
||||
if self.env.context.get('picking_type') == 'out':
|
||||
picking_type_code = 'outgoing'
|
||||
write_field = 'move_in_id'
|
||||
destination_id = self.claim_line_dest_location_id.id
|
||||
picking_type = self.env['stock.picking.type'].search([
|
||||
('code', '=', picking_type_code),
|
||||
('default_location_dest_id', '=', destination_id)
|
||||
], limit=1)
|
||||
|
||||
claim = self.env['crm.claim'].browse(self.env.context['active_id'])
|
||||
partner_id = claim.delivery_address_id.id
|
||||
claim_lines = self.claim_line_ids
|
||||
|
||||
# In case of product return, we don't allow one picking for various
|
||||
# product if location are different
|
||||
# or if partner address is different
|
||||
if self.env.context.get('product_return'):
|
||||
common_dest_location = self._get_common_dest_location_from_line(
|
||||
claim_lines)
|
||||
if not common_dest_location:
|
||||
raise Warning(
|
||||
_('Error'),
|
||||
_('A product return cannot be created for various '
|
||||
'destination locations, please choose line with a '
|
||||
'same destination location.'))
|
||||
|
||||
claim_lines.auto_set_warranty()
|
||||
|
||||
common_dest_partner = self._get_common_partner_from_line(
|
||||
claim_lines)
|
||||
if not common_dest_partner:
|
||||
raise exceptions.Warning(
|
||||
_('Error'),
|
||||
_('A product return cannot be created for various '
|
||||
'destination addresses, please choose line with a '
|
||||
'same address.'))
|
||||
partner_id = common_dest_partner.id
|
||||
|
||||
# create picking
|
||||
picking = self.env['stock.picking'].create(
|
||||
self._get_picking_data(claim, picking_type, partner_id))
|
||||
|
||||
# Create picking lines
|
||||
for line in self.claim_line_ids:
|
||||
move = self.env['stock.move'].create(
|
||||
self._get_picking_line_data(claim, picking, line))
|
||||
line.write({write_field: move.id})
|
||||
|
||||
wf_service = workflow
|
||||
if picking:
|
||||
cr, uid = self.env.cr, self.env.uid
|
||||
wf_service.trg_validate(uid, 'stock.picking',
|
||||
picking.id, 'button_confirm', cr)
|
||||
picking.action_assign()
|
||||
|
||||
domain = [
|
||||
('picking_type_id.code', '=', picking_type_code),
|
||||
('partner_id', '=', partner_id)
|
||||
]
|
||||
return {
|
||||
'name': self._get_picking_name(),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'domain': domain,
|
||||
'res_model': 'stock.picking',
|
||||
'res_id': picking.id,
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
@@ -13,15 +13,19 @@
|
||||
<field name="model">claim_make_picking.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Select exchange lines to add in picking" version="7.0">
|
||||
<separator string="Locations" colspan="4"/>
|
||||
<field name="claim_line_source_location" nolabel="1" />
|
||||
<field name="claim_line_dest_location" nolabel="1" />
|
||||
<separator string="Select lines for picking" colspan="4"/>
|
||||
<field name="claim_line_ids" nolabel="1" colspan="4"/>
|
||||
<group name="locations" string="Locations">
|
||||
<field name="claim_line_source_location_id"/>
|
||||
<field name="claim_line_dest_location_id"/>
|
||||
</group>
|
||||
<separator string="Select lines for picking"/>
|
||||
<field name="claim_line_ids" nolabel="1"/>
|
||||
<footer>
|
||||
<button name="action_create_picking" string="Create picking" type="object" class="oe_highlight"/>
|
||||
<button
|
||||
string="Create picking"
|
||||
name="action_create_picking" type="object"
|
||||
class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
Reference in New Issue
Block a user