mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
IMP rma add the ability to relate RMA's to pickings.
Additionally, improve tests to add lines by the wizard instead of manually (especially since manually is not an option in the UI).
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import controllers
|
||||
from . import models
|
||||
from . import wizard
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
'security/ir.model.access.csv',
|
||||
'views/rma_views.xml',
|
||||
'views/stock_picking_views.xml',
|
||||
'wizard/rma_lines_views.xml',
|
||||
],
|
||||
'demo': [
|
||||
'data/rma_demo.xml',
|
||||
|
||||
@@ -9,4 +9,16 @@
|
||||
<field name="out_location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="out_procure_method">make_to_stock</field>
|
||||
</record>
|
||||
|
||||
<record id="template_picking_return" model="rma.template">
|
||||
<field name="name">Picking Return</field>
|
||||
<field name="usage">stock_picking</field>
|
||||
<field name="valid_days" eval="10"/>
|
||||
<field name="create_in_picking" eval="True"/>
|
||||
<field name="in_type_id" ref="stock.picking_type_in"/>
|
||||
<field name="in_location_id" ref="stock.stock_location_customers"/>
|
||||
<field name="in_location_dest_id" ref="stock.stock_location_stock"/>
|
||||
<field name="in_procure_method">make_to_stock</field>
|
||||
<field name="in_require_return" eval="True"/>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -11,7 +11,9 @@ class RMATemplate(models.Model):
|
||||
_name = 'rma.template'
|
||||
|
||||
name = fields.Char(string='Name')
|
||||
usage = fields.Selection([], string='Applies To')
|
||||
usage = fields.Selection([
|
||||
('stock_picking', 'Stock Picking'),
|
||||
], string='Applies To')
|
||||
description = fields.Html(string='Internal Instructions')
|
||||
customer_description = fields.Html(string='Customer Instructions')
|
||||
valid_days = fields.Integer(string='Expire in Days')
|
||||
@@ -30,7 +32,6 @@ class RMATemplate(models.Model):
|
||||
('make_to_stock', 'Take from Stock'),
|
||||
('make_to_order', 'Apply Procurements')
|
||||
], string="Inbound Procurement Method", default='make_to_stock')
|
||||
in_to_refund_so = fields.Boolean(string='Inbound mark refund SO')
|
||||
|
||||
out_location_id = fields.Many2one('stock.location', string='Outbound Source Location')
|
||||
out_location_dest_id = fields.Many2one('stock.location', string='Outbound Destination Location')
|
||||
@@ -103,6 +104,8 @@ class RMA(models.Model):
|
||||
], string='State', default='draft', copy=False)
|
||||
company_id = fields.Many2one('res.company', 'Company')
|
||||
template_id = fields.Many2one('rma.template', string='Type', required=True)
|
||||
stock_picking_id = fields.Many2one('stock.picking', string='Stock Picking')
|
||||
stock_picking_rma_count = fields.Integer('Number of RMAs for this Picking', compute='_compute_stock_picking_rma_count')
|
||||
partner_id = fields.Many2one('res.partner', string='Partner')
|
||||
partner_shipping_id = fields.Many2one('res.partner', string='Shipping')
|
||||
lines = fields.One2many('rma.line', 'rma_id', string='Lines')
|
||||
@@ -130,9 +133,18 @@ class RMA(models.Model):
|
||||
@api.multi
|
||||
def _onchange_template_usage(self):
|
||||
now = datetime.now()
|
||||
for rma in self.filtered(lambda r: r.template_id.valid_days):
|
||||
rma.validity_date = now + timedelta(days=rma.template_id.valid_days)
|
||||
for rma in self:
|
||||
if rma.template_id.valid_days:
|
||||
rma.validity_date = now + timedelta(days=rma.template_id.valid_days)
|
||||
if rma.template_usage != 'stock_picking':
|
||||
rma.stock_picking_id = False
|
||||
|
||||
@api.onchange('stock_picking_id')
|
||||
@api.multi
|
||||
def _onchange_stock_picking_id(self):
|
||||
for rma in self.filtered(lambda rma: rma.stock_picking_id):
|
||||
rma.partner_id = rma.stock_picking_id.partner_id
|
||||
rma.partner_shipping_id = rma.stock_picking_id.partner_id
|
||||
|
||||
@api.onchange('in_carrier_tracking_ref', 'validity_date')
|
||||
@api.multi
|
||||
@@ -162,6 +174,29 @@ class RMA(models.Model):
|
||||
str(attachment.id) + '&e=' + str(e_expires) + \
|
||||
'&h=' + create_hmac(secret, attachment.id, e_expires)
|
||||
|
||||
@api.multi
|
||||
@api.depends('stock_picking_id')
|
||||
def _compute_stock_picking_rma_count(self):
|
||||
for rma in self:
|
||||
if rma.stock_picking_id:
|
||||
rma_data = self.read_group([('stock_picking_id', '=', rma.stock_picking_id.id), ('state', '!=', 'cancel')],
|
||||
['stock_picking_id'], ['stock_picking_id'])
|
||||
if rma_data:
|
||||
rma.stock_picking_rma_count = rma_data[0]['stock_picking_id_count']
|
||||
else:
|
||||
rma.stock_picking_rma_count = 0.0
|
||||
|
||||
|
||||
@api.multi
|
||||
def open_stock_picking_rmas(self):
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _('Picking RMAs'),
|
||||
'res_model': 'rma.rma',
|
||||
'view_mode': 'tree,form',
|
||||
'context': {'search_default_stock_picking_id': self[0].stock_picking_id.id}
|
||||
}
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if vals.get('name', _('New')) == _('New'):
|
||||
@@ -242,6 +277,17 @@ class RMA(models.Model):
|
||||
if rma.in_picking_id and rma.in_picking_carrier_id:
|
||||
rma.in_picking_id.send_to_shipper()
|
||||
|
||||
@api.multi
|
||||
def action_add_picking_lines(self):
|
||||
make_line_obj = self.env['rma.picking.make.lines']
|
||||
for rma in self:
|
||||
lines = make_line_obj.create({
|
||||
'rma_id': rma.id,
|
||||
})
|
||||
action = self.env.ref('rma.action_rma_add_lines').read()[0]
|
||||
action['res_id'] = lines.id
|
||||
return action
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
for rma in self:
|
||||
@@ -249,6 +295,115 @@ class RMA(models.Model):
|
||||
raise UserError(_('You can not delete a non-draft RMA.'))
|
||||
return super(RMA, self).unlink()
|
||||
|
||||
def _create_in_picking_stock_picking(self):
|
||||
if not self.stock_picking_id or self.stock_picking_id.state != 'done':
|
||||
raise UserError(_('You must have a completed stock picking for this RMA.'))
|
||||
if not self.template_id.in_require_return:
|
||||
group_id = self.stock_picking_id.group_id.id if self.stock_picking_id.group_id else 0
|
||||
|
||||
values = self.template_id._values_for_in_picking(self)
|
||||
values.update({'group_id': group_id})
|
||||
move_lines = []
|
||||
for l1, l2, vals in values['move_lines']:
|
||||
vals.update({'group_id': group_id})
|
||||
move_lines.append((l1, l2, vals))
|
||||
values['move_lines'] = move_lines
|
||||
return self.env['stock.picking'].sudo().create(values)
|
||||
|
||||
lines = self.lines.filtered(lambda l: l.product_uom_qty >= 1)
|
||||
if not lines:
|
||||
raise UserError(_('You have no lines with positive quantity.'))
|
||||
|
||||
old_picking = self.stock_picking_id
|
||||
|
||||
new_picking = old_picking.copy({
|
||||
'move_lines': [],
|
||||
'picking_type_id': self.template_id.in_type_id.id,
|
||||
'state': 'draft',
|
||||
'origin': old_picking.name + ' ' + self.name,
|
||||
'location_id': self.template_id.in_location_id.id,
|
||||
'location_dest_id': self.template_id.in_location_dest_id.id,
|
||||
'carrier_id': self.template_id.in_carrier_id.id if self.template_id.in_carrier_id else 0,
|
||||
'carrier_tracking_ref': False,
|
||||
'carrier_price': False
|
||||
})
|
||||
new_picking.message_post_with_view('mail.message_origin_link',
|
||||
values={'self': new_picking, 'origin': self},
|
||||
subtype_id=self.env.ref('mail.mt_note').id)
|
||||
|
||||
for l in lines:
|
||||
return_move = old_picking.move_lines.filtered(lambda ol: ol.state == 'done' and ol.product_id.id == l.product_id.id)[0]
|
||||
return_move.copy({
|
||||
'name': self.name + ' IN: ' + l.product_id.name_get()[0][1],
|
||||
'product_id': l.product_id.id,
|
||||
'product_uom_qty': l.product_uom_qty,
|
||||
'picking_id': new_picking.id,
|
||||
'state': 'draft',
|
||||
'location_id': return_move.location_dest_id.id,
|
||||
'location_dest_id': self.template_id.in_location_dest_id.id,
|
||||
'picking_type_id': new_picking.picking_type_id.id,
|
||||
'warehouse_id': new_picking.picking_type_id.warehouse_id.id,
|
||||
'origin_returned_move_id': return_move.id,
|
||||
'procure_method': self.template_id.in_procure_method,
|
||||
'move_dest_id': False,
|
||||
})
|
||||
|
||||
return new_picking
|
||||
|
||||
def _create_out_picking_stock_picking(self):
|
||||
if not self.stock_picking_id or self.stock_picking_id.state != 'done':
|
||||
raise UserError(_('You must have a completed stock picking for this RMA.'))
|
||||
if not self.template_id.out_require_return:
|
||||
group_id = self.stock_picking_id.group_id.id if self.stock_picking_id.group_id else 0
|
||||
|
||||
values = self.template_id._values_for_out_picking(self)
|
||||
values.update({'group_id': group_id})
|
||||
move_lines = []
|
||||
for l1, l2, vals in values['move_lines']:
|
||||
vals.update({'group_id': group_id})
|
||||
move_lines.append((l1, l2, vals))
|
||||
values['move_lines'] = move_lines
|
||||
return self.env['stock.picking'].sudo().create(values)
|
||||
|
||||
lines = self.lines.filtered(lambda l: l.product_uom_qty >= 1)
|
||||
if not lines:
|
||||
raise UserError(_('You have no lines with positive quantity.'))
|
||||
|
||||
old_picking = self.stock_picking_id
|
||||
new_picking = old_picking.copy({
|
||||
'move_lines': [],
|
||||
'picking_type_id': self.template_id.out_type_id.id,
|
||||
'state': 'draft',
|
||||
'origin': old_picking.name + ' ' + self.name,
|
||||
'location_id': self.template_id.out_location_id.id,
|
||||
'location_dest_id': self.template_id.out_location_dest_id.id,
|
||||
'carrier_id': self.template_id.out_carrier_id.id if self.template_id.out_carrier_id else 0,
|
||||
'carrier_tracking_ref': False,
|
||||
'carrier_price': False
|
||||
})
|
||||
new_picking.message_post_with_view('mail.message_origin_link',
|
||||
values={'self': new_picking, 'origin': self},
|
||||
subtype_id=self.env.ref('mail.mt_note').id)
|
||||
|
||||
for l in lines:
|
||||
return_move = old_picking.move_lines.filtered(lambda ol: ol.state == 'done' and ol.product_id.id == l.product_id.id)[0]
|
||||
return_move.copy({
|
||||
'name': self.name + ' OUT: ' + l.product_id.name_get()[0][1],
|
||||
'product_id': l.product_id.id,
|
||||
'product_uom_qty': l.product_uom_qty,
|
||||
'picking_id': new_picking.id,
|
||||
'state': 'draft',
|
||||
'location_id': self.template_id.out_location_id.id,
|
||||
'location_dest_id': self.template_id.out_location_dest_id.id,
|
||||
'picking_type_id': new_picking.picking_type_id.id,
|
||||
'warehouse_id': new_picking.picking_type_id.warehouse_id.id,
|
||||
'origin_returned_move_id': False,
|
||||
'procure_method': self.template_id.out_procure_method,
|
||||
'move_dest_id': False,
|
||||
})
|
||||
|
||||
return new_picking
|
||||
|
||||
|
||||
class RMALine(models.Model):
|
||||
_name = 'rma.line'
|
||||
|
||||
@@ -7,12 +7,14 @@ class TestRMA(common.TransactionCase):
|
||||
def setUp(self):
|
||||
super(TestRMA, self).setUp()
|
||||
self.product1 = self.env.ref('product.product_product_24')
|
||||
self.template1 = self.env.ref('rma.template_missing_item')
|
||||
self.template_missing = self.env.ref('rma.template_missing_item')
|
||||
self.template_return = self.env.ref('rma.template_picking_return')
|
||||
self.partner1 = self.env.ref('base.res_partner_2')
|
||||
|
||||
def test_00_basic_rma(self):
|
||||
self.template_missing.usage = False
|
||||
rma = self.env['rma.rma'].create({
|
||||
'template_id': self.template1.id,
|
||||
'template_id': self.template_missing.id,
|
||||
'partner_id': self.partner1.id,
|
||||
'partner_shipping_id': self.partner1.id,
|
||||
})
|
||||
@@ -41,8 +43,9 @@ class TestRMA(common.TransactionCase):
|
||||
self.assertEqual(rma.state, 'done')
|
||||
|
||||
def test_10_rma_cancel(self):
|
||||
self.template_missing.usage = False
|
||||
rma = self.env['rma.rma'].create({
|
||||
'template_id': self.template1.id,
|
||||
'template_id': self.template_missing.id,
|
||||
'partner_id': self.partner1.id,
|
||||
'partner_shipping_id': self.partner1.id,
|
||||
})
|
||||
@@ -58,3 +61,65 @@ class TestRMA(common.TransactionCase):
|
||||
self.assertEqual(rma.out_picking_id.move_lines.state, 'assigned')
|
||||
rma.action_cancel()
|
||||
self.assertEqual(rma.out_picking_id.move_lines.state, 'cancel')
|
||||
|
||||
def test_20_picking_rma(self):
|
||||
type_out = self.env.ref('stock.picking_type_out')
|
||||
location = self.env.ref('stock.stock_location_stock')
|
||||
location_customer = self.env.ref('stock.stock_location_customers')
|
||||
self.product1.tracking = 'serial'
|
||||
picking_out = self.env['stock.picking'].create({
|
||||
'partner_id': self.partner1.id,
|
||||
'name': 'testpicking',
|
||||
'picking_type_id': type_out.id,
|
||||
'location_id': location.id,
|
||||
'location_dest_id': location_customer.id,
|
||||
})
|
||||
self.env['stock.move'].create({
|
||||
'name': self.product1.name,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom_qty': 1.0,
|
||||
'product_uom': self.product1.uom_id.id,
|
||||
'picking_id': picking_out.id,
|
||||
'location_id': location.id,
|
||||
'location_dest_id': location_customer.id,
|
||||
})
|
||||
picking_out.action_confirm()
|
||||
|
||||
# Try to RMA item not delivered yet
|
||||
rma = self.env['rma.rma'].create({
|
||||
'template_id': self.template_return.id,
|
||||
'partner_id': self.partner1.id,
|
||||
'partner_shipping_id': self.partner1.id,
|
||||
'stock_picking_id': picking_out.id,
|
||||
})
|
||||
self.assertEqual(rma.state, 'draft')
|
||||
wizard = self.env['rma.picking.make.lines'].create({
|
||||
'rma_id': rma.id,
|
||||
})
|
||||
wizard.line_ids.product_uom_qty = 1.0
|
||||
wizard.add_lines()
|
||||
self.assertEqual(len(rma.lines), 1)
|
||||
with self.assertRaises(UserError):
|
||||
rma.action_confirm()
|
||||
|
||||
picking_out.force_assign()
|
||||
pack_opt = self.env['stock.pack.operation'].search([('picking_id', '=', picking_out.id)], limit=1)
|
||||
lot = self.env['stock.production.lot'].create({'product_id': self.product1.id, 'name': 'X100'})
|
||||
self.env['stock.pack.operation.lot'].create({'operation_id': pack_opt.id, 'lot_id': lot.id, 'qty': 1.0})
|
||||
pack_opt.qty_done = 1.0
|
||||
picking_out.do_transfer()
|
||||
|
||||
self.assertEqual(picking_out.state, 'done')
|
||||
|
||||
rma.action_confirm()
|
||||
self.assertEqual(rma.in_picking_id.state, 'assigned')
|
||||
pack_opt = self.env['stock.pack.operation'].search([('picking_id', '=', rma.in_picking_id.id)], limit=1)
|
||||
self.assertEqual(pack_opt.pack_lot_ids.lot_id, lot)
|
||||
|
||||
with self.assertRaises(UserError):
|
||||
rma.action_done()
|
||||
|
||||
pack_opt.pack_lot_ids.qty = 1.0
|
||||
pack_opt.qty_done = 1.0
|
||||
rma.in_picking_id.do_transfer()
|
||||
rma.action_done()
|
||||
|
||||
@@ -13,7 +13,12 @@
|
||||
<field name="state" widget="statusbar" on_change="1" modifiers="{'readonly': true}"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" name="open_stock_picking_rmas" icon="fa-cubes"
|
||||
type="object" attrs="{'invisible': ['|', ('stock_picking_id', '=', False), ('stock_picking_rma_count', '<=', 1)]}">
|
||||
<field name="stock_picking_rma_count" string="Pick RMAs" widget="statinfo" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" readonly="1" modifiers="{'readonly': true, 'required': true}"/>
|
||||
@@ -23,6 +28,9 @@
|
||||
<group>
|
||||
<field name="template_usage" invisible="1"/>
|
||||
<field name="template_id" options="{'no_create': True}" attrs="{'readonly': [('state', 'in', ('confirmed', 'done', 'cancel'))]}"/>
|
||||
<field name="stock_picking_id" options="{'no_create': True}" attrs="{'invisible': [('template_usage', '!=', 'stock_picking')], 'required': [('template_usage', '=', 'stock_picking')], 'readonly': [('state', 'in', ('confirmed', 'done', 'cancel'))]}"/>
|
||||
<br/>
|
||||
<button string="Add lines" type="object" name="action_add_picking_lines" attrs="{'invisible': ['|', ('stock_picking_id', '=', False), ('state', '!=', 'draft')]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="validity_date"/>
|
||||
@@ -106,6 +114,7 @@
|
||||
<tree colors="blue:state == 'draft';gray:state in ('cancel', 'done');orange:validity_date and validity_date < current_date;">
|
||||
<field name="name"/>
|
||||
<field name="template_id"/>
|
||||
<field name="stock_picking_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="create_date"/>
|
||||
<field name="validity_date"/>
|
||||
@@ -122,6 +131,7 @@
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="template_id"/>
|
||||
<field name="stock_picking_id"/>
|
||||
<separator/>
|
||||
<filter string="New" name="new" domain="[('state', '=', 'draft')]"/>
|
||||
<filter string="Confirmed" name="confirmed" domain="[('state', '=', 'confirmed')]"/>
|
||||
@@ -161,7 +171,6 @@
|
||||
<field name="in_carrier_id" attrs="{'invisible': [('create_in_picking', '=', False)]}"/>
|
||||
<field name="in_require_return" attrs="{'invisible': [('create_in_picking', '=', False)]}"/>
|
||||
<field name="in_procure_method" attrs="{'invisible': [('create_in_picking', '=', False)]}"/>
|
||||
<field name="in_to_refund_so" attrs="{'invisible': [('create_in_picking', '=', False)]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="create_out_picking"/>
|
||||
|
||||
2
rma/wizard/__init__.py
Normal file
2
rma/wizard/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import rma_lines
|
||||
59
rma/wizard/rma_lines.py
Normal file
59
rma/wizard/rma_lines.py
Normal file
@@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class RMAPickingMakeLines(models.TransientModel):
|
||||
_name = 'rma.picking.make.lines'
|
||||
_description = 'Add Picking Lines'
|
||||
|
||||
rma_id = fields.Many2one('rma.rma', string='RMA')
|
||||
line_ids = fields.One2many('rma.picking.make.lines.line', 'rma_make_lines_id', string='Lines')
|
||||
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
maker = super(RMAPickingMakeLines, self).create(vals)
|
||||
maker._create_lines()
|
||||
return maker
|
||||
|
||||
def _line_values(self, move):
|
||||
return {
|
||||
'rma_make_lines_id': self.id,
|
||||
'product_id': move.product_id.id,
|
||||
'qty_ordered': move.ordered_qty,
|
||||
'qty_delivered': move.product_uom_qty,
|
||||
'product_uom_qty': 0.0,
|
||||
'product_uom_id': move.product_uom.id,
|
||||
}
|
||||
|
||||
def _create_lines(self):
|
||||
make_lines_obj = self.env['rma.picking.make.lines.line']
|
||||
|
||||
if self.rma_id.template_usage == 'stock_picking' and self.rma_id.stock_picking_id:
|
||||
for l in self.rma_id.stock_picking_id.move_lines:
|
||||
self.line_ids |= make_lines_obj.create(self._line_values(l))
|
||||
|
||||
@api.multi
|
||||
def add_lines(self):
|
||||
rma_line_obj = self.env['rma.line']
|
||||
for o in self:
|
||||
lines = o.line_ids.filtered(lambda l: l.product_uom_qty > 0.0)
|
||||
for l in lines:
|
||||
rma_line_obj.create({
|
||||
'rma_id': o.rma_id.id,
|
||||
'product_id': l.product_id.id,
|
||||
'product_uom_id': l.product_uom_id.id,
|
||||
'product_uom_qty': l.product_uom_qty,
|
||||
})
|
||||
|
||||
|
||||
class RMAPickingMakeLinesLine(models.TransientModel):
|
||||
_name = 'rma.picking.make.lines.line'
|
||||
|
||||
rma_make_lines_id = fields.Many2one('rma.picking.make.lines')
|
||||
product_id = fields.Many2one('product.product', string="Product")
|
||||
qty_ordered = fields.Float(string='Ordered')
|
||||
qty_delivered = fields.Float(string='Delivered')
|
||||
product_uom_qty = fields.Float(string='QTY')
|
||||
product_uom_id = fields.Many2one('product.uom', 'UOM')
|
||||
38
rma/wizard/rma_lines_views.xml
Normal file
38
rma/wizard/rma_lines_views.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record id="view_rma_add_lines_form" model="ir.ui.view">
|
||||
<field name="name">view.rma.add.lines.form</field>
|
||||
<field name="model">rma.picking.make.lines</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="line_ids">
|
||||
<tree editable="top">
|
||||
<field name="product_id" readonly="1"/>
|
||||
<field name="qty_ordered" readonly="1"/>
|
||||
<field name="qty_delivered" readonly="1"/>
|
||||
<field name="product_uom_qty"/>
|
||||
<field name="product_uom_id" readonly="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
<footer>
|
||||
<button class="oe_highlight"
|
||||
name="add_lines"
|
||||
type="object"
|
||||
string="Add" />
|
||||
<button class="oe_link"
|
||||
special="cancel"
|
||||
string="Cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_rma_add_lines" model="ir.actions.act_window">
|
||||
<field name="name">Add RMA Lines</field>
|
||||
<field name="res_model">rma.picking.make.lines</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_rma_add_lines_form" />
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -8,6 +8,7 @@ class RMATemplate(models.Model):
|
||||
_inherit = 'rma.template'
|
||||
|
||||
usage = fields.Selection(selection_add=[('sale_order', 'Sale Order')])
|
||||
in_to_refund_so = fields.Boolean(string='Inbound mark refund SO')
|
||||
|
||||
|
||||
class RMA(models.Model):
|
||||
|
||||
@@ -6,7 +6,7 @@ class TestRMASale(TestRMA):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRMASale, self).setUp()
|
||||
self.template2 = self.env.ref('rma_sale.template_sale_return')
|
||||
self.template_sale_return = self.env.ref('rma_sale.template_sale_return')
|
||||
|
||||
def test_20_sale_return(self):
|
||||
self.product1.tracking = 'serial'
|
||||
@@ -27,18 +27,18 @@ class TestRMASale(TestRMA):
|
||||
|
||||
# Try to RMA item not delivered yet
|
||||
rma = self.env['rma.rma'].create({
|
||||
'template_id': self.template2.id,
|
||||
'template_id': self.template_sale_return.id,
|
||||
'partner_id': self.partner1.id,
|
||||
'partner_shipping_id': self.partner1.id,
|
||||
'sale_order_id': order.id,
|
||||
})
|
||||
self.assertEqual(rma.state, 'draft')
|
||||
rma_line = self.env['rma.line'].create({
|
||||
wizard = self.env['rma.sale.make.lines'].create({
|
||||
'rma_id': rma.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom_id': self.product1.uom_id.id,
|
||||
'product_uom_qty': 1.0,
|
||||
})
|
||||
wizard.line_ids.product_uom_qty = 1.0
|
||||
wizard.add_lines()
|
||||
self.assertEqual(len(rma.lines), 1)
|
||||
with self.assertRaises(UserError):
|
||||
rma.action_confirm()
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- RMA Template -->
|
||||
<record id="view_rma_template_form_sale" model="ir.ui.view">
|
||||
<field name="name">rma.template.form.sale</field>
|
||||
<field name="model">rma.template</field>
|
||||
<field name="inherit_id" ref="rma.view_rma_template_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='in_procure_method']" position="after">
|
||||
<field name="in_to_refund_so" attrs="{'invisible': [('create_in_picking', '=', False)]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- RMA -->
|
||||
<record id="view_rma_rma_form_sale" model="ir.ui.view">
|
||||
<field name="name">rma.rma.form.sale</field>
|
||||
<field name="model">rma.rma</field>
|
||||
|
||||
Reference in New Issue
Block a user