[ADD] rma: new module

[UPD] Update rma.pot

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: rma-12.0/rma-12.0-rma
Translate-URL: https://translation.odoo-community.org/projects/rma-12-0/rma-12-0-rma/
This commit is contained in:
Ernesto Tejeda
2020-05-13 00:27:46 -04:00
committed by Pedro M. Baeza
parent 8d3e3c364a
commit 0122a02458
48 changed files with 7643 additions and 0 deletions

5
rma/wizard/__init__.py Normal file
View File

@@ -0,0 +1,5 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import rma_delivery
from . import rma_split
from . import stock_picking_return

102
rma/wizard/rma_delivery.py Normal file
View File

@@ -0,0 +1,102 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
import odoo.addons.decimal_precision as dp
class RmaReDeliveryWizard(models.TransientModel):
_name = 'rma.delivery.wizard'
_description = 'RMA Delivery Wizard'
rma_count = fields.Integer()
type = fields.Selection(
selection=[
('replace', 'Replace'),
('return', 'Return to customer'),
],
string="Type",
required=True,
)
product_id = fields.Many2one(
comodel_name="product.product",
string="Replace Product",
)
product_uom_qty = fields.Float(
string='Product qty',
digits=dp.get_precision('Product Unit of Measure'),
)
product_uom = fields.Many2one(
comodel_name="uom.uom",
string="Unit of measure",
)
scheduled_date = fields.Datetime(
required=True,
default=fields.Datetime.now(),
)
warehouse_id = fields.Many2one(
comodel_name="stock.warehouse",
string='Warehouse',
required=True,
)
@api.constrains('product_uom_qty')
def _check_product_uom_qty(self):
self.ensure_one()
rma_ids = self.env.context.get('active_ids')
if len(rma_ids) == 1 and self.product_uom_qty <= 0:
raise ValidationError(_('Quantity must be greater than 0.'))
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
rma_ids = self.env.context.get('active_ids')
rma = self.env['rma'].browse(rma_ids)
warehouse_id = self.env['stock.warehouse'].search(
[('company_id', '=', rma[0].company_id.id)], limit=1).id
delivery_type = self.env.context.get('rma_delivery_type')
product_id = False
if len(rma) == 1 and delivery_type == 'return':
product_id = rma.product_id.id
product_uom_qty = 0.0
if len(rma) == 1 and rma.remaining_qty > 0.0:
product_uom_qty = rma.remaining_qty
res.update(
rma_count=len(rma),
warehouse_id=warehouse_id,
type=delivery_type,
product_id=product_id,
product_uom_qty=product_uom_qty,
)
return res
@api.onchange("product_id")
def _onchange_product_id(self):
domain_product_uom = []
if self.product_id:
domain_product_uom = [
('category_id', '=', self.product_id.uom_id.category_id.id)
]
if (not self.product_uom
or self.product_id.uom_id.id != self.product_uom.id):
self.product_uom = self.product_id.uom_id
return {'domain': {'product_uom': domain_product_uom}}
def action_deliver(self):
self.ensure_one()
rma_ids = self.env.context.get('active_ids')
rma = self.env['rma'].browse(rma_ids)
if self.type == 'replace':
rma.create_replace(
self.scheduled_date,
self.warehouse_id,
self.product_id,
self.product_uom_qty,
self.product_uom,
)
elif self.type == 'return':
qty = uom = None
if self.rma_count == 1:
qty, uom = self.product_uom_qty, self.product_uom
rma.create_return(self.scheduled_date, qty, uom)

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 Tecnativa - Ernesto Tejeda
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="rma_redelivery_wizard_view_form" model="ir.ui.view">
<field name="name">rma.delivery.wizard.form</field>
<field name="model">rma.delivery.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<group>
<field name="scheduled_date"/>
<field name="warehouse_id"
attrs="{'invisible': [('type', '!=', 'replace')]}"/>
</group>
<group>
<field name="product_id"
attrs="{'invisible': ['|', ('type', '!=', 'replace'), ('rma_count', '>', 1)], 'required': [('type', '=', 'replace'), ('rma_count', '=', 1)]}"/>
<label for="product_uom_qty"
attrs="{'invisible': [('rma_count', '>', 1)]}"/>
<div class="o_row"
attrs="{'invisible': [('rma_count', '>', 1)]}">
<field name="product_uom_qty"
attrs="{'required': [('rma_count', '=', 1)]}"/>
<field name="product_uom"
groups="uom.group_uom"
attrs="{'required': [('rma_count', '=', 1)]}"/>
</div>
</group>
</group>
<field name="rma_count" invisible="1"/>
<field name="type" invisible="1"/>
<footer>
<button name="action_deliver" string="Deliver" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel" />
</footer>
</form>
</field>
</record>
<act_window id="rma_delivery_wizard_action"
name="Return to customer"
src_model="rma"
res_model="rma.delivery.wizard"
view_type="form"
view_mode="form"
key2="client_action_multi"
target="new"
multi="True"
context="{'rma_delivery_type': 'return'}"/>
</odoo>

70
rma/wizard/rma_split.py Normal file
View File

