mirror of
https://github.com/OCA/rma.git
synced 2025-02-16 17:11:47 +02:00
crm_rma_stock_location: Migration V9
This commit is contained in:
@@ -50,7 +50,7 @@ Usage
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/8.0/145
|
||||
:target: https://runbot.odoo-community.org/runbot/145/9.0
|
||||
|
||||
For further information, please visit:
|
||||
|
||||
@@ -64,21 +64,26 @@ Known issues / Roadmap
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/rma/issues>`_.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
|
||||
`here <https://github.com/OCA/rma/issues/new?body=module:%20crm_rma_stock_location%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
|
||||
Bugs are tracked on `GitHub Issues
|
||||
<https://github.com/OCA/rma/issues>`_. In case of trouble, please
|
||||
check there if your issue has already been reported. If you spotted it first,
|
||||
help us smashing it by providing a detailed and welcomed feedback.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Images
|
||||
------
|
||||
|
||||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
|
||||
* Yanina Aular <yanina.aular@vauxoo.com>
|
||||
* Osval Reyes <osval@vauxoo.com>
|
||||
* Cyril Gaudin <cyril.gaudin@camptocamp.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
@@ -93,4 +98,4 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
To contribute to this module, please visit http://odoo-community.org.
|
||||
To contribute to this module, please visit https://odoo-community.org.
|
||||
|
||||
@@ -1,25 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright 2014 Camptocamp SA
|
||||
# Author: Guewen Baconnier,
|
||||
# Osval Reyes
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import models
|
||||
from . import wizards
|
||||
|
||||
@@ -1,32 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
# Author: Guewen Baconnier,
|
||||
# Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
# Joel Grand-Guillaume,
|
||||
# Yanina Aular, Osval Reyes
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright 2013-2014 Camptocamp SA
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Guewen Baconnier,
|
||||
# Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
# Joel Grand-Guillaume,
|
||||
# Yanina Aular, Osval Reyes
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# © 2009-2013 Akretion
|
||||
# © 2014-2016 Camptocamp SA
|
||||
# © 2015 Vauxoo
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
|
||||
{
|
||||
'name': 'RMA Stock Location',
|
||||
'version': '8.0.1.0.0',
|
||||
'version': '9.0.1.0.0',
|
||||
'author': "Akretion,Vauxoo,Camptocamp,Odoo Community Association (OCA)",
|
||||
'maintainer': 'Camptocamp',
|
||||
'website': 'http://www.camptocamp.com,http://www.vauxoo.com',
|
||||
|
||||
@@ -1,28 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<record id="rma_stock_location_move_01" model="stock.move">
|
||||
<field name="name">Demo Stock Move: Customer > RMA</field>
|
||||
<field name="product_id" ref="product.product_product_24"/>
|
||||
<field name="product_uom">1</field>
|
||||
<field name="product_uom_qty">1000</field>
|
||||
<field name="company_id" ref="base.main_company"/>
|
||||
<field name="priority">1</field> <!-- Normal -->
|
||||
<field name="picking_type_id" ref="stock.picking_type_in"/>
|
||||
<field name="location_id" ref="stock.stock_location_customers"/>
|
||||
<field name="location_dest_id" search="[('name', '=', 'RMA'), ('location_id.name', '=', 'WH')]"/>
|
||||
</record>
|
||||
<record id="rma_stock_location_move_03" model="stock.move">
|
||||
<field name="name">Demo Stock Move: RMA > Loss</field>
|
||||
<field name="product_id" ref="product.product_product_24"/>
|
||||
<field name="product_uom">1</field>
|
||||
<field name="product_uom_qty">1000</field>
|
||||
<field name="company_id" ref="base.main_company"/>
|
||||
<field name="priority">1</field> <!-- Normal -->
|
||||
<field name="picking_type_id" ref="stock.picking_type_internal"/>
|
||||
<field name="location_id" search="[('name', '=', 'RMA'), ('location_id.name', '=', 'WH')]"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_stock"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
<odoo noupdate="1">
|
||||
<record id="rma_stock_location_move_01" model="stock.move">
|
||||
<field name="name">Demo Stock Move: Customer > RMA</field>
|
||||
<field name="product_id" ref="product.product_product_24"/>
|
||||
<field name="product_uom">1</field>
|
||||
<field name="product_uom_qty">1000</field>
|
||||
<field name="company_id" ref="base.main_company"/>
|
||||
<field name="priority">1</field> <!-- Normal -->
|
||||
<field name="picking_type_id" ref="stock.picking_type_in"/>
|
||||
<field name="location_id" ref="stock.stock_location_customers"/>
|
||||
<field name="location_dest_id" search="[('name', '=', 'RMA'), ('location_id.name', '=', 'WH')]"/>
|
||||
</record>
|
||||
<record id="rma_stock_location_move_03" model="stock.move">
|
||||
<field name="name">Demo Stock Move: RMA > Loss</field>
|
||||
<field name="product_id" ref="product.product_product_24"/>
|
||||
<field name="product_uom">1</field>
|
||||
<field name="product_uom_qty">1000</field>
|
||||
<field name="company_id" ref="base.main_company"/>
|
||||
<field name="priority">1</field> <!-- Normal -->
|
||||
<field name="picking_type_id" ref="stock.picking_type_internal"/>
|
||||
<field name="location_id" search="[('name', '=', 'RMA'), ('location_id.name', '=', 'WH')]"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_stock"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
|
||||
@@ -1,37 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<odoo noupdate="1">
|
||||
<record id="location_rma" model="stock.location">
|
||||
<field name="name">RMA Demo</field>
|
||||
<field name="usage">internal</field>
|
||||
</record>
|
||||
|
||||
<record id="location_rma" model="stock.location">
|
||||
<field name="name">RMA Demo</field>
|
||||
<field name="usage">internal</field>
|
||||
</record>
|
||||
<record id="stock.stock_warehouse_shop0" model="stock.warehouse">
|
||||
<field name="lot_rma_id" ref="location_rma"/>
|
||||
</record>
|
||||
|
||||
<record id="stock.stock_warehouse_shop0" model="stock.warehouse">
|
||||
<field name="lot_rma_id" ref="location_rma"/>
|
||||
</record>
|
||||
<record id="location_rma_a" model="stock.location">
|
||||
<field name="name">RMA - Box A</field>
|
||||
<field name="location_id" ref="location_rma"/>
|
||||
<field name="usage">internal</field>
|
||||
</record>
|
||||
<record id="location_rma_b" model="stock.location">
|
||||
<field name="name">RMA - Box B</field>
|
||||
<field name="location_id" ref="location_rma"/>
|
||||
<field name="usage">internal</field>
|
||||
</record>
|
||||
|
||||
<record id="location_rma_a" model="stock.location">
|
||||
<field name="name">RMA - Box A</field>
|
||||
<field name="location_id" ref="location_rma"/>
|
||||
<field name="usage">internal</field>
|
||||
</record>
|
||||
<record id="location_rma_b" model="stock.location">
|
||||
<field name="name">RMA - Box B</field>
|
||||
<field name="location_id" ref="location_rma"/>
|
||||
<field name="usage">internal</field>
|
||||
</record>
|
||||
|
||||
<record id="product_socket" model="product.product">
|
||||
<field name="name">Socket</field>
|
||||
<field name="categ_id" ref="product.product_category_1"/>
|
||||
<field name="standard_price">70.0</field>
|
||||
<field name="list_price">100.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"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
<record id="product_socket" model="product.product">
|
||||
<field name="name">Socket</field>
|
||||
<field name="categ_id" ref="product.product_category_1"/>
|
||||
<field name="standard_price">70.0</field>
|
||||
<field name="list_price">100.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"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
|
||||
@@ -1,31 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright 2014 Camptocamp SA
|
||||
# Author: Guewen Baconnier,
|
||||
# Osval Reyes
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# © 2015 Vauxoo
|
||||
# © 2014-2016 Camptocamp SA
|
||||
# Author: Guewen Baconnier,
|
||||
# Osval Reyes
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.api import Environment
|
||||
|
||||
|
||||
def post_init_hook(cr, registry):
|
||||
stock_wh = registry['stock.warehouse']
|
||||
for wh_id in stock_wh.browse(cr, SUPERUSER_ID,
|
||||
stock_wh.search(cr, SUPERUSER_ID, [])):
|
||||
vals = stock_wh.create_locations_rma(cr, SUPERUSER_ID, wh_id)
|
||||
stock_wh.write(cr, SUPERUSER_ID, wh_id.id, vals)
|
||||
with Environment.manage():
|
||||
env = Environment(cr, SUPERUSER_ID, {})
|
||||
|
||||
warehouses = env['stock.warehouse'].search([])
|
||||
warehouses.create_locations_rma()
|
||||
|
||||
@@ -1,28 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright 2013-2014 Camptocamp SA
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Guewen Baconnier,
|
||||
# Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
# Joel Grand-Guillaume,
|
||||
# Osval Reyes
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import product_product
|
||||
from . import product_template
|
||||
|
||||
@@ -1,27 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Guewen Baconnier
|
||||
# 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/>.
|
||||
#
|
||||
##############################################################################
|
||||
# © 2014-2016 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import _, api, fields, models
|
||||
from openerp import api, fields, models
|
||||
import openerp.addons.decimal_precision as dp
|
||||
from openerp.tools.float_utils import float_round
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
|
||||
|
||||
@@ -30,16 +12,18 @@ class ProductProduct(models.Model):
|
||||
_inherit = 'product.product'
|
||||
|
||||
rma_qty_available = fields.Float(
|
||||
compute='_rma_product_available',
|
||||
compute='_compute_rma_product_quantities',
|
||||
digits_compute=dp.get_precision('Product Unit of Measure'),
|
||||
search='_search_rma_product_quantity',
|
||||
string=_('RMA Quantity On Hand'))
|
||||
string='RMA Quantity On Hand'
|
||||
)
|
||||
|
||||
rma_virtual_available = fields.Float(
|
||||
compute='_rma_product_available',
|
||||
compute='_compute_rma_product_quantities',
|
||||
digits_compute=dp.get_precision('Product Unit of Measure'),
|
||||
search='_search_rma_product_quantity',
|
||||
string=_('RMA Forecasted Quantity'))
|
||||
string='RMA Forecasted Quantity'
|
||||
)
|
||||
|
||||
def _search_rma_product_quantity(self, operator, value):
|
||||
res = []
|
||||
@@ -64,69 +48,48 @@ class ProductProduct(models.Model):
|
||||
res.append(('id', 'in', ids))
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def _rma_product_available(self):
|
||||
@api.depends()
|
||||
def _compute_rma_product_quantities(self):
|
||||
""" Compute both rma_qty_available and rma_virtual_available values
|
||||
by calling product_product._product_available with RMA locations
|
||||
in context.
|
||||
"""
|
||||
Finds the incoming and outgoing quantity of product for the RMA
|
||||
locations.
|
||||
"""
|
||||
context = self.env.context
|
||||
warehouse_id = context.get('warehouse_id')
|
||||
ctx = context.copy()
|
||||
location_ids = set()
|
||||
warehouse_model = self.env['stock.warehouse']
|
||||
|
||||
locations = self.env['stock.location']
|
||||
|
||||
warehouse_id = self.env.context.get('warehouse_id')
|
||||
if warehouse_id:
|
||||
warehouse = warehouse_model.browse(warehouse_id)
|
||||
if warehouse.lot_rma_id:
|
||||
locations |= warehouse.lot_rma_id
|
||||
|
||||
else:
|
||||
warehouses = warehouse_model.search([('lot_rma_id', '!=', False)])
|
||||
locations |= warehouses.mapped('lot_rma_id')
|
||||
|
||||
if locations:
|
||||
result = self.with_context(
|
||||
# Sorted by parent_left to avoid a little Odoo bug
|
||||
# in tests environnement
|
||||
# see https://github.com/odoo/odoo/pull/11996
|
||||
location=locations.sorted(
|
||||
lambda l: l.parent_left
|
||||
).mapped('id'),
|
||||
)._product_available()
|
||||
|
||||
else:
|
||||
result = {}
|
||||
|
||||
for product in self:
|
||||
if warehouse_id and warehouse_id.lot_rma_id:
|
||||
location_ids.add(warehouse_id.lot_rma_id.id)
|
||||
else:
|
||||
warehouse_ids = self.env['stock.warehouse'].search([])
|
||||
if not warehouse_ids:
|
||||
return
|
||||
for warehouse_id in warehouse_ids:
|
||||
if warehouse_id.lot_rma_id:
|
||||
location_ids.add(warehouse_id.lot_rma_id.id)
|
||||
try:
|
||||
product_qties = result[product.id]
|
||||
except KeyError:
|
||||
product.rma_qty_available = 0
|
||||
product.rma_virtual_available = 0
|
||||
|
||||
if not location_ids:
|
||||
return
|
||||
ctx['location'] = list(location_ids)
|
||||
|
||||
domain_products = [('product_id', 'in', [product.id])]
|
||||
domain_quant, domain_move_in, domain_move_out = \
|
||||
product.with_context(ctx)._get_domain_locations()
|
||||
domain_move_in += product.with_context(ctx)._get_domain_dates() + \
|
||||
[('state', 'not in', ('done', 'cancel', 'draft'))] + \
|
||||
domain_products
|
||||
domain_move_out += product.with_context(ctx).\
|
||||
_get_domain_dates() + \
|
||||
[('state', 'not in', ('done', 'cancel', 'draft'))] + \
|
||||
domain_products
|
||||
domain_quant += domain_products
|
||||
moves_in = []
|
||||
moves_out = []
|
||||
lot_id = context.get('lot_id')
|
||||
if lot_id:
|
||||
domain_quant.append(('lot_id', '=', lot_id))
|
||||
else:
|
||||
moves_in = self.env['stock.move'].\
|
||||
with_context(ctx).read_group(domain_move_in,
|
||||
['product_id', 'product_qty'],
|
||||
['product_id'])
|
||||
moves_out = self.env['stock.move'].\
|
||||
with_context(ctx).read_group(domain_move_out,
|
||||
['product_id', 'product_qty'],
|
||||
['product_id'])
|
||||
quants = self.env['stock.quant'].with_context(ctx).read_group(
|
||||
domain_quant, ['product_id', 'qty'], ['product_id'])
|
||||
quants = dict([(item.get('product_id')[0],
|
||||
item.get('qty')) for item in quants])
|
||||
moves_in = dict([(item.get('product_id')[0],
|
||||
item.get('product_qty')) for item in moves_in])
|
||||
moves_out = dict([(item.get('product_id')[0],
|
||||
item.get('product_qty')) for item in moves_out])
|
||||
product.rma_qty_available = \
|
||||
float_round(quants.get(product.id, 0.0),
|
||||
precision_rounding=product.uom_id.rounding)
|
||||
product.rma_virtual_available = \
|
||||
float_round(quants.get(product.id, 0.0) +
|
||||
moves_in.get(product.id, 0.0) -
|
||||
moves_out.get(product.id, 0.0),
|
||||
precision_rounding=product.uom_id.rounding)
|
||||
product.rma_qty_available = product_qties['qty_available']
|
||||
product.rma_virtual_available = product_qties[
|
||||
'virtual_available'
|
||||
]
|
||||
|
||||
@@ -1,50 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright 2014 Camptocamp SA
|
||||
# Author: Guewen Baconnier,
|
||||
# Osval Reyes
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# © 2015 Vauxoo
|
||||
# © 2014 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import _, api, fields, models
|
||||
|
||||
from openerp import api, fields, models
|
||||
import openerp.addons.decimal_precision as dp
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
|
||||
_inherit = 'product.template'
|
||||
|
||||
rma_qty_available = fields.Float(compute='_rma_template_available',
|
||||
digits_compute=dp.
|
||||
get_precision('Product Unit '
|
||||
'of Measure'),
|
||||
string=_('RMA Quantity On Hand'))
|
||||
rma_qty_available = fields.Float(
|
||||
compute='_compute_rma_template_quantities',
|
||||
digits_compute=dp.get_precision('Product Unit of Measure'),
|
||||
string='RMA Quantity On Hand'
|
||||
)
|
||||
rma_virtual_available = fields.Float(
|
||||
compute='_compute_rma_template_quantities',
|
||||
digits_compute=dp.get_precision('Product Unit of Measure'),
|
||||
string='RMA Forecasted Quantity'
|
||||
)
|
||||
|
||||
rma_virtual_available = fields.Float(compute='_rma_template_available',
|
||||
digits_compute=dp.
|
||||
get_precision('Product Unit'
|
||||
' of Measure'),
|
||||
string=_('RMA Forecasted Quantity'))
|
||||
@api.depends('product_variant_ids.rma_qty_available',
|
||||
'product_variant_ids.rma_virtual_available')
|
||||
def _compute_rma_template_quantities(self):
|
||||
""" Compute rma_qty_available and rma_virtual_available
|
||||
with sum of variants quantities.
|
||||
"""
|
||||
|
||||
@api.multi
|
||||
def _rma_template_available(self):
|
||||
for product in self:
|
||||
product.rma_qty_available = sum(
|
||||
product.mapped('product_variant_ids.rma_virtual_available'))
|
||||
product.rma_virtual_available = sum(
|
||||
product.mapped('product_variant_ids.rma_virtual_available'))
|
||||
for template in self:
|
||||
qantities = template.product_variant_ids.read(
|
||||
['rma_qty_available', 'rma_virtual_available']
|
||||
)
|
||||
template.rma_qty_available = sum(
|
||||
qty['rma_qty_available'] for qty in qantities
|
||||
)
|
||||
template.rma_virtual_available = sum(
|
||||
qty['rma_virtual_available'] for qty in qantities
|
||||
)
|
||||
|
||||
@@ -1,73 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
# © 2013 Camptocamp
|
||||
# © 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
# 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/>.
|
||||
#
|
||||
##############################################################################
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import _, api, fields, models
|
||||
|
||||
|
||||
class StockWarehouse(models.Model):
|
||||
|
||||
_inherit = "stock.warehouse"
|
||||
|
||||
loss_loc_id = fields.Many2one('stock.location', 'Loss Location')
|
||||
|
||||
lot_refurbish_id = fields.Many2one('stock.location', 'Refurbish Location')
|
||||
|
||||
@api.model
|
||||
def create_locations_rma(self, wh_id):
|
||||
vals = {}
|
||||
@api.multi
|
||||
def create_locations_rma(self):
|
||||
super(StockWarehouse, self).create_locations_rma()
|
||||
|
||||
location_obj = self.env['stock.location']
|
||||
context_with_inactive = self.env.context.copy()
|
||||
context_with_inactive['active_test'] = False
|
||||
wh_loc_id = wh_id.view_location_id.id
|
||||
|
||||
vals_new = super(StockWarehouse, self).create_locations_rma(wh_id)
|
||||
for warehouse in self:
|
||||
if not warehouse.lot_refurbish_id:
|
||||
location_id = location_obj.with_context(
|
||||
active_test=False
|
||||
).create({
|
||||
'name': _('Refurbish'),
|
||||
'usage': 'production',
|
||||
'location_id': warehouse.view_location_id.id,
|
||||
'company_id': warehouse.company_id.id,
|
||||
'active': True,
|
||||
})
|
||||
warehouse.lot_refurbish_id = location_id
|
||||
|
||||
loc_vals = {
|
||||
'location_id': wh_loc_id,
|
||||
'active': True,
|
||||
}
|
||||
|
||||
if vals.get('company_id'):
|
||||
loc_vals['company_id'] = vals.get('company_id')
|
||||
|
||||
if not wh_id.lot_refurbish_id:
|
||||
loc_vals.update({
|
||||
'name': _('Refurbish'),
|
||||
'usage': 'production'
|
||||
})
|
||||
location_id = location_obj.with_context(context_with_inactive).\
|
||||
create(loc_vals)
|
||||
vals['lot_refurbish_id'] = location_id.id
|
||||
|
||||
if not wh_id.loss_loc_id:
|
||||
loc_vals.update({
|
||||
'name': _('Loss'),
|
||||
'usage': 'inventory'
|
||||
})
|
||||
location_id = location_obj.with_context(context_with_inactive).\
|
||||
create(loc_vals)
|
||||
vals['loss_loc_id'] = location_id.id
|
||||
|
||||
vals.update(vals_new)
|
||||
return vals
|
||||
if not warehouse.loss_loc_id:
|
||||
location_id = location_obj.with_context(
|
||||
active_test=False
|
||||
).create({
|
||||
'name': _('Loss'),
|
||||
'usage': 'inventory',
|
||||
'location_id': warehouse.view_location_id.id,
|
||||
'company_id': warehouse.company_id.id,
|
||||
'active': True,
|
||||
})
|
||||
warehouse.loss_loc_id = location_id
|
||||
|
||||
@@ -1,23 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Author: Yanina Aular, Osval Reyes
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import test_crm_rma_stock_location
|
||||
from . import test_make_picking_from_picking
|
||||
from . import test_rma_stock
|
||||
|
||||
@@ -1,23 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Author: Osval Reyes
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# © 2015 Vauxoo
|
||||
# Author: Osval Reyes
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
|
||||
|
||||
@@ -1,23 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Yanina Aular
|
||||
# Copyright 2015 Vauxoo
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
##############################################################################
|
||||
# © 2015 Vauxoo
|
||||
# Author: Yanina Aular
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
|
||||
@@ -71,7 +55,7 @@ class TestPickingFromPicking(TransactionCase):
|
||||
'active_id': self.claim_id.id,
|
||||
'warehouse_id': self.claim_id.warehouse_id.id,
|
||||
'partner_id': self.claim_id.partner_id.id,
|
||||
'picking_type': self.claim_id.warehouse_id.rma_in_type_id.id,
|
||||
'picking_type': 'in',
|
||||
}
|
||||
wizard_id = self.wizardmakepicking.with_context(wiz_context).create({})
|
||||
|
||||
@@ -133,9 +117,10 @@ class TestPickingFromPicking(TransactionCase):
|
||||
}
|
||||
wizard_id = self.wizardmakepicking.with_context(new_context).create({})
|
||||
|
||||
default_location_dest_id = eval(
|
||||
'self.claim_id.warehouse_id.'
|
||||
'rma_%s_type_id.default_location_dest_id' % picking_type_str)
|
||||
default_location_dest_id = getattr(
|
||||
self.claim_id.warehouse_id,
|
||||
'rma_%s_type_id' % picking_type_str
|
||||
).default_location_dest_id
|
||||
self.assertEquals(
|
||||
wizard_id.claim_line_dest_location_id, default_location_dest_id)
|
||||
|
||||
@@ -153,7 +138,7 @@ class TestPickingFromPicking(TransactionCase):
|
||||
}
|
||||
wizard_id = self.wizardmakepicking.with_context(new_context).create({})
|
||||
|
||||
default_location_dest_id = eval(
|
||||
'self.claim_id.warehouse_id.loss_loc_id')
|
||||
default_location_dest_id = self.claim_id.warehouse_id.loss_loc_id
|
||||
self.assertEquals(
|
||||
wizard_id.claim_line_dest_location_id, default_location_dest_id)
|
||||
wizard_id.claim_line_dest_location_id, default_location_dest_id
|
||||
)
|
||||
|
||||
194
crm_rma_stock_location/tests/test_rma_stock.py
Normal file
194
crm_rma_stock_location/tests/test_rma_stock.py
Normal file
@@ -0,0 +1,194 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Cyril Gaudin (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp.tests import TransactionCase
|
||||
|
||||
|
||||
class TestRMAStock(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRMAStock, self).setUp()
|
||||
self.wh_main = self.env.ref("stock.warehouse0")
|
||||
|
||||
location_model = self.env['stock.location']
|
||||
self.loc_rma = location_model.create({
|
||||
'name': 'RMA',
|
||||
'usage': 'view',
|
||||
'location_id': self.wh_main.view_location_id.id,
|
||||
})
|
||||
|
||||
self.loc_box_a = location_model.create({
|
||||
'name': 'RMA - Box A',
|
||||
'usage': 'internal',
|
||||
'location_id': self.loc_rma.id,
|
||||
})
|
||||
|
||||
self.loc_box_b = location_model.create({
|
||||
'name': 'RMA - Box B',
|
||||
'usage': 'internal',
|
||||
'location_id': self.loc_rma.id,
|
||||
})
|
||||
|
||||
self.wh_main.lot_rma_id = self.loc_rma
|
||||
|
||||
# Create products
|
||||
self.product_socket = self.env['product.product'].create({
|
||||
'name': 'Sockets',
|
||||
})
|
||||
|
||||
self.product_shoes = self.env['product.product'].create({
|
||||
'name': 'Shoes',
|
||||
})
|
||||
|
||||
def test_rma_qty(self):
|
||||
# Put 50 in box A
|
||||
inventory = self.env['stock.inventory'].create({
|
||||
'name': 'Inventory for Sockets',
|
||||
'location_id': self.loc_box_a.id,
|
||||
'filter': 'partial'
|
||||
})
|
||||
inventory.prepare_inventory()
|
||||
|
||||
self.env['stock.inventory.line'].create({
|
||||
'inventory_id': inventory.id,
|
||||
'product_id': self.product_socket.id,
|
||||
'location_id': self.loc_box_a.id,
|
||||
'product_qty': 50,
|
||||
})
|
||||
inventory.action_done()
|
||||
|
||||
# Confirmed move for 30 in box B
|
||||
self.env['stock.move'].create({
|
||||
'name': 'Test move rma',
|
||||
'state': 'confirmed',
|
||||
'product_id': self.product_socket.id,
|
||||
'product_uom_qty': 30,
|
||||
'product_uom': self.product_socket.uom_id.id,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.loc_box_b.id,
|
||||
})
|
||||
|
||||
# Should have 50 avalaible and 80 forecasted
|
||||
self.assertEqual(50.0, self.product_socket.rma_qty_available)
|
||||
self.assertEqual(80.0, self.product_socket.rma_virtual_available)
|
||||
|
||||
# A warehouse can be specified
|
||||
other_warehouse = self.env['stock.warehouse'].create({
|
||||
'name': 'Other warehouse',
|
||||
'partner_id': self.ref('base.main_partner'),
|
||||
'code': 'WH2',
|
||||
})
|
||||
|
||||
self.assertEqual(
|
||||
0.0,
|
||||
self.product_socket.with_context(
|
||||
warehouse_id=other_warehouse.id
|
||||
).rma_qty_available
|
||||
)
|
||||
self.assertEqual(
|
||||
0.0,
|
||||
self.product_socket.with_context(
|
||||
warehouse_id=other_warehouse.id
|
||||
).rma_virtual_available
|
||||
)
|
||||
|
||||
# Reset lot_rma_id (automatically created)
|
||||
other_warehouse.lot_rma_id = False
|
||||
self.product_socket.refresh()
|
||||
self.assertEqual(
|
||||
0.0,
|
||||
self.product_socket.with_context(
|
||||
warehouse_id=other_warehouse.id
|
||||
).rma_qty_available
|
||||
)
|
||||
self.assertEqual(
|
||||
0.0,
|
||||
self.product_socket.with_context(
|
||||
warehouse_id=other_warehouse.id
|
||||
).rma_virtual_available
|
||||
)
|
||||
|
||||
def test_multi(self):
|
||||
inventory = self.env['stock.inventory'].create({
|
||||
'name': 'Inventory for Sockets',
|
||||
'location_id': self.loc_box_a.id,
|
||||
'filter': 'partial'
|
||||
})
|
||||
inventory.prepare_inventory()
|
||||
|
||||
# Put 20 sockets and 10 shoes in box A
|
||||
self.env['stock.inventory.line'].create({
|
||||
'inventory_id': inventory.id,
|
||||
'product_id': self.product_socket.id,
|
||||
'location_id': self.loc_box_a.id,
|
||||
'product_qty': 20,
|
||||
})
|
||||
self.env['stock.inventory.line'].create({
|
||||
'inventory_id': inventory.id,
|
||||
'product_id': self.product_shoes.id,
|
||||
'location_id': self.loc_box_a.id,
|
||||
'product_qty': 10,
|
||||
})
|
||||
inventory.action_done()
|
||||
|
||||
qties = self.env['product.product'].search_read(
|
||||
[('id', 'in', [self.product_socket.id, self.product_shoes.id])],
|
||||
['rma_qty_available', 'rma_virtual_available'],
|
||||
order='id'
|
||||
)
|
||||
self.assertEqual([
|
||||
{'id': self.product_socket.id, 'rma_qty_available': 20,
|
||||
'rma_virtual_available': 20},
|
||||
{'id': self.product_shoes.id, 'rma_qty_available': 10,
|
||||
'rma_virtual_available': 10}
|
||||
], qties)
|
||||
|
||||
def test_variants(self):
|
||||
|
||||
self.variant_shoes = self.env['product.product'].create({
|
||||
'product_tmpl_id': self.product_shoes.product_tmpl_id.id,
|
||||
'name': 'Variant shoes'
|
||||
})
|
||||
inventory = self.env['stock.inventory'].create({
|
||||
'name': 'Inventory for Sockets',
|
||||
'location_id': self.loc_box_a.id,
|
||||
'filter': 'partial'
|
||||
})
|
||||
inventory.prepare_inventory()
|
||||
|
||||
# Put 5 shoes and 4 variant shoes in box A
|
||||
self.env['stock.inventory.line'].create({
|
||||
'inventory_id': inventory.id,
|
||||
'product_id': self.product_shoes.id,
|
||||
'location_id': self.loc_box_a.id,
|
||||
'product_qty': 5,
|
||||
})
|
||||
self.env['stock.inventory.line'].create({
|
||||
'inventory_id': inventory.id,
|
||||
'product_id': self.variant_shoes.id,
|
||||
'location_id': self.loc_box_a.id,
|
||||
'product_qty': 4,
|
||||
})
|
||||
inventory.action_done()
|
||||
|
||||
# Confirmed move for 3 variant shoes in box B
|
||||
self.env['stock.move'].create({
|
||||
'name': 'Test move rma',
|
||||
'state': 'confirmed',
|
||||
'product_id': self.variant_shoes.id,
|
||||
'product_uom_qty': 3,
|
||||
'product_uom': self.variant_shoes.uom_id.id,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.loc_box_b.id,
|
||||
})
|
||||
|
||||
self.assertEqual(5.0, self.product_shoes.rma_qty_available)
|
||||
self.assertEqual(5.0, self.product_shoes.rma_virtual_available)
|
||||
|
||||
self.assertEqual(4.0, self.variant_shoes.rma_qty_available)
|
||||
self.assertEqual(7.0, self.variant_shoes.rma_virtual_available)
|
||||
|
||||
shoes_template = self.product_shoes.product_tmpl_id
|
||||
self.assertEqual(9.0, shoes_template.rma_qty_available)
|
||||
self.assertEqual(12.0, shoes_template.rma_virtual_available)
|
||||
@@ -1,19 +1,16 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="crm_claim_rma_form_view_loss">
|
||||
<field name="name">CRM - Claim product return Form</field>
|
||||
<field name="model">crm.claim</field>
|
||||
<field name="inherit_id" ref="crm_claim_rma.crm_claim_rma_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@string='New Delivery']" position="after">
|
||||
<button name="%(action_claim_picking_loss)d"
|
||||
string="New Product Loss"
|
||||
type="action" target="new"
|
||||
context="{'warehouse_id': warehouse_id,
|
||||
'partner_id': partner_id}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="crm_claim_rma_form_view_loss">
|
||||
<field name="name">CRM - Claim product return Form</field>
|
||||
<field name="model">crm.claim</field>
|
||||
<field name="inherit_id" ref="crm_claim_rma.crm_claim_rma_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<button name="%(crm_claim_rma.action_claim_picking_in)d" position="after">
|
||||
<button name="%(action_claim_picking_loss)d"
|
||||
string="New Product Loss"
|
||||
type="action" target="new"
|
||||
context="{'warehouse_id': warehouse_id, 'partner_id': partner_id}"/>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -1,46 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="rma_product_product_tree_view" model="ir.ui.view">
|
||||
<field name="name">product.stock.tree.inherit</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Product Variants" create="false">
|
||||
<field name="default_code"/>
|
||||
<field name="name"/>
|
||||
<field name="attribute_value_ids" widget="many2many_tags"/>
|
||||
<field name="rma_qty_available"/>
|
||||
<field name="rma_virtual_available"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<odoo>
|
||||
<record id="rma_product_product_tree_view" model="ir.ui.view">
|
||||
<field name="name">product.stock.tree.inherit</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Product Variants" create="false">
|
||||
<field name="default_code"/>
|
||||
<field name="name"/>
|
||||
<field name="attribute_value_ids" widget="many2many_tags"/>
|
||||
<field name="rma_qty_available"/>
|
||||
<field name="rma_virtual_available"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="rma_product_search_view" model="ir.ui.view">
|
||||
<field name="name">product.product.search</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="RMA Products">
|
||||
<separator/>
|
||||
<filter name="rma_available" string="RMA Available Products"
|
||||
domain="['|', ('rma_qty_available','>',0), ('rma_virtual_available','>',0)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="rma_product_search_view" model="ir.ui.view">
|
||||
<field name="name">product.product.search</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="RMA Products">
|
||||
<separator/>
|
||||
<filter name="rma_available" string="RMA Available Products"
|
||||
domain="['|', ('rma_qty_available','>',0), ('rma_virtual_available','>',0)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="rma_product_variant_action" model="ir.actions.act_window">
|
||||
<field name="name">RMA Stock</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">product.product</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="rma_product_product_tree_view"/>
|
||||
<field name="search_view_id" ref="rma_product_search_view"/>
|
||||
<field name="context">{'search_default_rma_available': 1}</field>
|
||||
</record>
|
||||
<record id="rma_product_variant_action" model="ir.actions.act_window">
|
||||
<field name="name">RMA Stock</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">product.product</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="rma_product_product_tree_view"/>
|
||||
<field name="search_view_id" ref="rma_product_search_view"/>
|
||||
<field name="context">{'search_default_rma_available': 1}</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="rma_product_variant_action"
|
||||
id="menu_stock_rma" parent="base.menu_aftersale"
|
||||
name="RMA Stock"
|
||||
sequence="100"/>
|
||||
</data>
|
||||
</openerp>
|
||||
<menuitem action="rma_product_variant_action"
|
||||
id="menu_stock_rma" parent="base.menu_aftersale"
|
||||
name="RMA Stock"
|
||||
sequence="100"/>
|
||||
</odoo>
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_template_property_form" model="ir.ui.view">
|
||||
<field name="name">product.normal.procurement.locations.inherit</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="stock.view_template_property_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='virtual_available']" position="after">
|
||||
<field name="rma_qty_available"/>
|
||||
<field name="rma_virtual_available"/>
|
||||
</xpath>
|
||||
<odoo>
|
||||
<record id="product_template_tree_view" model="ir.ui.view">
|
||||
<field name="name">product.template.tree</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="stock.view_stock_product_template_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="virtual_available" position="after">
|
||||
<field name="rma_qty_available"/>
|
||||
<field name="rma_virtual_available"/>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_template_form_view_rma" model="ir.ui.view">
|
||||
<field name="name">product.form.view.rma</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name='inventory' position="after">
|
||||
<separator string="RMA"/>
|
||||
<group name="rma">
|
||||
<field name="rma_qty_available" class="oe_inline"/>
|
||||
<field name="rma_virtual_available" class="oe_inline"/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -1,30 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- INHERITED VIEW FOR THE OBJECT : stock_picking -->
|
||||
<record id="picking_in_form" model="ir.ui.view">
|
||||
<field name="name">crm_claim_rma.picking_in_form</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='state']" position="before">
|
||||
<button name="%(action_stock_picking_from_claim_picking)d"
|
||||
string="Product to stock" type="action"
|
||||
attrs="{'invisible':['|',
|
||||
('state','<>','done'),
|
||||
('claim_id', '=', False)]}"/>
|
||||
<button name="%(action_loss_picking_from_claim_picking)d"
|
||||
string="Product to Loss" type="action"
|
||||
attrs="{'invisible':['|',
|
||||
('state','<>','done'),
|
||||
('claim_id', '=', False)]}"/>
|
||||
<button name="%(action_used_picking_from_claim_picking)d"
|
||||
string="Product to refurbish stock" type="action"
|
||||
attrs="{'invisible':['|',
|
||||
('state','<>','done'),
|
||||
('claim_id', '=', False)]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
<odoo>
|
||||
<!-- INHERITED VIEW FOR THE OBJECT : stock_picking -->
|
||||
<record id="picking_in_form" model="ir.ui.view">
|
||||
<field name="name">crm_claim_rma.picking_in_form</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='state']" position="before">
|
||||
<button name="%(action_stock_picking_from_claim_picking)d"
|
||||
string="Product to stock" type="action"
|
||||
attrs="{'invisible':['|',
|
||||
('state','<>','done'),
|
||||
('claim_id', '=', False)]}"/>
|
||||
<button name="%(action_loss_picking_from_claim_picking)d"
|
||||
string="Product to Loss" type="action"
|
||||
attrs="{'invisible':['|',
|
||||
('state','<>','done'),
|
||||
('claim_id', '=', False)]}"/>
|
||||
<button name="%(action_used_picking_from_claim_picking)d"
|
||||
string="Product to refurbish stock" type="action"
|
||||
attrs="{'invisible':['|',
|
||||
('state','<>','done'),
|
||||
('claim_id', '=', False)]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="warehouse_form" model="ir.ui.view">
|
||||
<field name="name">crm_claim_rma.warehouse_form</field>
|
||||
<field name="model">stock.warehouse</field>
|
||||
<field name="inherit_id" ref="crm_rma_location.view_warehouse_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='lot_rma_id']" position="after">
|
||||
<field name="loss_loc_id"/>
|
||||
<field name="lot_refurbish_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
<odoo>
|
||||
<record id="warehouse_form" model="ir.ui.view">
|
||||
<field name="name">crm_claim_rma.warehouse_form</field>
|
||||
<field name="model">stock.warehouse</field>
|
||||
<field name="inherit_id" ref="crm_rma_location.view_warehouse_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='lot_rma_id']" position="after">
|
||||
<field name="loss_loc_id"/>
|
||||
<field name="lot_refurbish_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -1,24 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
# 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 . import claim_make_picking_from_picking
|
||||
from . import claim_make_picking
|
||||
|
||||
@@ -1,25 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright (C) 2009-2012 Akretion
|
||||
# Author: Emmanuel Samyn, Benoît GUILLOT <benoit.guillot@akretion.com>,
|
||||
# Osval Reyes
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# © 2015 Vauxoo
|
||||
# © 2009-2012 Akretion
|
||||
# Author: Emmanuel Samyn, Benoît GUILLOT <benoit.guillot@akretion.com>,
|
||||
# Osval Reyes
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import models, fields
|
||||
|
||||
|
||||
@@ -1,27 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright (C) 2009-2012 Akretion
|
||||
# Author: Emmanuel Samyn, Benoît GUILLOT <benoit.guillot@akretion.com>,
|
||||
# Osval Reyes
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# © 2015 Vauxoo
|
||||
# © 2009-2012 Akretion
|
||||
# Author: Emmanuel Samyn, Benoît GUILLOT <benoit.guillot@akretion.com>,
|
||||
# Osval Reyes
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import _, models, fields, api
|
||||
|
||||
from openerp import models, fields, api
|
||||
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp import workflow
|
||||
import time
|
||||
@@ -82,16 +67,19 @@ class ClaimMakePickingFromPicking(models.TransientModel):
|
||||
return loc_id
|
||||
|
||||
picking_line_source_location = fields.Many2one(
|
||||
'stock.location', _('Source Location'),
|
||||
help=_("Source location where the returned products are"),
|
||||
required=True, default=_get_source_loc)
|
||||
'stock.location', 'Source Location',
|
||||
help="Source location where the returned products are",
|
||||
required=True, default=_get_source_loc
|
||||
)
|
||||
picking_line_dest_location = fields.Many2one(
|
||||
'stock.location', _('Dest. Location'),
|
||||
help=_("Target location to send returned products"),
|
||||
required=True, default=_get_dest_loc)
|
||||
'stock.location', 'Dest. Location',
|
||||
help="Target location to send returned products",
|
||||
required=True, default=_get_dest_loc
|
||||
)
|
||||
picking_line_ids = fields.Many2many(
|
||||
'stock.move', 'claim_picking_line_picking', 'claim_picking_id',
|
||||
'picking_line_id', 'Picking lines', default=_get_picking_lines)
|
||||
'picking_line_id', 'Picking lines', default=_get_picking_lines
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def action_cancel(self):
|
||||
@@ -124,7 +112,6 @@ class ClaimMakePickingFromPicking(models.TransientModel):
|
||||
'state': 'draft',
|
||||
'date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
'partner_id': prev_picking.partner_id.id,
|
||||
'invoice_state': "none",
|
||||
'company_id': prev_picking.company_id.id,
|
||||
'location_id': self.picking_line_source_location.id,
|
||||
'location_dest_id': self.picking_line_dest_location.id,
|
||||
@@ -152,7 +139,6 @@ class ClaimMakePickingFromPicking(models.TransientModel):
|
||||
'location_id': self.picking_line_source_location.id,
|
||||
'location_dest_id': self.picking_line_dest_location.id,
|
||||
'note': note,
|
||||
'invoice_state': 'none',
|
||||
})
|
||||
wizard_picking_line.write(
|
||||
{'move_dest_id': move_id.id})
|
||||
|
||||
@@ -4,65 +4,63 @@
|
||||
Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com>
|
||||
The licence is in the file __openerp__.py
|
||||
-->
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_claim_picking_from_picking" model="ir.ui.view">
|
||||
<field name="name">claim_picking</field>
|
||||
<field name="model">claim.make.picking.from.picking.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Select lines to add in picking">
|
||||
<separator string="Locations" colspan="4"/>
|
||||
<field name="picking_line_source_location" nolabel="1" />
|
||||
<field name="picking_line_dest_location" nolabel="1" />
|
||||
<separator string="Select lines for picking" colspan="4"/>
|
||||
<field name="picking_line_ids" nolabel="1" colspan="4"/>
|
||||
<group col="4" colspan="2">
|
||||
<button special="cancel" string="Cancel"
|
||||
name="action_cancel" type="object"
|
||||
icon='gtk-cancel'/>
|
||||
<button name="action_create_picking_from_picking"
|
||||
string="Create picking"
|
||||
icon='gtk-ok' type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<odoo>
|
||||
<record id="view_claim_picking_from_picking" model="ir.ui.view">
|
||||
<field name="name">claim_picking</field>
|
||||
<field name="model">claim.make.picking.from.picking.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Select lines to add in picking">
|
||||
<separator string="Locations" colspan="4"/>
|
||||
<field name="picking_line_source_location" nolabel="1" />
|
||||
<field name="picking_line_dest_location" nolabel="1" />
|
||||
<separator string="Select lines for picking" colspan="4"/>
|
||||
<field name="picking_line_ids" nolabel="1" colspan="4"/>
|
||||
<group col="4" colspan="2">
|
||||
<button special="cancel" string="Cancel"
|
||||
name="action_cancel" type="object"
|
||||
icon='gtk-cancel'/>
|
||||
<button name="action_create_picking_from_picking"
|
||||
string="Create picking"
|
||||
icon='gtk-ok' type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_stock_picking_from_claim_picking"
|
||||
model="ir.actions.act_window">
|
||||
<field name="name">Create Incoming Shipment to Stock</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">claim.make.picking.from.picking.wizard</field>
|
||||
<field name="src_model">stock.picking</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'picking_type': 'picking_stock'}</field>
|
||||
</record>
|
||||
<record id="action_stock_picking_from_claim_picking"
|
||||
model="ir.actions.act_window">
|
||||
<field name="name">Create Incoming Shipment to Stock</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">claim.make.picking.from.picking.wizard</field>
|
||||
<field name="src_model">stock.picking</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'picking_type': 'picking_stock'}</field>
|
||||
</record>
|
||||
|
||||
<record id="action_loss_picking_from_claim_picking"
|
||||
model="ir.actions.act_window">
|
||||
<field name="name">Create Incoming Shipment to Breakage Loss Location</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">claim.make.picking.from.picking.wizard</field>
|
||||
<field name="src_model">stock.picking</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'picking_type': 'picking_loss'}
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_loss_picking_from_claim_picking"
|
||||
model="ir.actions.act_window">
|
||||
<field name="name">Create Incoming Shipment to Breakage Loss Location</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">claim.make.picking.from.picking.wizard</field>
|
||||
<field name="src_model">stock.picking</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'picking_type': 'picking_loss'}
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_used_picking_from_claim_picking"
|
||||
model="ir.actions.act_window">
|
||||
<field name="name">Create Incoming Shipment to Refurbish Location</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">claim.make.picking.from.picking.wizard</field>
|
||||
<field name="src_model">stock.picking</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'picking_type': 'picking_refurbish'}</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
<record id="action_used_picking_from_claim_picking"
|
||||
model="ir.actions.act_window">
|
||||
<field name="name">Create Incoming Shipment to Refurbish Location</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">claim.make.picking.from.picking.wizard</field>
|
||||
<field name="src_model">stock.picking</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'picking_type': 'picking_refurbish'}</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -4,17 +4,15 @@
|
||||
Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com>
|
||||
The licence is in the file __openerp__.py
|
||||
-->
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="action_claim_picking_loss" model="ir.actions.act_window">
|
||||
<field name="name">Create a Product Loss</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">claim_make_picking.wizard</field>
|
||||
<field name="src_model">crm.claim</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'picking_type': 'loss'}</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
<odoo>
|
||||
<record id="action_claim_picking_loss" model="ir.actions.act_window">
|
||||
<field name="name">Create a Product Loss</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">claim_make_picking.wizard</field>
|
||||
<field name="src_model">crm.claim</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'picking_type': 'loss'}</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user