mirror of
https://github.com/OCA/rma.git
synced 2025-02-16 17:11:47 +02:00
Merge pull request #45 from vauxoo-dev/8.0-squash_crm_rma_lot_mass_return_oca_vauxoo
[WIP] new module crm_rma_lot_mass_return that adds possibility to ret…
This commit is contained in:
86
crm_rma_lot_mass_return/README.rst
Normal file
86
crm_rma_lot_mass_return/README.rst
Normal file
@@ -0,0 +1,86 @@
|
||||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:alt: License: AGPL-3
|
||||
|
||||
============================
|
||||
RMA Claim Mass Return by Lot
|
||||
============================
|
||||
|
||||
This module adds possibility to return a whole lot of product from an invoice
|
||||
and create a incoming shipment for them based on serial/lot for a product or
|
||||
invoice number.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
To install this module, just select it from availables modules
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
No configuration is need for this module
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
To use this module, you need to:
|
||||
|
||||
* Go into Sales > After-Sale services > Claims
|
||||
|
||||
* A button named "Mass return from serial/lot or invoice" will appear in the
|
||||
form view when creating or editing an existing claim.
|
||||
|
||||
* Enter into the wizard and introduce serial/lot for an invoiced product or
|
||||
invoice number and press enter.
|
||||
|
||||
* A list of selectable items it will show below or next to the input box
|
||||
depending upon is introduced either invoice number or serial/lot number
|
||||
respectively. When finish adding, click on Validate button and then Ok
|
||||
to exit of wizard and continue editing the claim.
|
||||
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/145/8.0
|
||||
|
||||
|
||||
For further information, please visit:
|
||||
|
||||
* https://www.odoo.com/forum/help-1
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
* No issues are registered
|
||||
|
||||
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_lot_mass_return%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Yanina Aular <yanina.aular@vauxoo.com>
|
||||
* Osval Reyes <osval@vauxoo.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
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.
|
||||
@@ -1,9 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau, Joel Grand-Guillaume
|
||||
# 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
|
||||
@@ -19,4 +21,6 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import wizard
|
||||
|
||||
from . import models
|
||||
from . import wizards
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau, Joel Grand-Guillaume
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: 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
|
||||
@@ -20,31 +23,29 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
{'name': 'RMA Claims Mass Return by Lot',
|
||||
'version': '1.0',
|
||||
'category': 'Generic Modules/CRM & SRM',
|
||||
'depends': ['crm_claim_rma'
|
||||
],
|
||||
'author': "Akretion,Odoo Community Association (OCA)",
|
||||
'license': 'AGPL-3',
|
||||
'website': 'http://www.akretion.com',
|
||||
'description': """
|
||||
RMA Claim Mass Return by Lot
|
||||
============================
|
||||
|
||||
This module adds possibility to return a whole lot of product from a Claim
|
||||
and create a incoming shipment for them.
|
||||
|
||||
|
||||
WARNING: This module is currently not yet completely debugged and is waiting his author to be.
|
||||
|
||||
""",
|
||||
'images': [],
|
||||
'demo': [],
|
||||
'data': [
|
||||
'wizard/returned_lines_from_serial_wizard_view.xml',
|
||||
'crm_rma_view.xml',
|
||||
],
|
||||
'installable': False,
|
||||
'application': True,
|
||||
{
|
||||
'name': 'RMA Claims Mass Return by Lot',
|
||||
'version': '8.0.1.0.0',
|
||||
'category': 'Generic Modules/CRM & SRM',
|
||||
'author': 'Vauxoo,Akretion,Odoo Community Association (OCA)',
|
||||
'license': 'AGPL-3',
|
||||
'website': 'http://www.vauxoo.com, http://www.akretion.com',
|
||||
'depends': [
|
||||
'crm_claim_rma',
|
||||
'crm_rma_prodlot_invoice',
|
||||
'crm_rma_prodlot_supplier',
|
||||
],
|
||||
'data': [
|
||||
'wizards/returned_lines_from_serial_wizard.xml',
|
||||
'views/crm_claim.xml',
|
||||
'templates/search_view.xml'
|
||||
],
|
||||
'demo': [
|
||||
'demo/stock_production_lot.xml',
|
||||
'demo/purchase_order.xml',
|
||||
'demo/sale_order.xml',
|
||||
'demo/transfer_details.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="crm_claim_rma_form_view">
|
||||
<field name="name">CRM - Claim product return Form</field>
|
||||
<field name="model">crm.claim</field>
|
||||
<field name="inherit_id" ref="crm_claim_rma.crm_claim_rma_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[@string='Product Return']/group/group[2]" position="inside">
|
||||
<button name="%(action_create_return_serial)d" string="Mass return from serial/lot" states="draft,open" type="action" target="new"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
69
crm_rma_lot_mass_return/demo/purchase_order.xml
Normal file
69
crm_rma_lot_mass_return/demo/purchase_order.xml
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- Purchase Order -->
|
||||
|
||||
<record id="po_wizard_rma_1" model="purchase.order">
|
||||
<field name="name">POWIZARDCLAIM001</field>
|
||||
<field name="date_order">2015-05-08 18:17:05</field>
|
||||
<field name="invoice_method">order</field>
|
||||
<field name="partner_id" ref="base.res_partner_21"/>
|
||||
<field name="currency_id" ref="base.EUR"/>
|
||||
<field name="pricelist_id" ref="purchase.list0"/>
|
||||
<field name="location_id" ref="stock.stock_location_stock"/>
|
||||
</record>
|
||||
|
||||
<!-- Purchase Order Lines-->
|
||||
|
||||
<record id="po_wizard_rma_1_line_1" model="purchase.order.line">
|
||||
<field name="name">POWIZARDCLAIM001 Line 1</field>
|
||||
<field name="order_id" ref="po_wizard_rma_1"/>
|
||||
<field name="product_id" ref="product.product_product_38"/>
|
||||
<field name="product_qty">10</field>
|
||||
<field name="price_unit">60.0</field>
|
||||
<field name="date_planned">2015-05-08</field>
|
||||
</record>
|
||||
|
||||
<record id="po_wizard_rma_1_line_2" model="purchase.order.line">
|
||||
<field name="name">POWIZARDCLAIM001 Line 2</field>
|
||||
<field name="order_id" ref="po_wizard_rma_1"/>
|
||||
<field name="product_id" ref="product.product_product_39"/>
|
||||
<field name="product_qty">10</field>
|
||||
<field name="price_unit">66.0</field>
|
||||
<field name="date_planned">2015-05-08</field>
|
||||
</record>
|
||||
|
||||
<record id="po_wizard_rma_1_line_3" model="purchase.order.line">
|
||||
<field name="name">POWIZARDCLAIM001 Line 3</field>
|
||||
<field name="order_id" ref="po_wizard_rma_1"/>
|
||||
<field name="product_id" ref="product.product_product_6"/>
|
||||
<field name="product_qty">10</field>
|
||||
<field name="price_unit">800.0</field>
|
||||
<field name="date_planned">2015-05-08</field>
|
||||
</record>
|
||||
|
||||
<record id="po_wizard_rma_1_line_4" model="purchase.order.line">
|
||||
<field name="name">POWIZARDCLAIM001 Line 4</field>
|
||||
<field name="order_id" ref="po_wizard_rma_1"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_qty">7</field>
|
||||
<field name="price_unit">1299.0</field>
|
||||
<field name="date_planned">2015-05-08</field>
|
||||
</record>
|
||||
|
||||
<!-- Confirm Purchase Order, (Invoice and Picking is created automatically) -->
|
||||
|
||||
<workflow action="purchase_confirm"
|
||||
model="purchase.order"
|
||||
ref="po_wizard_rma_1"/>
|
||||
|
||||
<workflow action="purchase_approve"
|
||||
model="purchase.order"
|
||||
ref="po_wizard_rma_1"/>
|
||||
|
||||
<workflow action="invoice_open" model="account.invoice">
|
||||
<value eval="obj(ref('po_wizard_rma_1')).invoice_ids[0].id" model="purchase.order"/>
|
||||
</workflow>
|
||||
</data>
|
||||
</openerp>
|
||||
67
crm_rma_lot_mass_return/demo/sale_order.xml
Normal file
67
crm_rma_lot_mass_return/demo/sale_order.xml
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="so_wizard_rma_1" model="sale.order">
|
||||
<field name="name">SOWIZARDCLAIM001</field>
|
||||
<field name="date_order">2015-05-08 18:17:05</field>
|
||||
<field name="partner_id" ref="base.res_partner_12"/>
|
||||
<field name="currency_id" ref="base.EUR"/>
|
||||
<field name="pricelist_id" ref="product.list0"/>
|
||||
</record>
|
||||
|
||||
<record id="so_wizard_rma_1_line_1" model="sale.order.line">
|
||||
<field name="name">SOWIZARDCLAIM001 Line 1</field>
|
||||
<field name="order_id" ref="so_wizard_rma_1"/>
|
||||
<field name="product_id" ref="product.product_product_38"/>
|
||||
<field name="product_uom_qty">1</field>
|
||||
<field name="price_unit">65.0</field>
|
||||
</record>
|
||||
|
||||
<record id="so_wizard_rma_1_line_2" model="sale.order.line">
|
||||
<field name="name">SOWIZARDCLAIM001 Line 2</field>
|
||||
<field name="order_id" ref="so_wizard_rma_1"/>
|
||||
<field name="product_id" ref="product.product_product_39"/>
|
||||
<field name="product_uom_qty">2</field>
|
||||
<field name="price_unit">66.0</field>
|
||||
</record>
|
||||
|
||||
<record id="so_wizard_rma_1_line_3" model="sale.order.line">
|
||||
<field name="name">SOWIZARDCLAIM001 Line 3</field>
|
||||
<field name="order_id" ref="so_wizard_rma_1"/>
|
||||
<field name="product_id" ref="product.product_product_6"/>
|
||||
<field name="product_uom_qty">1</field>
|
||||
<field name="price_unit">800.0</field>
|
||||
</record>
|
||||
|
||||
<record id="so_wizard_rma_1_line_4" model="sale.order.line">
|
||||
<field name="name">SOWIZARDCLAIM001 Line 4</field>
|
||||
<field name="order_id" ref="so_wizard_rma_1"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_qty">5</field>
|
||||
<field name="price_unit">1299.0</field>
|
||||
</record>
|
||||
|
||||
<workflow action="order_confirm" model="sale.order" ref="so_wizard_rma_1"/>
|
||||
|
||||
<workflow action="manual_invoice" model="sale.order" ref="so_wizard_rma_1" uid="base.user_root"/>
|
||||
|
||||
<workflow action="invoice_open" model="account.invoice">
|
||||
<value eval="obj(ref('so_wizard_rma_1')).invoice_ids[0].id" model="sale.order"/>
|
||||
</workflow>
|
||||
|
||||
<function model="account.invoice" name="pay_and_reconcile">
|
||||
<!-- ids = --> <value eval="obj(ref('so_wizard_rma_1')).invoice_ids[0].id" model="sale.order"/>
|
||||
<!-- amount = --> <value eval="30000"/>
|
||||
<!-- account_id = --> <value eval="ref('account.cash')"/>
|
||||
<!-- period_id = --> <value eval="ref('account.period_10')"/>
|
||||
<!-- journal_id = --> <value eval="ref('account.bank_journal')"/>
|
||||
<!-- writeoff_acc_id = --> <value eval="ref('account.cash')"/>
|
||||
<!-- writeoff_period_id = --> <value eval="ref('account.period_10')"/>
|
||||
<!-- writeoff_journal_id = --> <value eval="ref('account.bank_journal')"/>
|
||||
<!-- context = --> <value eval="{}"/>
|
||||
<!-- name = --> <value eval="str('Payment WIzard RMA')"/>
|
||||
</function>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
37
crm_rma_lot_mass_return/demo/stock_production_lot.xml
Normal file
37
crm_rma_lot_mass_return/demo/stock_production_lot.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="lot_purchase_wizard_rma_item_1" model="stock.production.lot">
|
||||
<field name="name">MAC0001</field>
|
||||
<field name="ref">MAC0001</field>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
</record>
|
||||
|
||||
<record id="lot_purchase_wizard_rma_item_2" model="stock.production.lot">
|
||||
<field name="name">MAC0002</field>
|
||||
<field name="ref">MAC0002</field>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
</record>
|
||||
|
||||
<record id="lot_purchase_wizard_rma_item_3" model="stock.production.lot">
|
||||
<field name="name">MAC0003</field>
|
||||
<field name="ref">MAC0003</field>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
</record>
|
||||
|
||||
<record id="lot_purchase_wizard_rma_item_4" model="stock.production.lot">
|
||||
<field name="name">MAC0004</field>
|
||||
<field name="ref">MAC0004</field>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
</record>
|
||||
|
||||
<record id="lot_purchase_wizard_rma_item_5" model="stock.production.lot">
|
||||
<field name="name">IPAD0001</field>
|
||||
<field name="ref">IPAD0001</field>
|
||||
<field name="product_id" ref="product.product_product_6"/>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
196
crm_rma_lot_mass_return/demo/transfer_details.xml
Normal file
196
crm_rma_lot_mass_return/demo/transfer_details.xml
Normal file
@@ -0,0 +1,196 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<!--Transfer of Products in the Picking of Purchase Order -->
|
||||
|
||||
<record id="transfer_purchase_wizard_rma" model="stock.transfer_details">
|
||||
<field name="picking_id" model="stock.picking" search="[('origin', '=', 'POWIZARDCLAIM001')]"/>
|
||||
<field name="picking_source_location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="picking_destination_location_id" ref="stock.stock_location_stock"/>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Transfer Detail Items of Product Transfer -->
|
||||
|
||||
<record id="transfer_purchase_wizard_rma_item_1" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_purchase_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_1"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_purchase_wizard_rma_item_2" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_purchase_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_2"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_purchase_wizard_rma_item_3" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_purchase_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_3"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_purchase_wizard_rma_item_4" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_purchase_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_4"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_purchase_wizard_rma_item_5" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_purchase_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_6"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_5"/>
|
||||
</record>
|
||||
|
||||
<!-- two MAC without lot -->
|
||||
<record id="transfer_purchase_wizard_rma_item_6" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_purchase_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">2</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_stock"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="transfer_purchase_wizard_rma_item_7" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_purchase_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_39"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_stock"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="transfer_purchase_wizard_rma_item_8" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_purchase_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_39"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_stock"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="transfer_purchase_wizard_rma_item_9" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_purchase_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_38"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_stock"/>
|
||||
</record>
|
||||
|
||||
<!-- Make transfer of product -->
|
||||
|
||||
<function model="stock.transfer_details"
|
||||
name="do_detailed_transfer" eval="[ref('transfer_purchase_wizard_rma')]"/>
|
||||
|
||||
|
||||
|
||||
<!-- Transfer of Products in the Picking of Purchase Order 2 -->
|
||||
|
||||
<record id="transfer_sale_wizard_rma" model="stock.transfer_details">
|
||||
<field name="picking_id" model="stock.picking" search="[('origin', '=', 'SOWIZARDCLAIM001')]"/>
|
||||
<field name="picking_source_location_id" ref="stock.stock_location_stock"/>
|
||||
<field name="picking_destination_location_id" ref="stock.stock_location_customers"/>
|
||||
</record>
|
||||
|
||||
<!-- Transfer Detail Items Part 2 of Product Transfer -->
|
||||
|
||||
<record id="transfer_sale_wizard_rma_item_1" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_sale_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_38"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_customers"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_sale_wizard_rma_item_2" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_sale_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_39"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">2</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_customers"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_sale_wizard_rma_item_3" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_sale_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_6"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_customers"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_5"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_sale_wizard_rma_item_4" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_sale_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_customers"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_1"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_sale_wizard_rma_item_5" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_sale_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_customers"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_2"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_sale_wizard_rma_item_6" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_sale_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_customers"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_3"/>
|
||||
</record>
|
||||
|
||||
<record id="transfer_sale_wizard_rma_item_7" model="stock.transfer_details_items">
|
||||
<field name="transfer_id" ref="transfer_sale_wizard_rma"/>
|
||||
<field name="product_id" ref="product.product_product_8"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="quantity">1</field>
|
||||
<field name="sourceloc_id" ref="stock.stock_location_stock"/>
|
||||
<field name="destinationloc_id" ref="stock.stock_location_customers"/>
|
||||
<field name="lot_id" ref="lot_purchase_wizard_rma_item_4"/>
|
||||
</record>
|
||||
|
||||
<!-- Make transfer of product -->
|
||||
|
||||
<function model="stock.transfer_details"
|
||||
name="do_detailed_transfer" eval="[ref('transfer_sale_wizard_rma')]"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,13 +1,13 @@
|
||||
# Translation of OpenERP Server.
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * crm_rma_lot_mass_return
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 7.0\n"
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-11-15 13:30+0000\n"
|
||||
"PO-Revision-Date: 2013-11-15 13:30+0000\n"
|
||||
"POT-Creation-Date: 2015-10-16 03:32+0000\n"
|
||||
"PO-Revision-Date: 2015-10-16 03:32+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,52 +16,160 @@ msgstr ""
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:crm.claim:0
|
||||
msgid "Mass return from serial/lot"
|
||||
#. openerp-web
|
||||
#: code:addons/crm_rma_lot_mass_return/static/src/js/barcode_text.js:90
|
||||
#, python-format
|
||||
msgid "-->"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned_lines_from_serial.wizard:0
|
||||
msgid "Claim short description"
|
||||
#: model:ir.model,name:crm_rma_lot_mass_return.model_crm_claim
|
||||
msgid "Claim"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned_lines_from_serial.wizard:0
|
||||
msgid "Select serial numbers to create"
|
||||
#: field:returned.lines.from.serial.wizard,create_uid:0
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: model:ir.actions.act_window,name:crm_rma_lot_mass_return.action_create_return_serial
|
||||
msgid "action_create_return_serial"
|
||||
#: field:returned.lines.from.serial.wizard,create_date:0
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,scan_data:0
|
||||
msgid "Field used to load and show the products"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,lines_id:0
|
||||
msgid "Field used to load the ids of invoice lines in invoices writed"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,scaned_data:0
|
||||
msgid "Field used to load the ids of products loaded"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,lines_list_id:0
|
||||
msgid "Field used to show the current status of the lots loaded"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,current_status:0
|
||||
msgid "Field used to show the current status of the product loaded(Name and quantity)"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,id:0
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,lines_id:0
|
||||
msgid "Invoice Lines to Select"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,write_uid:0
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,write_date:0
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,lines_list_id:0
|
||||
msgid "Lots selected"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:crm.claim:crm_rma_lot_mass_return.crm_claim_rma_form_view_meta
|
||||
msgid "Mass return from serial/lot or invoice"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#. openerp-web
|
||||
#: code:addons/crm_rma_lot_mass_return/static/src/js/barcode_text.js:93
|
||||
#, python-format
|
||||
msgid "Ok"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,scan_data:0
|
||||
#: field:returned.lines.from.serial.wizard,scaned_data:0
|
||||
msgid "Products"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: code:addons/crm_rma_lot_mass_return/wizards/returned_lines_from_serial.py:141
|
||||
#, python-format
|
||||
msgid "Search Product"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,current_status:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: code:addons/crm_rma_lot_mass_return/wizards/returned_lines_from_serial.py:299
|
||||
#, python-format
|
||||
msgid "The following Serial/Lot numbers were not added, because all of them (listed below) are currently in use:\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: code:addons/crm_rma_lot_mass_return/wizards/returned_lines_from_serial.py:221
|
||||
#, python-format
|
||||
msgid "The product or invoice %s was not found"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:crm.claim:crm_rma_lot_mass_return.crm_claim_rma_form_view_meta
|
||||
msgid "True"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "Validate the actual picking, it will execute all the validations and the inventory will be affected"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: model:ir.model,name:crm_rma_lot_mass_return.model_returned_lines_from_serial_wizard
|
||||
msgid "Wizard to create product return lines from serial numbers"
|
||||
msgid "Wizard to create product return lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned_lines_from_serial.wizard:0
|
||||
msgid "Quantity returned"
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "Write the Invoice Number to search the products in lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned_lines_from_serial.wizard:0
|
||||
msgid "Save and close"
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "Write the Serial/Lot Number to search the product"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned_lines_from_serial.wizard:0
|
||||
msgid "Save and new"
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "You add new returns in claim, are you sure?."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned_lines_from_serial.wizard:0
|
||||
msgid "Cancel"
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "You should use this windows on this way."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned_lines_from_serial.wizard:0
|
||||
msgid "Serial / Lot Number"
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "_Validate"
|
||||
msgstr ""
|
||||
|
||||
|
||||
181
crm_rma_lot_mass_return/i18n/es.po
Normal file
181
crm_rma_lot_mass_return/i18n/es.po
Normal file
@@ -0,0 +1,181 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * crm_rma_lot_mass_return
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-07-21 01:59+0000\n"
|
||||
"PO-Revision-Date: 2015-07-21 01:59+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#. openerp-web
|
||||
#: code:addons/crm_rma_lot_mass_return/static/src/js/barcode_text.js:89
|
||||
#, python-format
|
||||
msgid "-->"
|
||||
msgstr "-->"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: model:ir.model,name:crm_rma_lot_mass_return.model_crm_claim
|
||||
msgid "Claim"
|
||||
msgstr "Reclamo"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,create_uid:0
|
||||
msgid "Created by"
|
||||
msgstr "Creado por"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,create_date:0
|
||||
msgid "Created on"
|
||||
msgstr "Creado en"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: code:addons/crm_rma_lot_mass_return/wizards/returned_lines_from_serial.py:111
|
||||
#, python-format
|
||||
msgid "Error!"
|
||||
msgstr "Error!"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,scan_data:0
|
||||
msgid "Field used to load and show the products"
|
||||
msgstr "Campo usado para cargar y ver los productos"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,lines_id:0
|
||||
msgid "Field used to load the ids of invoice lines in invoices writed"
|
||||
msgstr "Campo usado para cargar los ids de las líneas de factura en facturas editadas"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,scaned_data:0
|
||||
msgid "Field used to load the ids of products loaded"
|
||||
msgstr "Campo usado para cargar los ids de los productos cargados"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,lines_list_id:0
|
||||
msgid "Field used to show the current status of the invoice lines loaded"
|
||||
msgstr "Campo usado para visualizar el estado actual de las línea de factura cargadas"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: help:returned.lines.from.serial.wizard,current_status:0
|
||||
msgid "Field used to show the current status of the product loaded(Name and quantity)"
|
||||
msgstr "Campo usado para visualizar el estado actual de los productos cargados (Nombre y cantidad)"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,id:0
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,lines_list_id:0
|
||||
msgid "Invoice Lines selected"
|
||||
msgstr "Líneas de factura seleccionadas"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,lines_id:0
|
||||
msgid "Invoice Lines to Select"
|
||||
msgstr "Líneas de factura a seleccionar"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,write_uid:0
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última actualización hecha por"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,write_date:0
|
||||
msgid "Last Updated on"
|
||||
msgstr "Última actualización hecha en"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:crm.claim:crm_rma_lot_mass_return.crm_claim_rma_form_view_meta
|
||||
msgid "Add claim lines using serial or invoice number"
|
||||
msgstr "Agregar devoluciones usando número de serial o de factura"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#. openerp-web
|
||||
#: code:addons/crm_rma_lot_mass_return/static/src/js/barcode_text.js:90
|
||||
#, python-format
|
||||
msgid "Ok"
|
||||
msgstr "Ok"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr "Socio"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,scan_data:0
|
||||
#: field:returned.lines.from.serial.wizard,scaned_data:0
|
||||
msgid "Products"
|
||||
msgstr "Productos"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: code:addons/crm_rma_lot_mass_return/wizard/returned_lines_from_serial.py:213
|
||||
#, python-format
|
||||
msgid "Search Product"
|
||||
msgstr "Buscar producto"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: field:returned.lines.from.serial.wizard,current_status:0
|
||||
msgid "Status"
|
||||
msgstr "Estado"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: code:addons/crm_rma_lot_mass_return/wizard/returned_lines_from_serial.py:285
|
||||
#, python-format
|
||||
msgid "The product or invoice %s was not found"
|
||||
msgstr "El producto o factura %s no fué encontrado"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: code:addons/crm_rma_lot_mass_return/wizard/returned_lines_from_serial.py:112
|
||||
#, python-format
|
||||
msgid "There is no warehouse for the current user's company."
|
||||
msgstr "No existe un almacén para la compañia del usuario actual"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "Validate the actual picking, it will execute all the validations and the inventory will be affected"
|
||||
msgstr "Validar el albarán actual, ejecutará todas las validaciones y el inventario será afectado."
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: model:ir.model,name:crm_rma_lot_mass_return.model_returned_lines_from_serial_wizard
|
||||
msgid "Wizard to create product return lines from serial numbers"
|
||||
msgstr "Wizard para crear líneas de devolución de productos usando el número de serie o lote"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "Write the Invoice Number to search the products in lines"
|
||||
msgstr "Escribir el número de factura para buscar los productos en las líneas"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "Write the Serial/Lot Number to search the product"
|
||||
msgstr "Escribir el número de serie o lote para buscar el producto."
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "You are about to add new lines to the claim, Do you want to continue?."
|
||||
msgstr "Se agregarán nuevas líneas a la reclamación, ¿Desea continuar?"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "You should use this windows on this way."
|
||||
msgstr "Deberías usar ésta ventana"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: view:returned.lines.from.serial.wizard:crm_rma_lot_mass_return.view_enter_product
|
||||
msgid "Add items to the claim"
|
||||
msgstr "Añadir productos a la reclamación"
|
||||
|
||||
#. module: crm_rma_lot_mass_return
|
||||
#: code:addons/crm_rma_lot_mass_return/wizards/returned_lines_from_serial.py:585
|
||||
#, python-format
|
||||
msgid "The following Serial/Lot numbers won't be added, because all of them (listed below) are currently in use:\n\n %s"
|
||||
msgstr "los siguientes números de seriales no pueden ser agregados, porque todos ellos (listados abajo) están actualmente en uso:\n\n %s"
|
||||
16
crm_rma_lot_mass_return/i18n/es_MX.po
Normal file
16
crm_rma_lot_mass_return/i18n/es_MX.po
Normal file
@@ -0,0 +1,16 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * crm_rma_lot_mass_return
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-07-17 19:54+0000\n"
|
||||
"PO-Revision-Date: 2015-07-17 19:54+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
16
crm_rma_lot_mass_return/i18n/es_PA.po
Normal file
16
crm_rma_lot_mass_return/i18n/es_PA.po
Normal file
@@ -0,0 +1,16 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * crm_rma_lot_mass_return
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-07-17 19:54+0000\n"
|
||||
"PO-Revision-Date: 2015-07-17 19:54+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
16
crm_rma_lot_mass_return/i18n/es_VE.po
Normal file
16
crm_rma_lot_mass_return/i18n/es_VE.po
Normal file
@@ -0,0 +1,16 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * crm_rma_lot_mass_return
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-07-17 19:54+0000\n"
|
||||
"PO-Revision-Date: 2015-07-17 19:54+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
22
crm_rma_lot_mass_return/models/__init__.py
Normal file
22
crm_rma_lot_mass_return/models/__init__.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Author: Osval Reyes, Yanina Aular
|
||||
#
|
||||
# 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 crm_claim
|
||||
58
crm_rma_lot_mass_return/models/crm_claim.py
Normal file
58
crm_rma_lot_mass_return/models/crm_claim.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Author: Osval Reyes, Yanina Aular
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import api, models
|
||||
|
||||
|
||||
class CrmClaim(models.Model):
|
||||
|
||||
_inherit = 'crm.claim'
|
||||
|
||||
@api.model
|
||||
def _get_stock_moves_with_code(self, code='incoming'):
|
||||
"""
|
||||
@code: Type of operation code.
|
||||
Returns all stock_move with filtered by type of
|
||||
operation.
|
||||
"""
|
||||
stockmove = self.env['stock.move']
|
||||
receipts = self.env['stock.picking.type']
|
||||
|
||||
spt_receipts = receipts.search([('code',
|
||||
'=',
|
||||
code)])
|
||||
spt_receipts = [spt.id for spt in spt_receipts]
|
||||
sm_receipts = stockmove.search([('picking_type_id',
|
||||
'in',
|
||||
spt_receipts)])
|
||||
return sm_receipts
|
||||
|
||||
@api.multi
|
||||
def render_metasearch_view(self):
|
||||
context = self._context.copy()
|
||||
context.update({
|
||||
'active_model': self._name,
|
||||
'active_ids': self.ids,
|
||||
'active_id': self.id or False,
|
||||
})
|
||||
wizard = self.env['returned.lines.from.serial.wizard'].\
|
||||
with_context(context).create({})
|
||||
return wizard.render_metasearch_view()
|
||||
115
crm_rma_lot_mass_return/static/src/js/barcode_text.js
Normal file
115
crm_rma_lot_mass_return/static/src/js/barcode_text.js
Normal file
@@ -0,0 +1,115 @@
|
||||
openerp.crm_rma_lot_mass_return = function(openerp) {
|
||||
var _t = openerp.web._t,
|
||||
_lt = openerp.web._lt;
|
||||
var QWeb = openerp.web.qweb;
|
||||
/*
|
||||
This widget is suposed to be used only in places where you need to load several
|
||||
barcodes at same time. In order to save locally information and trigger save
|
||||
data "ala onchange" but without lose the focus.
|
||||
*/
|
||||
openerp.web.form.BarcodeText = openerp.web.form.FieldText.extend({
|
||||
events: {
|
||||
'keyup': function(e) {
|
||||
if (e.which === $.ui.keyCode.ENTER) {
|
||||
this.store_dom_value();
|
||||
e.stopPropagation();
|
||||
|
||||
}
|
||||
},
|
||||
'keypress': function(e) {
|
||||
if (e.which === $.ui.keyCode.ENTER) {
|
||||
this.store_dom_value();
|
||||
e.stopPropagation();
|
||||
}
|
||||
},
|
||||
'change textarea': function(e) {
|
||||
this.store_dom_value();
|
||||
e.stopPropagation();
|
||||
$('textarea[name="scan_data"]').focus();
|
||||
$('textarea[name="scan_data"]').trigger('focus');
|
||||
|
||||
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
openerp.web.form.ChangeFocus = openerp.web.form.FieldChar.extend({
|
||||
|
||||
events: {
|
||||
'keyup': function(e) {
|
||||
if (e.which === $.ui.keyCode.ENTER) {
|
||||
$('textarea[name="scan_data"]').focus();
|
||||
this.store_dom_value();
|
||||
e.stopPropagation();
|
||||
|
||||
}
|
||||
},
|
||||
'keypress': function(e) {
|
||||
if (e.which === 0 || e.which === $.ui.keyCode.TAB) {
|
||||
$('textarea[name="scan_data"]').focus();
|
||||
this.store_dom_value();
|
||||
e.stopPropagation();
|
||||
}
|
||||
},
|
||||
'change input': function(e) {
|
||||
this.store_dom_value();
|
||||
e.stopPropagation();
|
||||
$('.packing_cache_button').click(function(e) {
|
||||
$('body').off("keypress");
|
||||
});
|
||||
$('body').keypress(function(p) {
|
||||
if ($._data($('body')[0], 'events').keypress.length > 1) {
|
||||
$._data($('body')[0], 'events').keypress.pop();
|
||||
|
||||
}
|
||||
var search = p.target.parentElement.className.search('pack_search');
|
||||
if (p.target.name != 'scan_data' && search < 0 && p.keyCode === $.ui.keyCode.ENTER){
|
||||
playAlert.volume(0.9);
|
||||
playAlert('purr');
|
||||
}
|
||||
});
|
||||
$('textarea[name="scan_data"]').focus();
|
||||
$('textarea[name="scan_data"]').trigger('focus');
|
||||
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
openerp.web.FormView.include({
|
||||
on_processed_onchange: function(result){
|
||||
try {
|
||||
var result2 = result;
|
||||
if (!_.isEmpty(result2.warning) && this.model == 'returned.lines.from.serial.wizard') {
|
||||
playAlert.volume(0.9);
|
||||
playAlert('purr');
|
||||
new openerp.web.Dialog(this, {
|
||||
size: 'medium',
|
||||
title: result2.warning.title,
|
||||
buttons: [{
|
||||
text: _t("-->"),
|
||||
click: function() {}
|
||||
}, {
|
||||
text: _t("Ok"),
|
||||
click: function() {
|
||||
this.parents('.modal').modal('hide');
|
||||
}
|
||||
}]
|
||||
}, QWeb.render("CrashManager.warning", result2.warning)).open();
|
||||
|
||||
$("span:contains('-->')").focus();
|
||||
} else {
|
||||
this._super.apply(this, arguments);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
openerp.webclient.crashmanager.show_message(e);
|
||||
return $.Deferred().reject();
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
});
|
||||
openerp.web.form.widgets.add('barcode_text', 'openerp.web.form.BarcodeText');
|
||||
openerp.web.form.widgets.add('change_focus', 'openerp.web.form.ChangeFocus');
|
||||
};
|
||||
11
crm_rma_lot_mass_return/templates/search_view.xml
Normal file
11
crm_rma_lot_mass_return/templates/search_view.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<template id="assets_backend" name="search_product assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/crm_rma_lot_mass_return/static/lib/alert.js"></script>
|
||||
<script type="text/javascript" src="/crm_rma_lot_mass_return/static/src/js/barcode_text.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
25
crm_rma_lot_mass_return/tests/__init__.py
Normal file
25
crm_rma_lot_mass_return/tests/__init__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Author: Osval Reyes,
|
||||
# Yanina Aular
|
||||
#
|
||||
# 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_lot_mass_return
|
||||
from . import test_crm_rma_lot_mass_return_2
|
||||
from . import test_constrains
|
||||
48
crm_rma_lot_mass_return/tests/test_constrains.py
Normal file
48
crm_rma_lot_mass_return/tests/test_constrains.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Author: Yanina Aular
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
from openerp.exceptions import ValidationError
|
||||
|
||||
|
||||
class TestConstrains(TransactionCase):
|
||||
|
||||
"""
|
||||
- The product in claim.line.wizard must be the same
|
||||
that product of invoice line
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestConstrains, self).setUp()
|
||||
self.claim_line_wizard = self.env['claim.line.wizard']
|
||||
|
||||
def test_product_constrain(self):
|
||||
|
||||
msg = "The product of the invoice .* is not same that product .*"
|
||||
with self.assertRaisesRegexp(ValidationError, msg):
|
||||
self.claim_line_wizard.\
|
||||
create({
|
||||
'product_id': self.env.ref('product.'
|
||||
'product_product_8').id,
|
||||
'invoice_line_id':
|
||||
self.env.ref('account.demo_invoice_0_'
|
||||
'line_rpanrearpanelshe0').id,
|
||||
})
|
||||
199
crm_rma_lot_mass_return/tests/test_crm_rma_lot_mass_return.py
Normal file
199
crm_rma_lot_mass_return/tests/test_crm_rma_lot_mass_return.py
Normal file
@@ -0,0 +1,199 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Author: Osval Reyes,
|
||||
# Yanina Aular
|
||||
#
|
||||
# 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 datetime import date
|
||||
from openerp.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestCrmRmaLotMassReturn(TransactionCase):
|
||||
|
||||
"""
|
||||
Test cases for CRM RMA Lot Mass Return Module
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestCrmRmaLotMassReturn, self).setUp()
|
||||
self.metasearch_wizard = self.env['returned.lines.from.serial.wizard']
|
||||
self.partner_id = self.env['res.partner'].browse(
|
||||
self.ref('base.res_partner_2'))
|
||||
self.invoice_id, self.lot_ids = self.create_sale_invoice()
|
||||
self.claim_id = self.env['crm.claim'].\
|
||||
create({
|
||||
'name': 'Test',
|
||||
'claim_type': self.ref('crm_claim_type.'
|
||||
'crm_claim_type_customer'),
|
||||
'partner_id': self.invoice_id.partner_id.id,
|
||||
'pick': True
|
||||
})
|
||||
|
||||
def create_sale_order(self, order_policy='manual'):
|
||||
sale_order_id = self.env['sale.order'].create({
|
||||
'partner_id': self.partner_id.id,
|
||||
'note': 'Sale Order Test',
|
||||
'order_policy': order_policy,
|
||||
'payment_term': self.ref('account.account_payment_term'),
|
||||
'order_line': [(0, 0, {
|
||||
'name': 'Test',
|
||||
'product_id': self.ref('product.product_product_8'),
|
||||
'product_uom_qty': 2
|
||||
})]
|
||||
})
|
||||
|
||||
sale_order_id.action_button_confirm()
|
||||
|
||||
return sale_order_id
|
||||
|
||||
def test_01_render_metasearch_view(self):
|
||||
res = self.claim_id.render_metasearch_view()
|
||||
self.assertEqual(res['res_model'], self.metasearch_wizard._name)
|
||||
|
||||
def test_02_load_products(self):
|
||||
|
||||
wizard_id = self.metasearch_wizard.with_context({
|
||||
'active_model': self.claim_id._name,
|
||||
'active_id': self.claim_id.id,
|
||||
'active_ids': [self.claim_id.id]
|
||||
}).create({})
|
||||
|
||||
# Get ids for invoice lines
|
||||
lines_list_id = wizard_id.onchange_load_products(
|
||||
self.invoice_id.number +
|
||||
'*5*description here' + '\n' + self.lot_ids[0].name,
|
||||
[(6, 0, [])])
|
||||
|
||||
lines_list_id = lines_list_id['domain']['lines_list_id'][0][2]
|
||||
|
||||
option_ids = wizard_id.onchange_load_products(
|
||||
self.invoice_id.number, [(6, 0, [])])['value']['option_ids'][0][2]
|
||||
|
||||
wizard_id.option_ids = option_ids
|
||||
wizard_id.lines_list_id = [(6, 0, lines_list_id)]
|
||||
|
||||
# the invoice lines are two
|
||||
self.assertEqual(len(lines_list_id), 2)
|
||||
|
||||
# Validate it has exactly as much records as the taken invoice has
|
||||
self.assertEqual(len(lines_list_id),
|
||||
int(self.invoice_id.invoice_line.quantity))
|
||||
|
||||
wizard_id._set_message()
|
||||
|
||||
wizard_id.add_claim_lines()
|
||||
|
||||
# Claim record it must have same line count as the invoice
|
||||
qty = 0
|
||||
for inv_line in self.invoice_id.invoice_line:
|
||||
qty += inv_line.quantity
|
||||
self.assertEqual(len(self.claim_id.claim_line_ids),
|
||||
int(qty))
|
||||
|
||||
def sale_validate_invoice(self, sale):
|
||||
|
||||
sale_advance_obj = self.env['sale.advance.payment.inv']
|
||||
|
||||
context = {
|
||||
'active_model': 'sale.order',
|
||||
'active_ids': [sale.id],
|
||||
'active_id': sale.id,
|
||||
}
|
||||
|
||||
wizard_invoice_id = sale_advance_obj.with_context(context).create({
|
||||
'advance_payment_method': 'all',
|
||||
})
|
||||
|
||||
wizard_invoice_id.with_context(context).create_invoices()
|
||||
|
||||
invoice_id = sale.invoice_ids[0]
|
||||
invoice_id.signal_workflow('invoice_open')
|
||||
|
||||
# check if invoice is open
|
||||
self.assertEqual(invoice_id.state, 'open')
|
||||
|
||||
pay_account_id = self.env['account.account'].\
|
||||
browse(self.ref("account.cash"))
|
||||
journal_id = self.env['account.journal'].\
|
||||
browse(self.ref("account.bank_journal"))
|
||||
date_start = date.today().replace(day=1, month=1).strftime('%Y-%m-%d')
|
||||
period_id = self.env['account.fiscalyear'].search(
|
||||
[('date_start', '=', date_start)]).period_ids[8]
|
||||
|
||||
invoice_id.pay_and_reconcile(
|
||||
invoice_id.amount_total, pay_account_id.id,
|
||||
period_id.id, journal_id.id, pay_account_id.id,
|
||||
period_id.id, journal_id.id,
|
||||
name="Payment for Invoice")
|
||||
|
||||
# in order to proceed is necessary to get the sale order invoiced
|
||||
# and the invoice paid as well
|
||||
self.assertTrue(sale.invoiced)
|
||||
self.assertEqual(invoice_id.state, 'paid')
|
||||
|
||||
return invoice_id
|
||||
|
||||
def create_sale_invoice(self):
|
||||
sale_order_id = self.create_sale_order('manual')
|
||||
|
||||
lot_ids = []
|
||||
for picking_id in sale_order_id.picking_ids:
|
||||
|
||||
picking_id.force_assign()
|
||||
|
||||
# create wizard
|
||||
wizard_id = self.env['stock.transfer_details'].create({
|
||||
'picking_id': picking_id.id,
|
||||
})
|
||||
|
||||
# make the transfers
|
||||
for move_id in picking_id.move_lines:
|
||||
|
||||
wizard_item_id = self.env['stock.transfer_details_items'].\
|
||||
create({
|
||||
'transfer_id': wizard_id.id,
|
||||
'product_id': move_id.product_id.id,
|
||||
'quantity': move_id.product_qty,
|
||||
'sourceloc_id': move_id.location_id.id,
|
||||
'destinationloc_id':
|
||||
self.ref('stock.stock_location_stock'),
|
||||
'lot_id': False,
|
||||
'product_uom_id': move_id.product_uom.id,
|
||||
})
|
||||
|
||||
lot_id = self.env['stock.production.lot'].create({
|
||||
'product_id': move_id.product_id.id,
|
||||
'name': 'Test Lot %s%s' % (move_id.id,
|
||||
move_id.product_id.id)
|
||||
})
|
||||
|
||||
# keep lot_id for later check
|
||||
lot_ids.append(lot_id)
|
||||
|
||||
wizard_item_id.write({
|
||||
'lot_id': lot_id.id
|
||||
})
|
||||
|
||||
wizard_id.do_detailed_transfer()
|
||||
|
||||
# Before continue, invoice must be open to get a number value
|
||||
# and this is needed by the wizard
|
||||
invoice_id = self.sale_validate_invoice(sale_order_id)
|
||||
|
||||
return invoice_id, lot_ids
|
||||
209
crm_rma_lot_mass_return/tests/test_crm_rma_lot_mass_return_2.py
Normal file
209
crm_rma_lot_mass_return/tests/test_crm_rma_lot_mass_return_2.py
Normal file
@@ -0,0 +1,209 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Author: Osval Reyes,
|
||||
# Yanina Aular
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
import re
|
||||
|
||||
|
||||
class TestCrmRmaLotMassReturn2(TransactionCase):
|
||||
|
||||
"""
|
||||
Test cases for CRM RMA Lot Mass Return Module
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestCrmRmaLotMassReturn2, self).setUp()
|
||||
self.metasearch_wizard = self.env['returned.lines.from.serial.wizard']
|
||||
self.sale_order = self.env.ref('crm_rma_lot_mass_return.'
|
||||
'so_wizard_rma_1')
|
||||
self.lot_ids_mac0001 = self.env.ref('crm_rma_lot_mass_return.'
|
||||
'lot_purchase_wizard_rma_item_1')
|
||||
self.lot_ids_mac0003 = self.env.ref('crm_rma_lot_mass_return.'
|
||||
'lot_purchase_wizard_rma_item_3')
|
||||
self.claim_id_1 = self.env['crm.claim'].\
|
||||
create({
|
||||
'name': 'CLAIM001',
|
||||
'claim_type': self.ref('crm_claim_type.'
|
||||
'crm_claim_type_customer'),
|
||||
'partner_id': self.sale_order.partner_id.id,
|
||||
'pick': True
|
||||
})
|
||||
|
||||
self.claim_id_2 = self.env['crm.claim'].\
|
||||
create({
|
||||
'name': 'CLAIM002',
|
||||
'claim_type': self.ref('crm_claim_type.'
|
||||
'crm_claim_type_customer'),
|
||||
'partner_id': self.sale_order.partner_id.id,
|
||||
'pick': True
|
||||
})
|
||||
|
||||
def test_01_load_products(self):
|
||||
wizard_id = self.metasearch_wizard.with_context({
|
||||
'active_model': self.claim_id_1._name,
|
||||
'active_id': self.claim_id_1.id,
|
||||
'active_ids': [self.claim_id_1.id]
|
||||
}).create({})
|
||||
|
||||
# Get ids for invoice lines
|
||||
lines_list_id = wizard_id.onchange_load_products(
|
||||
self.sale_order.invoice_ids[0].number +
|
||||
'*5*description here' + '\n' + self.lot_ids_mac0001.name,
|
||||
[(6, 0, [])])['domain']['lines_list_id'][0][2]
|
||||
|
||||
option_ids = wizard_id.onchange_load_products(
|
||||
self.sale_order.invoice_ids[0].number +
|
||||
'*5*description here' + '\n' + self.lot_ids_mac0001.name,
|
||||
[(6, 0, [])])['value']['option_ids'][0][2]
|
||||
|
||||
wizard_id.option_ids = option_ids
|
||||
|
||||
items_to_select = self.env['claim.line.wizard'].browse(lines_list_id)
|
||||
|
||||
mac0001 = items_to_select.search([('lot_id.name', '=', 'MAC0001')])
|
||||
mac0002 = items_to_select.search([('lot_id.name', '=', 'MAC0002')])
|
||||
wizard_id.lines_list_id = [(6, 0, [mac0001.id, mac0002.id])]
|
||||
|
||||
# 1 Ink Cartridge, 2 Toner Cartridge, 1 iPad, 5 iMac
|
||||
self.assertEqual(len(lines_list_id), 9)
|
||||
|
||||
qty = 0
|
||||
for inv_line in self.sale_order.invoice_ids[0].invoice_line:
|
||||
qty += inv_line.quantity
|
||||
# Validate it has exactly as much records as the taken invoice has
|
||||
self.assertEqual(len(lines_list_id), int(qty))
|
||||
|
||||
wizard_id._set_message()
|
||||
wizard_id.add_claim_lines()
|
||||
|
||||
# 2 Macs
|
||||
self.assertEqual(len(self.claim_id_1.claim_line_ids), 2)
|
||||
|
||||
def test_02_load_products(self):
|
||||
wizard_id = self.metasearch_wizard.with_context({
|
||||
'active_model': self.claim_id_2._name,
|
||||
'active_id': self.claim_id_2.id,
|
||||
'active_ids': [self.claim_id_2.id]
|
||||
}).create({})
|
||||
|
||||
line_str = self.sale_order.invoice_ids[0].number + '*5*A description\n'
|
||||
# Get ids for invoice lines
|
||||
lines_list_id = wizard_id.onchange_load_products(
|
||||
line_str, [(6, 0, [])])['domain']['lines_list_id'][0][2]
|
||||
|
||||
option_ids = wizard_id.onchange_load_products(
|
||||
line_str, [(6, 0, [])])['value']['option_ids'][0][2]
|
||||
|
||||
wizard_id.option_ids = option_ids
|
||||
cl_wizard = self.env['claim.line.wizard'].browse(lines_list_id)
|
||||
|
||||
mac0001 = cl_wizard.search([('lot_id.name', '=', 'MAC0001')])
|
||||
mac0003 = cl_wizard.search([('lot_id.name', '=', 'MAC0003')])
|
||||
toner0001 = cl_wizard.search([('product_id.name',
|
||||
'=', 'Toner Cartridge')])
|
||||
toner0002 = toner0001[1]
|
||||
toner0001 = toner0001[0]
|
||||
ink0001 = cl_wizard.search([('product_id.name', '=', 'Ink Cartridge')])
|
||||
|
||||
wizard_id.lines_list_id = [(6, 0, [mac0001.id, mac0003.id,
|
||||
toner0001.id, toner0002.id,
|
||||
ink0001.id])]
|
||||
# 1 Ink Cartridge, 2 Toner Cartridge, 1 iPad, 5 iMac
|
||||
self.assertEqual(len(lines_list_id), 9)
|
||||
|
||||
qty = 0
|
||||
for inv_line in self.sale_order.invoice_ids[0].invoice_line:
|
||||
qty += inv_line.quantity
|
||||
# Validate it has exactly as much records as the taken invoice has
|
||||
self.assertEqual(len(lines_list_id), int(qty))
|
||||
wizard_id.add_claim_lines()
|
||||
# 2 Macs
|
||||
self.assertEqual(len(self.claim_id_2.claim_line_ids), 5)
|
||||
|
||||
def test_03_claim_line_creation_and_error_message(self):
|
||||
"""
|
||||
Challenge the wizard when a claim line is created, to set claim_origin
|
||||
and the name correctly in a claim line itself, and also it tests the
|
||||
message displayed to the user when is introduced an Serial/Lot numbers
|
||||
that already is part of another claim.
|
||||
"""
|
||||
|
||||
subject_list = self.env['claim.line'].SUBJECT_LIST
|
||||
lot_name = "MAC0001"
|
||||
subject_index = 3
|
||||
scanned_data = lot_name + '*' + \
|
||||
str(subject_index) + '*A short description to test\n'
|
||||
wizard_id = self.metasearch_wizard.with_context({
|
||||
'active_model': self.claim_id_2._name,
|
||||
'active_id': self.claim_id_2.id,
|
||||
'active_ids': [self.claim_id_2.id]
|
||||
}).create({})
|
||||
wizard_id.scan_data = scanned_data
|
||||
|
||||
# Get ids for invoice lines
|
||||
lines_list_id = wizard_id.onchange_load_products(
|
||||
scanned_data, [(6, 0, [])])['domain']['lines_list_id'][0][2]
|
||||
|
||||
wizard_id.option_id = wizard_id.onchange_load_products(
|
||||
scanned_data, [(6, 0, [])])['value']['option_ids'][0][2]
|
||||
|
||||
items_to_select = self.env['claim.line.wizard'].browse(lines_list_id)
|
||||
mac0001 = items_to_select.search([('lot_id.name', '=', lot_name)])
|
||||
wizard_id.lines_list_id = [(6, 0, [mac0001.id])]
|
||||
self.assertEqual(len(lines_list_id), 1)
|
||||
|
||||
wizard_id.add_claim_lines()
|
||||
self.assertEqual(len(self.claim_id_2.claim_line_ids), 1)
|
||||
|
||||
line_id = self.claim_id_2.claim_line_ids
|
||||
self.assertEqual(
|
||||
subject_list[subject_index - 1][0], line_id.claim_origin)
|
||||
self.assertEqual(scanned_data, line_id.prodlot_id.name + '*' +
|
||||
str(subject_index) + '*' + line_id.name + '\n')
|
||||
|
||||
# create again the wizard
|
||||
wizard_id = self.metasearch_wizard.with_context({
|
||||
'active_model': self.claim_id_2._name,
|
||||
'active_id': self.claim_id_2.id,
|
||||
'active_ids': [self.claim_id_2.id]
|
||||
}).create({})
|
||||
wizard_id.scan_data = scanned_data
|
||||
|
||||
# Get ids for invoice lines
|
||||
lines_list_id = wizard_id.onchange_load_products(
|
||||
scanned_data, [(6, 0, [])])['domain']['lines_list_id'][0][2]
|
||||
|
||||
wizard_id.option_id = wizard_id.onchange_load_products(
|
||||
scanned_data, [(6, 0, [])])['value']['option_ids'][0][2]
|
||||
|
||||
cl_wizard = self.env['claim.line.wizard'].browse(lines_list_id)
|
||||
clw_id = cl_wizard.search([('lot_id.name', '=', lot_name)])
|
||||
wizard_id.lines_list_id = [(6, 0, [clw_id.id])]
|
||||
self.assertEqual(len(lines_list_id), 1)
|
||||
|
||||
wizard_id._set_message()
|
||||
wizard_id.add_claim_lines()
|
||||
self.assertEqual(len(self.claim_id_2.claim_line_ids), 1)
|
||||
|
||||
# if the message exists, then it's being displayed
|
||||
regex = re.compile(".*" + lot_name + ".*")
|
||||
self.assertTrue(regex.search(wizard_id.message))
|
||||
19
crm_rma_lot_mass_return/views/crm_claim.xml
Normal file
19
crm_rma_lot_mass_return/views/crm_claim.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="crm_claim_rma_form_view_meta" model="ir.ui.view">
|
||||
<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="//page[@string='Claim Description']//div[@name='serial']" position="inside">
|
||||
<button name="render_metasearch_view"
|
||||
string="Add claim lines using serial or invoice number" type="object"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='invoice_id']" position="attributes">
|
||||
<attribute name="invisible">True</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,267 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#########################################################################
|
||||
# #
|
||||
# #
|
||||
#########################################################################
|
||||
# #
|
||||
# Copyright (C) 2009-2011 Akretion, Emmanuel Samyn #
|
||||
# #
|
||||
#This program is free software: you can redistribute it and/or modify #
|
||||
#it under the terms of the GNU 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 General Public License for more details. #
|
||||
# #
|
||||
#You should have received a copy of the GNU General Public License #
|
||||
#along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
#########################################################################
|
||||
from openerp.osv import fields, orm
|
||||
|
||||
|
||||
class returned_lines_from_serial(orm.TransientModel):
|
||||
|
||||
_name = 'returned_lines_from_serial.wizard'
|
||||
_description = 'Wizard to create product return lines from serial numbers'
|
||||
_columns = {
|
||||
'prodlot_id_1': fields.many2one('stock.production.lot',
|
||||
'Serial / Lot Number 1', required=True),
|
||||
'prodlot_id_2': fields.many2one('stock.production.lot',
|
||||
'Serial / Lot Number 2'),
|
||||
'prodlot_id_3': fields.many2one('stock.production.lot',
|
||||
'Serial / Lot Number 3'),
|
||||
'prodlot_id_4': fields.many2one('stock.production.lot',
|
||||
'Serial / Lot Number 4'),
|
||||
'prodlot_id_5': fields.many2one('stock.production.lot',
|
||||
'Serial / Lot Number 5'),
|
||||
'qty_1' : fields.float('Quantity 1', digits=(12,2), required=True),
|
||||
'qty_2' : fields.float('Quantity 2', digits=(12,2)),
|
||||
'qty_3' : fields.float('Quantity 3', digits=(12,2)),
|
||||
'qty_4' : fields.float('Quantity 4', digits=(12,2)),
|
||||
'qty_5' : fields.float('Quantity 5', digits=(12,2)),
|
||||
'claim_1': fields.selection([('none','Not specified'),
|
||||
('legal','Legal retractation'),
|
||||
('cancellation','Order cancellation'),
|
||||
('damaged','Damaged delivered product'),
|
||||
('error','Shipping error'),
|
||||
('exchange','Exchange request'),
|
||||
('lost','Lost during transport'),
|
||||
('other','Other')], 'Claim Subject',
|
||||
required=True,
|
||||
help="To describe the product problem"),
|
||||
'claim_2': fields.selection([('none','Not specified'),
|
||||
('legal','Legal retractation'),
|
||||
('cancellation','Order cancellation'),
|
||||
('damaged','Damaged delivered product'),
|
||||
('error','Shipping error'),
|
||||
('exchange','Exchange request'),
|
||||
('lost','Lost during transport'),
|
||||
('other','Other')], 'Claim Subject',
|
||||
required=True,
|
||||
help="To describe the line product problem"),
|
||||
'claim_3': fields.selection([('none','Not specified'),
|
||||
('legal','Legal retractation'),
|
||||
('cancellation','Order cancellation'),
|
||||
('damaged','Damaged delivered product'),
|
||||
('error','Shipping error'),
|
||||
('exchange','Exchange request'),
|
||||
('lost','Lost during transport'),
|
||||
('other','Other')], 'Claim Subject',
|
||||
required=True,
|
||||
help="To describe the line product problem"),
|
||||
'claim_4': fields.selection([('none','Not specified'),
|
||||
('legal','Legal retractation'),
|
||||
('cancellation','Order cancellation'),
|
||||
('damaged','Damaged delivered product'),
|
||||
('error','Shipping error'),
|
||||
('exchange','Exchange request'),
|
||||
('lost','Lost during transport'),
|
||||
('other','Other')], 'Claim Subject',
|
||||
required=True,
|
||||
help="To describe the line product problem"),
|
||||
'claim_5': fields.selection([('none','Not specified'),
|
||||
('legal','Legal retractation'),
|
||||
('cancellation','Order cancellation'),
|
||||
('damaged','Damaged delivered product'),
|
||||
('error','Shipping error'),
|
||||
('exchange','Exchange request'),
|
||||
('lost','Lost during transport'),
|
||||
('other','Other')], 'Claim Subject',
|
||||
required=True,
|
||||
help="To describe the line product problem"),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
}
|
||||
|
||||
# Get partner from case is set to filter serials
|
||||
def _get_default_partner_id(self, cr, uid, context):
|
||||
return self.pool.get('crm.claim').read(cr, uid,
|
||||
context['active_id'], ['partner_id'])['partner_id'][0]
|
||||
|
||||
_defaults = {
|
||||
'qty_1': lambda *a: 1.0,
|
||||
'qty_2': lambda *a: 1.0,
|
||||
'qty_3': lambda *a: 1.0,
|
||||
'qty_4': lambda *a: 1.0,
|
||||
'qty_5': lambda *a: 1.0,
|
||||
'claim_1': lambda *a: "none",
|
||||
'claim_2': lambda *a: "none",
|
||||
'claim_3': lambda *a: "none",
|
||||
'claim_4': lambda *a: "none",
|
||||
'claim_5': lambda *a: "none",
|
||||
'partner_id': _get_default_partner_id,
|
||||
}
|
||||
|
||||
# If "Cancel" button pressed
|
||||
def action_cancel(self,cr,uid,ids,conect=None):
|
||||
return {'type': 'ir.actions.act_window_close',}
|
||||
|
||||
# If "Add & close" button pressed
|
||||
def action_add_and_close(self, cr, uid, ids, context=None):
|
||||
self.add_return_lines(cr, uid, ids, context)
|
||||
return {'type': 'ir.actions.act_window_close',}
|
||||
|
||||
# If "Add & new" button pressed
|
||||
def action_add_and_new(self, cr, uid, ids, context=None):
|
||||
self.add_return_lines(cr, uid, ids, context)
|
||||
return {
|
||||
'context': context,
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'returned_lines_from_serial.wizard',
|
||||
'view_id': False,
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
# Method to get the product id from set
|
||||
def get_product_id(self, cr, uid,ids,product_set, context=None):
|
||||
product_id = False
|
||||
for product in self.prodlot_2_product(cr, uid,[product_set]):
|
||||
product_id = product
|
||||
return product_id
|
||||
|
||||
# Method to create return lines
|
||||
def add_return_lines(self, cr, uid, ids, context=None):
|
||||
result = self.browse(cr,uid,ids)[0]
|
||||
return_line = self.pool.get('claim.line')
|
||||
# Refactor code : create 1 "createmethode" called by each if with values as parameters
|
||||
return_line.create(cr, uid, {
|
||||
'claim_id': context['active_id'],
|
||||
'claim_origine': result.claim_1,
|
||||
'product_id' : self.get_product_id(cr, uid, ids,
|
||||
result.prodlot_id_1.id, context=context),
|
||||
#'invoice_id' : self.prodlot_2_invoice(cr, uid,[result.prodlot_id_1.id],[result.prodlot_id_1.product_id.id]), #PRODLOT_ID can be in many invoice !!
|
||||
'product_returned_quantity' : result.qty_1,
|
||||
'prodlot_id' : result.prodlot_id_1.id,
|
||||
'selected' : False,
|
||||
'state' : 'draft',
|
||||
#'guarantee_limit' : warranty['value']['guarantee_limit'],
|
||||
#'warning' : warranty['value']['warning'],
|
||||
})
|
||||
if result.prodlot_id_2.id :
|
||||
return_line.create(cr, uid, {
|
||||
'claim_id': context['active_id'],
|
||||
'claim_origine': result.claim_2,
|
||||
'product_id' : self.get_product_id(cr, uid, ids,
|
||||
result.prodlot_id_2.id, context=context),
|
||||
# 'invoice_id' : self.prodlot_2_invoice(cr, uid,[result.prodlot_id_1.id]),
|
||||
'product_returned_quantity' : result.qty_2,
|
||||
'prodlot_id' : result.prodlot_id_2.id,
|
||||
'selected' : False,
|
||||
'state' : 'draft',
|
||||
#'guarantee_limit' : warranty['value']['guarantee_limit'],
|
||||
#'warning' : warranty['value']['warning'],
|
||||
})
|
||||
if result.prodlot_id_3.id :
|
||||
return_line.create(cr, uid, {
|
||||
'claim_id': context['active_id'],
|
||||
'claim_origine': result.claim_3,
|
||||
'product_id' : self.get_product_id(cr, uid, ids,
|
||||
result.prodlot_id_3.id, context=context),
|
||||
# 'invoice_id' : self.prodlot_2_invoice(cr, uid,[result.prodlot_id_1.id]),
|
||||
'product_returned_quantity' : result.qty_3,
|
||||
'prodlot_id' : result.prodlot_id_3.id,
|
||||
'selected' : False,
|
||||
'state' : 'draft',
|
||||
#'guarantee_limit' : warranty['value']['guarantee_limit'],
|
||||
#'warning' : warranty['value']['warning'],
|
||||
})
|
||||
if result.prodlot_id_4.id :
|
||||
return_line.create(cr, uid, {
|
||||
'claim_id': context['active_id'],
|
||||
'claim_origine': result.claim_4,
|
||||
'product_id' : self.get_product_id(cr, uid, ids,
|
||||
result.prodlot_id_4.id, context=context),
|
||||
# 'invoice_id' : self.prodlot_2_invoice(cr, uid,[result.prodlot_id_1.id]),
|
||||
'product_returned_quantity' : result.qty_4,
|
||||
'prodlot_id' : result.prodlot_id_4.id,
|
||||
'selected' : False,
|
||||
'state' : 'draft',
|
||||
#'guarantee_limit' : warranty['value']['guarantee_limit'],
|
||||
#'warning' : warranty['value']['warning'],
|
||||
})
|
||||
if result.prodlot_id_5.id :
|
||||
return_line.create(cr, uid, {
|
||||
'claim_id': context['active_id'],
|
||||
'claim_origine': result.claim_5,
|
||||
'product_id' : self.get_product_id(cr, uid, ids,
|
||||
result.prodlot_id_5.id, context=context),
|
||||
# 'invoice_id' : self.prodlot_2_invoice(cr, uid,[result.prodlot_id_1.id],[result.prodlot_id_1.product_id.id]),
|
||||
'product_returned_quantity' : result.qty_5,
|
||||
'prodlot_id' : result.prodlot_id_5.id,
|
||||
'selected' : False,
|
||||
'state' : 'draft',
|
||||
#'guarantee_type':
|
||||
#'guarantee_limit' : warranty['value']['guarantee_limit'],
|
||||
#'warning' : warranty['value']['warning'],
|
||||
})
|
||||
|
||||
return True
|
||||
|
||||
def prodlot_2_product(self,cr, uid, prodlot_ids):
|
||||
stock_move_ids = self.pool.get('stock.move').search(cr, uid,
|
||||
[('prodlot_id', 'in', prodlot_ids)])
|
||||
res = self.pool.get('stock.move').read(cr, uid,
|
||||
stock_move_ids, ['product_id'])
|
||||
return set([x['product_id'][0] for x in res if x['product_id']])
|
||||
|
||||
def prodlot_2_invoice(self,cr, uid, prodlot_id,product_id):
|
||||
# get stock_move_ids
|
||||
stock_move_ids = self.pool.get('stock.move').search(cr, uid,
|
||||
[('prodlot_id', 'in', prodlot_id)])
|
||||
# if 1 id
|
||||
# (get stock picking (filter on out ?))
|
||||
# get invoice_ids from stock_move_id where invoice.line.product = prodlot_product and invoice customer = claim_partner
|
||||
# if 1 id
|
||||
# return invoice_id
|
||||
# else
|
||||
# else : move_in / move_out ; 1 move per order line so if many order lines with same lot, ...
|
||||
|
||||
|
||||
#
|
||||
#return set(self.stock_move_2_invoice(cr, uid, stock_move_ids))
|
||||
return True
|
||||
|
||||
def stock_move_2_invoice(self, cr, uid, stock_move_ids):
|
||||
inv_line_ids = []
|
||||
res = self.pool.get('stock.move').read(cr, uid,
|
||||
stock_move_ids, ['sale_line_id'])
|
||||
sale_line_ids = [x['sale_line_id'][0] for x in res if x['sale_line_id']]
|
||||
if not sale_line_ids:
|
||||
return []
|
||||
sql_base = "select invoice_id from sale_order_line_invoice_rel where \
|
||||
order_line_id in ("
|
||||
cr.execute(sql_base + ','.join(map(lambda x: str(x),sale_line_ids))+')')
|
||||
res = cr.fetchall()
|
||||
for i in res:
|
||||
for j in i:
|
||||
inv_line_ids.append(j)
|
||||
|
||||
res = self.pool.get('account.invoice.line').read(cr, uid,
|
||||
inv_line_ids,['invoice_id'])
|
||||
return [x['invoice_id'][0] for x in res if x['invoice_id']]
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
#########################################################################
|
||||
# #
|
||||
# #
|
||||
#########################################################################
|
||||
# #
|
||||
# Copyright (C) 2009-2011 Akretion, Emmanuel Samyn #
|
||||
# #
|
||||
#This program is free software: you can redistribute it and/or modify #
|
||||
#it under the terms of the GNU 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 General Public License for more details. #
|
||||
# #
|
||||
#You should have received a copy of the GNU General Public License #
|
||||
#along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
#########################################################################
|
||||
-->
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- SELECT FORM VIEW -->
|
||||
<record id="view_create_return_serial_form" model="ir.ui.view">
|
||||
<field name="name">returned_lines_from_serial_wiew</field>
|
||||
<field name="model">returned_lines_from_serial.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Select serial numbers to create">
|
||||
<group col="3" colspan="4">
|
||||
<separator string="Serial / Lot Number" colspan="1"/>
|
||||
<separator string="Quantity returned" colspan="1"/>
|
||||
<separator string="Claim short description" colspan="1"/>
|
||||
<field name="prodlot_id_1" nolabel="1"/>
|
||||
<field name="qty_1" nolabel="1"/>
|
||||
<field name="claim_1" nolabel="1"/>
|
||||
<field name="prodlot_id_2" nolabel="1"/>
|
||||
<field name="qty_2" nolabel="1"/>
|
||||
<field name="claim_2" nolabel="1"/>
|
||||
<field name="prodlot_id_3" nolabel="1"/>
|
||||
<field name="qty_3" nolabel="1"/>
|
||||
<field name="claim_3" nolabel="1"/>
|
||||
<field name="prodlot_id_4" nolabel="1"/>
|
||||
<field name="qty_4" nolabel="1"/>
|
||||
<field name="claim_4" nolabel="1"/>
|
||||
<field name="prodlot_id_5" nolabel="1"/>
|
||||
<field name="qty_5" nolabel="1"/>
|
||||
<field name="claim_5" nolabel="1"/>
|
||||
</group>
|
||||
<group col="4" colspan="2">
|
||||
<button special="cancel" string="Cancel" name="action_cancel" type="object" icon='gtk-cancel'/>
|
||||
<button name="action_add_and_close" string="Save and close" icon='gtk-ok' type="object"/>
|
||||
<button name="action_add_and_new" string="Save and new" icon='gtk-add' type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- SELECT ACTION -->
|
||||
<record id="action_create_return_serial" model="ir.actions.act_window">
|
||||
<field name="name">action_create_return_serial</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">returned_lines_from_serial.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>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,9 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau, Joel Grand-Guillaume
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: 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
|
||||
@@ -19,4 +22,5 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import returned_lines_from_serial
|
||||
595
crm_rma_lot_mass_return/wizards/returned_lines_from_serial.py
Normal file
595
crm_rma_lot_mass_return/wizards/returned_lines_from_serial.py
Normal file
@@ -0,0 +1,595 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Vauxoo
|
||||
# Copyright (C) 2009-2011 Akretion
|
||||
# Author: Emmanuel Samyn,
|
||||
# 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 openerp import _, api, fields, models
|
||||
from openerp.exceptions import ValidationError
|
||||
|
||||
|
||||
class ClaimLineWizard(models.TransientModel):
|
||||
|
||||
_name = "claim.line.wizard"
|
||||
|
||||
product_id = fields.Many2one("product.product",
|
||||
string="Product",
|
||||
help="Product to claim")
|
||||
lot_id = fields.Many2one("stock.production.lot",
|
||||
string="Lot",
|
||||
help="Product to claim")
|
||||
invoice_line_id = fields.Many2one("account.invoice.line",
|
||||
required=True,
|
||||
string="Invoice Line",
|
||||
help="Invoice Line")
|
||||
name = fields.Char(compute="_get_complete_name",
|
||||
string="Complete Lot Name",)
|
||||
|
||||
@api.constrains('product_id', 'invoice_line_id')
|
||||
def _check_product_id(self):
|
||||
for record in self:
|
||||
if record.product_id != \
|
||||
record.invoice_line_id.product_id:
|
||||
raise ValidationError("The product of the"
|
||||
" invoice %s is not same"
|
||||
" that product %s" %
|
||||
(record.invoice_line_id.product_id.name,
|
||||
record.product_id.name))
|
||||
|
||||
@api.depends('invoice_line_id', 'lot_id', 'product_id')
|
||||
def _get_complete_name(self):
|
||||
for wizard in self:
|
||||
invoice_number = wizard.invoice_line_id.invoice_id.number
|
||||
product_name = wizard.product_id.name
|
||||
|
||||
lot_name = False
|
||||
if wizard.lot_id:
|
||||
lot_name = wizard.lot_id.name
|
||||
|
||||
if not lot_name:
|
||||
name = _("(ID: %s) - %s - %s") % \
|
||||
(wizard.id,
|
||||
product_name,
|
||||
invoice_number)
|
||||
else:
|
||||
name = _("(ID: %s) - %s - %s - %s") % \
|
||||
(wizard.id,
|
||||
product_name,
|
||||
invoice_number,
|
||||
lot_name)
|
||||
|
||||
wizard.name = name
|
||||
|
||||
|
||||
class ReturnedLinesFromSerial(models.TransientModel):
|
||||
|
||||
_name = 'returned.lines.from.serial.wizard'
|
||||
_description = 'Wizard to create product return lines'
|
||||
' from serial numbers or invoices'
|
||||
|
||||
# Get partner from case is set to filter serials
|
||||
@api.model
|
||||
def _get_default_partner_id(self):
|
||||
"""
|
||||
Obtain partner from the claim
|
||||
"""
|
||||
crm_claim_model = self.env['crm.claim']
|
||||
claim_id = self.env.context.get('active_id')
|
||||
partner_record = crm_claim_model.browse(claim_id).\
|
||||
partner_id
|
||||
return partner_record and partner_record[0] or \
|
||||
self.env['res.partner']
|
||||
|
||||
@api.model
|
||||
def create_claim_line(self, claim_id, claim_origin,
|
||||
product_record, claim_line_wizard,
|
||||
qty, name):
|
||||
clima_line = self.env['claim.line']
|
||||
if claim_line_wizard.lot_id:
|
||||
inv_line = self.prodlot_2_invoice_line(
|
||||
claim_line_wizard.lot_id.name)
|
||||
lot_id = claim_line_wizard.lot_id.id
|
||||
else:
|
||||
inv_line = claim_line_wizard.invoice_line_id
|
||||
lot_id = False
|
||||
line_rec = clima_line.create({
|
||||
'claim_id': claim_id,
|
||||
'claim_origin': claim_origin,
|
||||
'product_id': product_record and product_record.id or False,
|
||||
'name': name and name or (product_record and
|
||||
product_record.name or
|
||||
inv_line.name),
|
||||
'invoice_line_id': inv_line.id,
|
||||
'product_returned_quantity': qty,
|
||||
'prodlot_id': lot_id,
|
||||
})
|
||||
line_rec.set_warranty()
|
||||
|
||||
# If "Cancel" button pressed
|
||||
@api.multi
|
||||
def action_cancel(self):
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
partner_id = fields.Many2one('res.partner',
|
||||
'Partner',
|
||||
default=_get_default_partner_id)
|
||||
|
||||
def _get_claim_type(self):
|
||||
claim_id = self.env.context.get('active_id')
|
||||
claim_record = self.env['crm.claim'].browse(claim_id)
|
||||
current_claim_type = claim_record.claim_type
|
||||
customer_claim_type = \
|
||||
self.env.ref('crm_claim_type.crm_claim_type_customer')
|
||||
supplier_claim_type = \
|
||||
self.env.ref('crm_claim_type.crm_claim_type_supplier')
|
||||
return current_claim_type, customer_claim_type, supplier_claim_type
|
||||
|
||||
@api.model
|
||||
def prodlot_2_invoice_line(self, prodlot):
|
||||
"""
|
||||
Return the last line of customer invoice
|
||||
based in serial/lot number
|
||||
"""
|
||||
lot_obj = self.env['stock.production.lot']
|
||||
current_claim_type, customer_claim_type, supplier_claim_type = \
|
||||
self._get_claim_type()
|
||||
|
||||
prodlot = lot_obj.search([('name', '=', str(prodlot))])
|
||||
|
||||
if supplier_claim_type == current_claim_type:
|
||||
if prodlot.supplier_invoice_line_id:
|
||||
return prodlot.supplier_invoice_line_id
|
||||
elif customer_claim_type == current_claim_type:
|
||||
if prodlot.invoice_line_id:
|
||||
return prodlot.invoice_line_id
|
||||
else:
|
||||
if prodlot.invoice_line_id:
|
||||
return prodlot.invoice_line_id
|
||||
elif prodlot.supplier_invoice_line_id:
|
||||
return prodlot.supplier_invoice_line_id
|
||||
|
||||
return False
|
||||
|
||||
lines_list_id = fields.Many2many('claim.line.wizard',
|
||||
'claim_line_wizard_returned',
|
||||
'wizard_id',
|
||||
'claim_line_wizard_id',
|
||||
string='Products selected',
|
||||
help='Field used to show the current '
|
||||
'status of the lots '
|
||||
'loaded')
|
||||
option_ids = fields.Many2many('claim.line.wizard',
|
||||
string='Invoice Lines to Select',
|
||||
help='Field used to load the ids of '
|
||||
'invoice lines in invoices writed')
|
||||
scan_data = fields.Text('Products',
|
||||
help='Field used to load and show the '
|
||||
'products')
|
||||
scaned_data = fields.Text('Products',
|
||||
help='Field used to load the ids of '
|
||||
'products loaded')
|
||||
current_status = fields.Text('Status',
|
||||
help='Field used to show the current '
|
||||
'status of the product '
|
||||
'loaded(Name and quantity)')
|
||||
|
||||
@api.multi
|
||||
def get_metasearch_view_brw(self):
|
||||
"""
|
||||
@return: view with metasearch field
|
||||
"""
|
||||
view_id = self.env.\
|
||||
ref('crm_rma_lot_mass_return.view_enter_product')
|
||||
return view_id
|
||||
|
||||
@api.multi
|
||||
def render_metasearch_view(self):
|
||||
"""
|
||||
Render wizard view with metasearch field
|
||||
"""
|
||||
view = self.get_metasearch_view_brw()
|
||||
if view:
|
||||
return {
|
||||
'name': _('Search Product'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'returned.lines.from.serial.wizard',
|
||||
'view_id': view.id,
|
||||
'views': [(view.id, 'form')],
|
||||
'target': 'new',
|
||||
'res_id': self.id,
|
||||
}
|
||||
|
||||
@api.model
|
||||
def get_data_of_products(self, input_data):
|
||||
data_line = []
|
||||
for item in input_data and input_data.split('\n') or []:
|
||||
if '*' in item:
|
||||
|
||||
comput = item.split('*')
|
||||
data_it_1 = '0'
|
||||
data_it_2 = ''
|
||||
if len(comput) >= 2:
|
||||
data_it_1 = comput[1]
|
||||
if len(comput) >= 3:
|
||||
data_it_2 = comput[2]
|
||||
if comput[0]:
|
||||
data_line.append((comput[0], (data_it_1, data_it_2)))
|
||||
else:
|
||||
if item.strip():
|
||||
data_line.append((item.strip(), ('0', '')))
|
||||
return data_line
|
||||
|
||||
def _get_lots_from_scan_data(self, input_data):
|
||||
|
||||
input_lines = self.get_data_of_products(input_data)
|
||||
invoice = self.env['account.invoice']
|
||||
lot = self.env['stock.production.lot']
|
||||
|
||||
prodlot_set_ids = set()
|
||||
lot_set_ids = []
|
||||
lots_lot_set_ids = []
|
||||
|
||||
if not input_lines:
|
||||
return False, False, False
|
||||
|
||||
current_claim_type, customer_claim_type, supplier_claim_type = \
|
||||
self._get_claim_type()
|
||||
|
||||
claim_line_wizard = self.env['claim.line.wizard']
|
||||
|
||||
for line in input_lines:
|
||||
# if there is no invoice/serial in it
|
||||
if not line[0]:
|
||||
continue
|
||||
|
||||
number_serial = line[0].encode('utf8')
|
||||
# search invoices first
|
||||
invoice_ids = invoice.search([('number', '=', number_serial)])
|
||||
element_searched = False
|
||||
if invoice_ids:
|
||||
|
||||
if supplier_claim_type == current_claim_type:
|
||||
invoice_field = 'supplier_invoice_line_id'
|
||||
elif customer_claim_type == current_claim_type:
|
||||
invoice_field = 'invoice_line_id'
|
||||
|
||||
for inv in invoice_ids:
|
||||
for inv_line in inv.invoice_line:
|
||||
clw = claim_line_wizard.\
|
||||
search([('invoice_line_id', '=', inv_line.id)])
|
||||
enter = False
|
||||
lot_ids = lot.\
|
||||
search([(invoice_field, '=',
|
||||
inv_line.id)])
|
||||
if len(clw) < int(inv_line.quantity):
|
||||
for asd in clw:
|
||||
if asd not in lot_set_ids:
|
||||
lot_set_ids.append(asd)
|
||||
lot_ids = lot_ids - asd.lot_id
|
||||
num_to_create = int(inv_line.quantity) - len(clw)
|
||||
for num in xrange(0, num_to_create):
|
||||
clw = \
|
||||
claim_line_wizard.\
|
||||
create({
|
||||
'product_id':
|
||||
inv_line.product_id.id,
|
||||
'invoice_line_id': inv_line.id,
|
||||
})
|
||||
if lot_ids:
|
||||
lot = lot_ids[0]
|
||||
clw.write({'lot_id': lot.id})
|
||||
lot_ids = lot_ids - lot
|
||||
for asd in clw:
|
||||
if asd not in lot_set_ids:
|
||||
lot_set_ids.append(asd)
|
||||
enter = True
|
||||
if not enter:
|
||||
for asd in clw:
|
||||
if asd not in lot_set_ids:
|
||||
if lot_ids:
|
||||
lot = lot_ids[0]
|
||||
asd.write({'lot_id': lot.id})
|
||||
lot_ids = lot_ids - lot
|
||||
lot_set_ids.append(asd)
|
||||
|
||||
element_searched = lot_set_ids
|
||||
else:
|
||||
# if not, it must be a serial lot number
|
||||
prodlot_ids = lot
|
||||
if supplier_claim_type == current_claim_type:
|
||||
prodlot_ids = \
|
||||
lot.search([('name', '=', number_serial),
|
||||
('supplier_invoice_line_id', '!=', False)])
|
||||
invoice_line = prodlot_ids.supplier_invoice_line_id
|
||||
elif customer_claim_type == current_claim_type:
|
||||
prodlot_ids = \
|
||||
lot.search([('name', '=', number_serial),
|
||||
('invoice_line_id', '!=', False)])
|
||||
invoice_line = prodlot_ids.invoice_line_id
|
||||
else:
|
||||
prodlot_ids = \
|
||||
lot.search([('name', '=', number_serial), '|',
|
||||
('supplier_invoice_line_id', '!=', False),
|
||||
('invoice_line_id', '!=', False),
|
||||
])
|
||||
if prodlot_ids.invoice_line_id:
|
||||
invoice_line = prodlot_ids.invoice_line_id
|
||||
else:
|
||||
invoice_line = prodlot_ids.supplier_invoice_line_id
|
||||
if prodlot_ids:
|
||||
for lot_id in prodlot_ids:
|
||||
clw = claim_line_wizard.\
|
||||
search([('lot_id', '=', lot_id.id)])
|
||||
if not clw:
|
||||
clw = \
|
||||
claim_line_wizard.\
|
||||
create({
|
||||
'product_id': lot_id.product_id.id,
|
||||
'lot_id': lot_id.id,
|
||||
'invoice_line_id': invoice_line.id,
|
||||
})
|
||||
for asd in clw:
|
||||
if asd not in lot_set_ids:
|
||||
lot_set_ids.append(asd)
|
||||
element_searched = True
|
||||
|
||||
for item in prodlot_ids:
|
||||
item_name = item.product_id \
|
||||
and item.product_id.name.encode('utf8') or False
|
||||
prodlot_set_ids |= {'%s+%s' % (item.id, item_name)}
|
||||
|
||||
for asd in lot_set_ids:
|
||||
if asd not in lots_lot_set_ids:
|
||||
lots_lot_set_ids.append(asd)
|
||||
|
||||
# if at least one line is not found, then return error
|
||||
if not element_searched:
|
||||
return False, line[0], False
|
||||
|
||||
# all lines were found, then return those lots
|
||||
return lot_set_ids, prodlot_set_ids, lots_lot_set_ids
|
||||
|
||||
@api.multi
|
||||
def onchange_load_products(self, input_data, lines_list_id):
|
||||
"""
|
||||
Load claim lines from partner invoices or related production lots
|
||||
into the current claim massively
|
||||
"""
|
||||
lot_lots_ids = []
|
||||
prodlot_set_ids = set()
|
||||
lines_set_ids = []
|
||||
current_status = scaned_data = ''
|
||||
|
||||
elements_searched, line_found, lot_lots_ids = \
|
||||
self._get_lots_from_scan_data(input_data)
|
||||
|
||||
if not elements_searched and not line_found:
|
||||
return {
|
||||
'value': {
|
||||
'option_ids': [],
|
||||
'current_status': current_status,
|
||||
'scaned_data': scaned_data,
|
||||
},
|
||||
'domain': {
|
||||
'lines_list_id': [('id', 'in', [])]
|
||||
}
|
||||
}
|
||||
if not elements_searched and not lot_lots_ids and line_found:
|
||||
return {
|
||||
'warning': {
|
||||
'message': (_('The product or invoice %s'
|
||||
' was not found') % line_found)},
|
||||
}
|
||||
else:
|
||||
lines_set_ids = elements_searched
|
||||
prodlot_set_ids = line_found
|
||||
|
||||
for line in prodlot_set_ids:
|
||||
name = line.split('+')
|
||||
current_status += name[1] + '\n'
|
||||
scaned_data += name[0] + '\n'
|
||||
|
||||
lines_set_ids = [asd.id for asd in lines_set_ids]
|
||||
return {
|
||||
'value': {
|
||||
'option_ids': [(6, 0, lines_set_ids)],
|
||||
'current_status': current_status,
|
||||
'scaned_data': scaned_data,
|
||||
},
|
||||
'domain': {
|
||||
'lines_list_id': [('id', 'in', lines_set_ids)]
|
||||
}
|
||||
}
|
||||
|
||||
def _get_lot_ids(self):
|
||||
lot = self.env['stock.production.lot']
|
||||
lot_ids = set()
|
||||
if self.scaned_data:
|
||||
lot_ids |= {lot_id
|
||||
for lid in self.scaned_data.strip().split('\n')
|
||||
for lot_id in lot.browse(int(lid))}
|
||||
|
||||
claim_line_wizard = self.env['claim.line.wizard']
|
||||
|
||||
lot_ids_2 = []
|
||||
for wizard_id in lot_ids:
|
||||
clws = claim_line_wizard.search([('lot_id', '=', wizard_id.id)])
|
||||
for clw in clws:
|
||||
lot_ids_2.append(clw)
|
||||
|
||||
lot_ids = set(lot_ids_2)
|
||||
|
||||
if self.lines_list_id:
|
||||
lot_ids |= {lid for lid in self.lines_list_id}
|
||||
|
||||
return lot_ids
|
||||
|
||||
@api.model
|
||||
def _get_invalid_lots_set(self, claim_line_wizard_ids, add=False):
|
||||
"""
|
||||
Return only those lots are related to claim lines
|
||||
"""
|
||||
claim_line_wizard = self.env['claim.line.wizard']
|
||||
valid = claim_line_wizard.browse(claim_line_wizard_ids)
|
||||
invalid_lots = []
|
||||
for clw in claim_line_wizard.browse(claim_line_wizard_ids):
|
||||
if clw.lot_id:
|
||||
invalid_lot = self.env['claim.line'].search([
|
||||
('invoice_line_id', '=', clw.invoice_line_id.id),
|
||||
('product_id', '=', clw.product_id.id),
|
||||
('prodlot_id', '=', clw.lot_id.id),
|
||||
])
|
||||
if not invalid_lot:
|
||||
valid = valid - clw
|
||||
if invalid_lot:
|
||||
invalid_lots.append(clw)
|
||||
|
||||
for clw in valid.mapped('invoice_line_id'):
|
||||
|
||||
# mac1, None -> claim.line
|
||||
invalid_lot = self.env['claim.line'].search([
|
||||
('invoice_line_id', '=', clw.id),
|
||||
('product_id', '=', clw.product_id.id),
|
||||
])
|
||||
|
||||
# mac1, mac2, mac3, mac4, None -> breaked down
|
||||
clws = self.env['claim.line.wizard'].\
|
||||
search([('invoice_line_id', '=', clw.id),
|
||||
])
|
||||
|
||||
if invalid_lot:
|
||||
for item in invalid_lot:
|
||||
if item.prodlot_id:
|
||||
add = clws.search([
|
||||
('lot_id', '=', item.prodlot_id.id),
|
||||
('id', 'in', clws.mapped('id')),
|
||||
('id', 'not in', [rdy.id for rdy in invalid_lots]),
|
||||
])
|
||||
else:
|
||||
add = clws.search([
|
||||
('lot_id', '=', False),
|
||||
('id', 'in', clws.mapped('id')),
|
||||
('id', 'not in', [rdy.id for rdy in invalid_lots]),
|
||||
])
|
||||
if add:
|
||||
invalid_lots.append(add[0])
|
||||
|
||||
# mac1, None -> like claim.line.wizard
|
||||
return invalid_lots and invalid_lots or []
|
||||
|
||||
@api.multi
|
||||
def add_claim_lines(self):
|
||||
info = self.get_data_of_products(self.scan_data)
|
||||
lot_ids = self._get_lot_ids()
|
||||
lot_ids = [lid.id for lid in lot_ids]
|
||||
clw_ids = set(self._get_lot_ids()) - \
|
||||
set(self._get_invalid_lots_set(lot_ids, True))
|
||||
clw_ids = list(clw_ids)
|
||||
# It creates only those claim lines that have a valid production lot,
|
||||
# i. e. not using in others claims
|
||||
info = dict(info)
|
||||
|
||||
if clw_ids:
|
||||
for clw_id in clw_ids:
|
||||
product_id = clw_id.product_id
|
||||
|
||||
claim_line_info = False
|
||||
if clw_id.lot_id.name in info:
|
||||
claim_line_info = info.get(clw_id.lot_id.name, False)
|
||||
elif clw_id.invoice_line_id.invoice_id.number in info:
|
||||
claim_line_info = \
|
||||
info.get(clw_id.invoice_line_id.invoice_id.number,
|
||||
False)
|
||||
|
||||
num = claim_line_info and claim_line_info[0] or '0'
|
||||
name = claim_line_info and claim_line_info[1] or ''
|
||||
if num.isdigit():
|
||||
num = int(num)
|
||||
else:
|
||||
num = 0
|
||||
|
||||
current_claim_type, customer_claim_type, \
|
||||
supplier_claim_type = \
|
||||
self._get_claim_type()
|
||||
self.create_claim_line(self.env.context.get('active_id'),
|
||||
self.env[
|
||||
'claim.line']._get_subject(num),
|
||||
product_id, clw_id, 1, name)
|
||||
|
||||
# Clean items in wizard model
|
||||
if len(clw_ids) == 1:
|
||||
ids_to_delete = "(%s)" % str(clw_ids[0].id)
|
||||
else:
|
||||
ids_to_delete = "%s" % str(tuple([clw.id for clw in clw_ids]))
|
||||
self._cr.execute("DELETE FROM claim_line_wizard where id IN %s"
|
||||
% ids_to_delete)
|
||||
|
||||
# normal execution
|
||||
self.action_cancel()
|
||||
|
||||
@api.multi
|
||||
def change_list(self, lines):
|
||||
return {
|
||||
'value': {
|
||||
'lines_list_id': lines,
|
||||
}
|
||||
}
|
||||
|
||||
message = fields.Text(string='Message',
|
||||
compute='_set_message'
|
||||
)
|
||||
|
||||
@api.depends('current_status', 'lines_list_id', 'scan_data')
|
||||
def _set_message(self):
|
||||
"""
|
||||
Notify for missing (not added) claim lines that are in use in others
|
||||
claims
|
||||
"""
|
||||
for wizard in self:
|
||||
msg = ''
|
||||
all_lots = wizard._get_lots_from_scan_data(wizard.scan_data)
|
||||
not_valid_lot_ids = set()
|
||||
if all_lots[0]:
|
||||
all_lots_0 = [item for item in all_lots[0]]
|
||||
not_valid_lot_ids = set(all_lots_0)
|
||||
if all_lots[2]:
|
||||
all_lots_2 = [item for item in all_lots[2]]
|
||||
not_valid_lot_ids |= set(all_lots_2)
|
||||
|
||||
if not_valid_lot_ids:
|
||||
not_valid_lot_ids = [item.id for
|
||||
item in list(not_valid_lot_ids)]
|
||||
not_valid_lot_ids = wizard.\
|
||||
_get_invalid_lots_set(not_valid_lot_ids)
|
||||
not_valid_lot_ids = list(set(not_valid_lot_ids))
|
||||
claim_with_lots_msg = ""
|
||||
|
||||
for line_id in not_valid_lot_ids:
|
||||
claim_with_lots_msg += "\t- %s\n" % \
|
||||
line_id.name
|
||||
if claim_with_lots_msg:
|
||||
msg = _("The following Serial/Lot numbers won't be added,"
|
||||
" because all of them (listed below)"
|
||||
" are currently in"
|
||||
" use:\n\n %s") % (claim_with_lots_msg) or ''
|
||||
|
||||
wizard.message = msg
|
||||
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_enter_product" model="ir.ui.view">
|
||||
<field name="name">returned_lines_from_serial_wiew</field>
|
||||
<field name="model">returned.lines.from.serial.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<div class='row'>
|
||||
<div class="col-md-10 col-sm-10 col-lg-10">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h2><field name="partner_id" readonly="1"/></h2>
|
||||
<field class="oe_form_box_info oe_text_center"
|
||||
name='message'
|
||||
readonly="1"
|
||||
attrs="{'invisible':[('message', '=', '')]}"/>
|
||||
<group>
|
||||
<field name="scaned_data" invisible="1"/>
|
||||
</group>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<td>
|
||||
<field name="current_status" readonly="1" widget="barcode_text" nolabel='1'/>
|
||||
</td>
|
||||
<td>
|
||||
<field name="scan_data"
|
||||
widget='barcode_text'
|
||||
on_change="onchange_load_products(scan_data, option_ids)"
|
||||
nolabel='1'/>
|
||||
</td>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-10 col-sm-10 col-lg-10">
|
||||
<div class="row">
|
||||
<div class="pull-right" name="buttons">
|
||||
<button name="add_claim_lines"
|
||||
help="All the valid lines will be added to the claim"
|
||||
confirm="You are about to add new lines to the claim, Do you want to continue?."
|
||||
string="Add items to the claim" colspan="1" type="object" class="oe_highlight"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class='col-md-4 col-sm-4 col-lg-4'>
|
||||
<div class="row">
|
||||
<field name="option_ids" invisible="1"/>
|
||||
<field name="lines_list_id"
|
||||
domain="[('id', 'in', [])]"
|
||||
widget="many2many_checkboxes" on_change="change_list(lines_list_id)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-md-16 col-sm-16 col-lg-16'>
|
||||
<div class="row">
|
||||
<!-- Invoice lines list -->
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-md-4 col-sm-4 col-lg-4'>
|
||||
<div class="row">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<p class="oe_help">
|
||||
You should use this windows on this way.
|
||||
<ol>
|
||||
<li>Write the Serial/Lot Number to search the product</li>
|
||||
or
|
||||
<li>Write the Invoice Number to search the products in lines</li>
|
||||
<li>Example: A4JD6JHS</li>
|
||||
</ol>
|
||||
The format for writing the reason for the claim and
|
||||
the description is:
|
||||
<ol>
|
||||
<li>Serial/Lot Number*reason number*Description here</li>
|
||||
<li>Example: A4JD6JHS*4*The display is break</li>
|
||||
</ol>
|
||||
|
||||
The reasons for the claim can be
|
||||
<ol>
|
||||
<li>Not specified</li>
|
||||
<li>Legal retractation</li>
|
||||
<li>Order Cancellation</li>
|
||||
<li>Damaged Delivered Product</li>
|
||||
<li>Shipping error</li>
|
||||
<li>Exchange request</li>
|
||||
<li>Lost during transport</li>
|
||||
<li>Perfect Conditions</li>
|
||||
<li>Imperfection</li>
|
||||
<li>Physical Damage by Client</li>
|
||||
<li>Physical Damage by Company</li>
|
||||
<li>Other</li>
|
||||
</ol>
|
||||
</p>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
Reference in New Issue
Block a user