@@ -0,0 +1,70 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
import odoo.addons.decimal_precision as dp
class RmaReSplitWizard(models.TransientModel):
_name = 'rma.split.wizard'
_description = 'RMA Split Wizard'
rma_id = fields.Many2one(
comodel_name='rma',
string='RMA',
)
product_uom_qty = fields.Float(
string='Quantity to extract',
digits=dp.get_precision('Product Unit of Measure'),
required=True,
help="Quantity to extract to a new RMA."
)
product_uom = fields.Many2one(
comodel_name='uom.uom',
string='Unit of measure',
required=True,
)
_sql_constraints = [
(
'check_product_uom_qty_positive',
'CHECK(product_uom_qty > 0)',
'Quantity must be greater than 0.'
),
]
@api.model
def fields_get(self, allfields=None, attributes=None):
res = super().fields_get(allfields, attributes=attributes)
rma_id = self.env.context.get('active_id')
rma = self.env['rma'].browse(rma_id)
res['product_uom']['domain'] = [
('category_id', '=', rma.product_uom.category_id.id)
]
return res
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
rma_id = self.env.context.get('active_id')
rma = self.env['rma'].browse(rma_id)
res.update(
rma_id=rma.id,
product_uom_qty=rma.remaining_qty,
product_uom=rma.product_uom.id,
)
return res
def action_split(self):
self.ensure_one()
extracted_rma = self.rma_id.extract_quantity(
self.product_uom_qty, self.product_uom)
return {
'name': _('Extracted RMA'),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'rma',
'views': [(self.env.ref('rma.rma_view_form').id, 'form')],
'res_id': extracted_rma.id,
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 Tecnativa - Ernesto Tejeda
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="rma_split_wizard_view_form2" model="ir.ui.view">
<field name="name">rma.split.wizard.form</field>
<field name="model">rma.split.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<group>
<label for="product_uom_qty"/>
<div class="o_row">
<field name="product_uom_qty"/>
<field name="product_uom" groups="uom.group_uom"/>
</div>
</group>
</group>
<footer>
<button name="action_split" string="Split" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="rma_split_wizard_action" model="ir.actions.act_window">
<field name="name">Split RMA</field>
<field name="res_model">rma.split.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>

View File

@@ -0,0 +1,83 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class ReturnPicking(models.TransientModel):
_inherit = 'stock.return.picking'
create_rma = fields.Boolean(
string="Create RMAs"
)
picking_type_code = fields.Selection(
selection=[
('incoming', 'Vendors'),
('outgoing', 'Customers'),
('internal', 'Internal'),
],
related='picking_id.picking_type_id.code',
store=True,
readonly=True,
)
@api.onchange("create_rma")
def _onchange_create_rma(self):
if self.create_rma:
warehouse = self.picking_id.picking_type_id.warehouse_id
self.location_id = warehouse.rma_loc_id.id
rma_loc = warehouse.search([]).mapped('rma_loc_id')
rma_loc_domain = [('id', 'child_of', rma_loc.ids)]
else:
self.location_id = self.default_get(['location_id'])['location_id']
rma_loc_domain = [
'|',
('id', '=', self.picking_id.location_id.id),
('return_location', '=', True),
]
return {'domain': {'location_id': rma_loc_domain}}
def create_returns(self):
""" Override create_returns method for creating one or more
'confirmed' RMAs after return a delivery picking in case
'Create RMAs' checkbox is checked in this wizard.
New RMAs will be linked to the delivery picking as the origin
delivery and also RMAs will be linked to the returned picking
as the 'Receipt'.
"""
if self.create_rma:
# set_rma_picking_type is to override the copy() method of stock
# picking and change the default picking type to rma picking type
self_with_context = self.with_context(set_rma_picking_type=True)
res = super(ReturnPicking, self_with_context).create_returns()
partner = self.picking_id.partner_id
if not partner:
raise ValidationError(_(
"You must specify the 'Customer' in the "
"'Stock Picking' from which RMAs will be created"))
picking = self.picking_id
returned_picking = self.env['stock.picking'].browse(res['res_id'])
if hasattr(picking, 'sale_id') and picking.sale_id:
partner_invoice_id = picking.sale_id.partner_invoice_id.id
else:
partner_invoice_id = partner.address_get(
['invoice']).get('invoice', False),
for move in returned_picking.move_lines:
self.env['rma'].create({
'partner_id': partner.id,
'partner_invoice_id': partner_invoice_id,
'origin': picking.name,
'picking_id': picking.id,
'move_id': move.origin_returned_move_id.id,
'product_id': move.origin_returned_move_id.product_id.id,
'product_uom_qty': move.product_uom_qty,
'product_uom': move.product_uom.id,
'reception_move_id': move.id,
'company_id': move.company_id.id,
'location_id': move.location_dest_id.id,
'state': 'confirmed',
})
return res
else:
return super().create_returns()

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 Tecnativa - Ernesto Tejeda
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_stock_return_picking_form" model="ir.ui.view">
<field name="name">Return lines inherit RMA</field>
<field name="model">stock.return.picking</field>
<field name="inherit_id" ref="stock.view_stock_return_picking_form" />
<field name="arch" type="xml">
<xpath expr="//group[.//field[@name='product_return_moves']]" position="before">
<group name="group_rma">
<field name="create_rma"
attrs="{'invisible': [('picking_type_code', '!=', 'outgoing')]}"/>
<field name="picking_id" invisible="1"/>
<field name="picking_type_code" invisible="1"/>
</group>
</xpath>
</field>
</record>
</odoo>