diff --git a/.travis.yml b/.travis.yml index 6ef26cb1..e03bd8d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ install: - travis_install_nightly # add OCA/crm dependencies - git clone --depth=1 https://github.com/OCA/crm -b ${VERSION} $HOME/crm + - git clone --depth=1 https://github.com/OCA/stock-logistics-workflow -b ${VERSION} $HOME/stock-logistics-workflow script: - travis_run_tests diff --git a/crm_rma_prodlot_invoice/README.rst b/crm_rma_prodlot_invoice/README.rst new file mode 100644 index 00000000..8ad2bd63 --- /dev/null +++ b/crm_rma_prodlot_invoice/README.rst @@ -0,0 +1,75 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + + +========================= +CRM Claim Prodlot Invoice +========================= + +When an invoice is created from sale order, invoice line information +is kept into production lot. + +Also, helps to display invoice line information when an production lot is displayed + +Installation +============ + +To install this module, just select it from availables modules + +Configuration +============= + +No extra configurations is needed + +Usage +===== + +When generating Customer Invoices from Sales Order, this module handles and set +related information about procurement and picking + +.. 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 known + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + + +Credits +======= + +Contributors +------------ + +* Yanina Aular +* Osval Reyes + +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. diff --git a/crm_rma_prodlot_invoice/__init__.py b/crm_rma_prodlot_invoice/__init__.py new file mode 100644 index 00000000..140fb3fd --- /dev/null +++ b/crm_rma_prodlot_invoice/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2015 Vauxoo +# Author: Yanina Aular, Osval Reyes +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import models diff --git a/crm_rma_prodlot_invoice/__openerp__.py b/crm_rma_prodlot_invoice/__openerp__.py new file mode 100644 index 00000000..23833d41 --- /dev/null +++ b/crm_rma_prodlot_invoice/__openerp__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2015 Vauxoo +# Author: Yanina Aular, Osval Reyes +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +{ + 'name': 'CRM Claim Prodlot Invoice', + 'version': '8.0.1.0.0', + 'author': 'Vauxoo,Odoo Community Association (OCA)', + 'website': 'http://www.vauxoo.com/', + 'category': 'RMA', + 'license': 'AGPL-3', + 'depends': [ + 'sale', + 'sale_stock', + 'product_unique_serial', + ], + 'data': [ + 'views/stock_production_lot.xml', + ], + 'installable': True, +} diff --git a/crm_rma_prodlot_invoice/i18n/crm_rma_prodlot_invoice.pot b/crm_rma_prodlot_invoice/i18n/crm_rma_prodlot_invoice.pot new file mode 100644 index 00000000..efdc4222 --- /dev/null +++ b/crm_rma_prodlot_invoice/i18n/crm_rma_prodlot_invoice.pot @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * crm_rma_prodlot_invoice +# +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" + +#. module: crm_rma_prodlot_invoice +#: model:ir.model,name:crm_rma_prodlot_invoice.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: crm_rma_prodlot_invoice +#: model:ir.model,name:crm_rma_prodlot_invoice.model_sale_order_line +msgid "Sales Order Line" +msgstr "" diff --git a/crm_rma_prodlot_invoice/i18n/es.po b/crm_rma_prodlot_invoice/i18n/es.po new file mode 100644 index 00000000..4c967380 --- /dev/null +++ b/crm_rma_prodlot_invoice/i18n/es.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * crm_rma_prodlot_invoice +# +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" + +#. module: crm_rma_prodlot_invoice +#: model:ir.model,name:crm_rma_prodlot_invoice.model_sale_order +msgid "Sales Order" +msgstr "Órdenes de venta" + +#. module: crm_rma_prodlot_invoice +#: model:ir.model,name:crm_rma_prodlot_invoice.model_sale_order_line +msgid "Sales Order Line" +msgstr "Línea de orden de venta" diff --git a/crm_rma_prodlot_invoice/i18n/es_MX.po b/crm_rma_prodlot_invoice/i18n/es_MX.po new file mode 100644 index 00000000..12faecfb --- /dev/null +++ b/crm_rma_prodlot_invoice/i18n/es_MX.po @@ -0,0 +1,16 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * crm_rma_prodlot_invoice +# +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" diff --git a/crm_rma_prodlot_invoice/i18n/es_PA.po b/crm_rma_prodlot_invoice/i18n/es_PA.po new file mode 100644 index 00000000..12faecfb --- /dev/null +++ b/crm_rma_prodlot_invoice/i18n/es_PA.po @@ -0,0 +1,16 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * crm_rma_prodlot_invoice +# +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" diff --git a/crm_rma_prodlot_invoice/i18n/es_VE.po b/crm_rma_prodlot_invoice/i18n/es_VE.po new file mode 100644 index 00000000..23624817 --- /dev/null +++ b/crm_rma_prodlot_invoice/i18n/es_VE.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * crm_rma_prodlot_invoice +# +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" + +#. module: crm_rma_prodlot_invoice +#: model:ir.model,name:crm_rma_prodlot_invoice.model_sale_order +msgid "Sales Order" +msgstr "Pedidos de venta" + +#. module: crm_rma_prodlot_invoice +#: model:ir.model,name:crm_rma_prodlot_invoice.model_sale_order_line +msgid "Sales Order Line" +msgstr "Línea de pedido de venta" diff --git a/crm_rma_prodlot_invoice/models/__init__.py b/crm_rma_prodlot_invoice/models/__init__.py new file mode 100644 index 00000000..84440d36 --- /dev/null +++ b/crm_rma_prodlot_invoice/models/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2015 Vauxoo +# Author: Yanina Aular, Osval Reyes +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import sale_order +from . import sale_order_line +from . import stock_production_lot +from . import stock_transfer_details +from . import stock_picking diff --git a/crm_rma_prodlot_invoice/models/sale_order.py b/crm_rma_prodlot_invoice/models/sale_order.py new file mode 100644 index 00000000..3172ff0f --- /dev/null +++ b/crm_rma_prodlot_invoice/models/sale_order.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2015 Vauxoo +# Author: Yanina Aular, Osval Reyes +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from openerp import api, models + + +class SaleOrder(models.Model): + + _inherit = 'sale.order' + + @api.multi + def action_done(self): + """ + Set stock moves to invoice lines that matches with + product and product quantity when sale order is done + """ + return self.set_lot_invoice_line(self, 'action_done') + + @api.multi + def action_ship_create(self): + """ + Set stock moves to invoice lines that matches with + product and product quantity when delivery is created + """ + return self.set_lot_invoice_line(self, 'action_ship_create') + + def set_lot_invoice_line(self, record_set, method=False): + res = getattr(super(SaleOrder, self), method)() if method else False + for order_id in record_set: + move_ids = order_id.mapped('picking_ids.move_lines') + invoice_lines = order_id.mapped('invoice_ids.invoice_line') + + if not invoice_lines or not move_ids: + continue + + for inv_line in invoice_lines: + qty_lots_with_inv_line = len(self.env['stock.production.lot']. + search([('invoice_line_id', '=', + inv_line.id)])) + for move_id in move_ids: + lots = move_id.mapped('quant_ids.lot_id') + for lot in lots: + if not lot.invoice_line_id and \ + inv_line.product_id.id == \ + lot.product_id.id and \ + qty_lots_with_inv_line < inv_line.quantity: + lot.write({'invoice_line_id': inv_line.id}) + return res diff --git a/crm_rma_prodlot_invoice/models/sale_order_line.py b/crm_rma_prodlot_invoice/models/sale_order_line.py new file mode 100644 index 00000000..ed4155f3 --- /dev/null +++ b/crm_rma_prodlot_invoice/models/sale_order_line.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2015 Vauxoo +# Author: Yanina Aular, Osval Reyes +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import api, models + + +class SaleOrderLine(models.Model): + + _inherit = 'sale.order.line' + + @api.multi + def invoice_line_create(self): + res = super(SaleOrderLine, self).invoice_line_create() + for order_line in self: + prodlot_obj = self.env['stock.production.lot'] + procurements = order_line.procurement_ids + + if not procurements: + continue + + move_id = self.env['stock.move'].\ + search([('procurement_id', '=', + order_line.procurement_ids[0].id)], limit=1) + + if move_id and move_id.quant_ids: + lot = move_id.quant_ids[0].lot_id + + if lot.invoice_line_id: + continue + + for inv_line_id in res: + + inv_line = self.env['account.invoice.line'].\ + browse(inv_line_id) + + lots = prodlot_obj.search([('invoice_line_id', '=', + inv_line.id)]) + + if inv_line.product_id.id == lot.product_id.id and \ + len(lots) < inv_line.quantity: + lot.write({'invoice_line_id': inv_line.id}) + return res diff --git a/crm_rma_prodlot_invoice/models/stock_picking.py b/crm_rma_prodlot_invoice/models/stock_picking.py new file mode 100644 index 00000000..3068a252 --- /dev/null +++ b/crm_rma_prodlot_invoice/models/stock_picking.py @@ -0,0 +1,54 @@ +# -*- 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 . +# +############################################################################## + +from openerp import api, models + + +class StockPicking(models.Model): + + _inherit = 'stock.picking' + + @api.multi + def action_invoice_create(self, journal_id, + group=False, type='out_invoice'): + invoices = super(StockPicking, self).\ + action_invoice_create(journal_id=journal_id, + group=group, + type=type) + if type == 'out_invoice': + prodlot_obj = self.env['stock.production.lot'] + for picking in self: + for move in picking.move_lines: + if move and move.quant_ids: + lot = move.quant_ids[0].lot_id + if lot.invoice_line_id: + continue + for inv_id in invoices: + for inv_line in self.env['account.invoice'].\ + browse(inv_id).invoice_line: + lots = prodlot_obj.search([('invoice_line_id', + '=', + inv_line.id)]) + if inv_line.product_id.id == \ + lot.product_id.id and \ + len(lots) < inv_line.quantity: + lot.write({'invoice_line_id': inv_line.id}) + return invoices diff --git a/crm_rma_prodlot_invoice/models/stock_production_lot.py b/crm_rma_prodlot_invoice/models/stock_production_lot.py new file mode 100644 index 00000000..0cbceb0a --- /dev/null +++ b/crm_rma_prodlot_invoice/models/stock_production_lot.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2015 Vauxoo +# Author: Yanina Aular, Osval Reyes +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import _, api, fields, models + + +class StockProductionLot(models.Model): + + _inherit = 'stock.production.lot' + + invoice_line_id = fields.Many2one('account.invoice.line', + string='Customer Invoice Line', + help="Invoice Line Of " + "Product to Customer Invoice") + + lot_complete_name = fields.Char(compute="_get_lot_complete_name", + string="Complete Lot Name") + + @api.depends('invoice_line_id', 'name') + def _get_lot_complete_name(self): + name = _("%s - Lot Number: %s - %s") % \ + (self.invoice_line_id.invoice_id.number, + self.name or _('No lot number'), + self.invoice_line_id.name) + return name diff --git a/crm_rma_prodlot_invoice/models/stock_transfer_details.py b/crm_rma_prodlot_invoice/models/stock_transfer_details.py new file mode 100644 index 00000000..32e25ec3 --- /dev/null +++ b/crm_rma_prodlot_invoice/models/stock_transfer_details.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2015 Vauxoo +# Author: Yanina Aular, Osval Reyes +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from openerp import api, models + + +class StockTransferDetails(models.TransientModel): + + _inherit = 'stock.transfer_details' + + @api.multi + def do_detailed_transfer(self): + """ + When incoming type transfer are made and stock move have serial/lot + number, the supplier is assigned to the serial/lot number taken from + picking. + @return: do_detailed_transfer boolean results + """ + res = super(StockTransferDetails, self).do_detailed_transfer() + + picking_ids = self.env['stock.picking'].browse(self.picking_id.id) + order = picking_ids.sale_id + move_ids = order.mapped('picking_ids.move_lines') + invoice_lines = order.mapped('invoice_ids.invoice_line') + + if not invoice_lines or not move_ids: + return res + + for inv_line in invoice_lines: + for mov in move_ids: + + quants = mov.quant_ids + if not quants: + continue + + lots = list(set([qua.lot_id for qua in quants])) + for lot in lots: + + lots_with_inv_line = self.env['stock.production.lot'].\ + search([('invoice_line_id', '=', + inv_line.id)]) + + if not lot.invoice_line_id and \ + inv_line.product_id.id == lot.product_id.id and \ + len(lots_with_inv_line) < inv_line.quantity: + lot.write({'invoice_line_id': inv_line.id}) + return res diff --git a/crm_rma_prodlot_invoice/tests/__init__.py b/crm_rma_prodlot_invoice/tests/__init__.py new file mode 100644 index 00000000..790239c9 --- /dev/null +++ b/crm_rma_prodlot_invoice/tests/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2015 Vauxoo +# Author: Yanina Aular, Osval Reyes +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import test_crm_rma_prodlot_invoice diff --git a/crm_rma_prodlot_invoice/tests/test_crm_rma_prodlot_invoice.py b/crm_rma_prodlot_invoice/tests/test_crm_rma_prodlot_invoice.py new file mode 100644 index 00000000..c58d34eb --- /dev/null +++ b/crm_rma_prodlot_invoice/tests/test_crm_rma_prodlot_invoice.py @@ -0,0 +1,236 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2015 Vauxoo +# Author: Yanina Aular, Osval Reyes +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.tests.common import TransactionCase +from datetime import date +from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT + + +class TestCrmRmaProdLotInvoice(TransactionCase): + + """ + Test Cases + """ + + def setUp(self): + super(TestCrmRmaProdLotInvoice, self).setUp() + self.sale_order = self.env['sale.order'] + self.partner_id = self.env['res.partner'].browse( + self.ref('base.res_partner_2')) + self.product_id = self.env['product.product'].\ + browse(self.ref('product.product_product_8')) + + date_start = date.today().replace(day=1, month=1).strftime('%Y-%m-%d') + self.period_id = self.env['account.fiscalyear'].search( + [('date_start', '=', date_start)]).period_ids[8] + + self.pay_account_id = self.env['account.account'].\ + browse(self.ref("account.cash")) + self.journal_id = self.env['account.journal'].\ + browse(self.ref("account.bank_journal")) + self.wizard = self.env['stock.transfer_details'] + self.wizard_item = self.env['stock.transfer_details_items'] + self.production_lot = self.env['stock.production.lot'] + self.purchase_order = self.env['purchase.order'] + self.picking = self.env['stock.picking'] + + def create_sale_order(self, invoicing_rule='manual'): + # Create a sale order manual + sale_order_id = self.sale_order.create({ + 'partner_id': self.partner_id.id, + 'client_order_ref': 'TEST_SO', + 'order_policy': invoicing_rule, + 'order_line': [(0, 0, { + 'product_id': self.product_id.id, + 'product_uom_qty': 1 + })] + }) + + sale_order_id.action_button_confirm() + + return sale_order_id + + def create_purchase_order(self): + purchase_order_id = self.purchase_order.create({ + 'partner_id': self.ref('base.res_partner_1'), + 'location_id': self.ref('stock.picking_type_in'), + 'pricelist_id': 1, + 'order_line': [(0, 0, { + 'name': self.product_id.name, + 'product_id': self.product_id.id, + 'price_unit': self.product_id.list_price, + 'product_qty': 1, + 'date_planned': date.today().replace(day=31, month=12). + strftime(DEFAULT_SERVER_DATETIME_FORMAT), + })] + }) + + purchase_order_id.wkf_confirm_order() + self.assertEquals(purchase_order_id.state, 'confirmed') + + purchase_order_id.action_invoice_create() + purchase_order_id.invoice_ids.invoice_validate() + purchase_order_id.action_picking_create() + self.assertEquals(1, len(self.picking. + search([('origin', '=', + purchase_order_id.name)]))) + return purchase_order_id + + def do_whole_transfer_process(self, lot_id, picking_ids): + """ + Do transfer process + @param picking_ids: picking record set to be transfers + @return Returns production lots ids for outside use/verification + """ + for picking_id in picking_ids: + + picking_id.force_assign() + # create wizard + wizard_id = self.wizard.create({ + 'picking_id': picking_id.id, + }) + + # make the transfers + for move_id in picking_id.move_lines: + + self.wizard_item.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': lot_id and lot_id.id or False, + 'product_uom_id': move_id.product_uom.id, + }) + + wizard_id.do_detailed_transfer() + + def get_invoices_paid(self, invoice_ids=False): + for invoice_id in invoice_ids: + # check if a journal entry have been created + self.assertTrue(invoice_id.move_id) + + invoice_id.pay_and_reconcile( + invoice_id.amount_total, self.pay_account_id.id, + self.period_id.id, self.journal_id.id, + self.pay_account_id.id, + self.period_id.id, self.journal_id.id, + name="Payment for Invoice %s" % (invoice_id.name)) + + self.assertEqual(invoice_id.state, 'paid') + + def test_01_prodlot_invoice(self): + """ + A Sale Order for a product which origin has a production lot number + from a incoming picking. + """ + purchase_order_id = self.create_purchase_order() + + lot_id = self.production_lot.create({ + 'name': 'Lot for %s' % (purchase_order_id.name), + 'product_id': self.product_id.id, + }) + + self.do_whole_transfer_process( + lot_id=lot_id, + picking_ids=purchase_order_id.picking_ids) + sale_order_id = self.create_sale_order('prepaid') + + sale_order_id.action_invoice_create() + self.assertTrue(sale_order_id.invoice_ids) + invoice_id = sale_order_id.invoice_ids + invoice_id.signal_workflow('invoice_open') + + self.get_invoices_paid(invoice_ids=sale_order_id.invoice_ids) + + # Check if sale order is marked as invoiced, the only way to + # became true is when its invoices have been paid + self.assertTrue(sale_order_id.invoiced) + + self.do_whole_transfer_process(lot_id=lot_id, + picking_ids=sale_order_id.picking_ids) + + # check if invoice line if is set to the lot + self.assertTrue(lot_id.invoice_line_id) + + def test_02_prodlot_invoice(self): + """ + A Sale Order for a product which origin has a production lot number + from a incoming picking. + """ + purchase_order_id = self.create_purchase_order() + + lot_id = self.production_lot.create({ + 'name': 'Lot for %s' % (purchase_order_id.name), + 'product_id': self.product_id.id, + }) + lot_id._get_lot_complete_name() + + self.do_whole_transfer_process( + lot_id=lot_id, + picking_ids=purchase_order_id.picking_ids) + sale_order_id = self.create_sale_order('manual') + + self.do_whole_transfer_process(lot_id=lot_id, + picking_ids=sale_order_id.picking_ids) + + sale_order_id.action_invoice_create() + self.assertTrue(sale_order_id.invoice_ids) + + # check if lot_id have been set when creating invoice lines + self.assertTrue(lot_id.invoice_line_id) + + # check if lot invoice line belongs to this sale order by its origin + self.assertEquals(sale_order_id.name, lot_id.invoice_line_id.origin) + + def test_03_prodlot_invoice(self): + """ + A Sale Order for a product which origin has a production lot number + from a incoming picking. + """ + purchase_order_id = self.create_purchase_order() + + lot_id = self.production_lot.create({ + 'name': 'Lot for %s' % (purchase_order_id.name), + 'product_id': self.product_id.id, + }) + + self.do_whole_transfer_process( + lot_id=lot_id, + picking_ids=purchase_order_id.picking_ids) + sale_order_id = self.create_sale_order('manual') + + sale_order_id.action_invoice_create() + self.assertTrue(sale_order_id.invoice_ids) + invoice_id = sale_order_id.invoice_ids + invoice_id.signal_workflow('invoice_open') + + self.get_invoices_paid(invoice_ids=sale_order_id.invoice_ids) + + self.do_whole_transfer_process(lot_id=lot_id, + picking_ids=sale_order_id.picking_ids) + + # check if lot_id have been set when creating invoice lines + self.assertTrue(lot_id.invoice_line_id) + + # check if lot invoice line belongs to this sale order by its origin + self.assertEquals(sale_order_id.name, lot_id.invoice_line_id.origin) diff --git a/crm_rma_prodlot_invoice/views/stock_production_lot.xml b/crm_rma_prodlot_invoice/views/stock_production_lot.xml new file mode 100644 index 00000000..d22e5de0 --- /dev/null +++ b/crm_rma_prodlot_invoice/views/stock_production_lot.xml @@ -0,0 +1,15 @@ + + + + + stock.production.lot.view + stock.production.lot + + + + + + + + +