diff --git a/stock_optional_valuation/AUTHORS.txt b/stock_optional_valuation/AUTHORS.txt new file mode 100644 index 000000000..ce64f52de --- /dev/null +++ b/stock_optional_valuation/AUTHORS.txt @@ -0,0 +1,2 @@ +Lorenzo Battistini +Leonardo Pistone diff --git a/stock_optional_valuation/__init__.py b/stock_optional_valuation/__init__.py new file mode 100644 index 000000000..eeb857e66 --- /dev/null +++ b/stock_optional_valuation/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2013 Agile Business Group sagl () +# +# 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 stock diff --git a/stock_optional_valuation/__openerp__.py b/stock_optional_valuation/__openerp__.py new file mode 100644 index 000000000..f15fef4c6 --- /dev/null +++ b/stock_optional_valuation/__openerp__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2013 Agile Business Group sagl () +# +# 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': "Stock optional valuation", + 'version': '0.1', + 'category': 'Warehouse Management', + 'description': """ +You can choose which stock moves have to generate inventory valuation accounting entries, by specifying it in the location form. +""", + 'author': 'Agile Business Group', + 'website': 'http://www.agilebg.com', + 'license': 'AGPL-3', + "depends": ['stock'], + "data": [ + "stock_view.xml", + ], + "demo": [], + 'test': [ + 'test/stock.yml' + ], + "active": False, + "installable": True +} diff --git a/stock_optional_valuation/i18n/stock_optional_valuation.pot b/stock_optional_valuation/i18n/stock_optional_valuation.pot new file mode 100644 index 000000000..7dadaf212 --- /dev/null +++ b/stock_optional_valuation/i18n/stock_optional_valuation.pot @@ -0,0 +1,42 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * stock_optional_valuation +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-10-17 15:07+0000\n" +"PO-Revision-Date: 2013-10-17 15:07+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: stock_optional_valuation +#: field:stock.location,consider_internal:0 +msgid "Consider internal" +msgstr "" + +#. module: stock_optional_valuation +#: view:stock.location:0 +msgid "Inventory valuation" +msgstr "" + +#. module: stock_optional_valuation +#: help:stock.location,consider_internal:0 +msgid "Consider as internal location for inventory valuation: stock moves from internal to internal will not generate accounting entries" +msgstr "" + +#. module: stock_optional_valuation +#: model:ir.model,name:stock_optional_valuation.model_stock_location +msgid "Location" +msgstr "" + +#. module: stock_optional_valuation +#: model:ir.model,name:stock_optional_valuation.model_stock_move +msgid "Stock Move" +msgstr "" + diff --git a/stock_optional_valuation/stock.py b/stock_optional_valuation/stock.py new file mode 100644 index 000000000..15b655fc3 --- /dev/null +++ b/stock_optional_valuation/stock.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2013 Agile Business Group sagl () +# +# 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.osv import fields, orm +from openerp.tools.translate import _ + + +class stock_location(orm.Model): + _inherit = "stock.location" + _columns = { + 'consider_internal': fields.boolean('Consider internal', help="Consider as internal location for inventory valuation: stock moves from internal to internal will not generate accounting entries"), + } + + +class stock_move(orm.Model): + _inherit = "stock.move" + + def _create_product_valuation_moves(self, cr, uid, move, context=None): + if (move.location_id.company_id and move.location_dest_id.company_id + and move.location_id.company_id != move.location_dest_id.company_id): + return super(stock_move, self)._create_product_valuation_moves( + cr, uid, move, context=context) + if (move.location_id.usage == 'internal' or + move.location_id.consider_internal) and ( + move.location_dest_id.usage == 'internal' or + move.location_dest_id.consider_internal): + return + return super(stock_move, self)._create_product_valuation_moves( + cr, uid, move, context=context) diff --git a/stock_optional_valuation/stock_view.xml b/stock_optional_valuation/stock_view.xml new file mode 100644 index 000000000..a121b5629 --- /dev/null +++ b/stock_optional_valuation/stock_view.xml @@ -0,0 +1,17 @@ + + + + + stock.location.form + stock.location + + + + + + + + + + + diff --git a/stock_optional_valuation/test/stock.yml b/stock_optional_valuation/test/stock.yml new file mode 100644 index 000000000..f91ebee10 --- /dev/null +++ b/stock_optional_valuation/test/stock.yml @@ -0,0 +1,95 @@ +- + I need a product with real time valuation. +- + !record {model: product.product, id: product.product_product_24}: + valuation: real_time + property_stock_account_input: account.o_expense + property_stock_account_output: account.o_income +- + !record {model: stock.picking, id: outgoing_shipment}: + type: out +- + !record {model: stock.move, id: outgoing_shipment_card}: + picking_id: outgoing_shipment + product_id: product.product_product_24 + product_qty: 2.0 + location_id: stock.stock_location_stock + location_dest_id: stock.location_inventory +- + I confirm outgoing shipment of 2 Graphics Cards from Stock to Inventory Loss +- + !workflow {model: stock.picking, action: button_confirm, ref: outgoing_shipment} +- + I process the picking +- + !python {model: stock.partial.picking}: | + context.update({'active_model': 'stock.picking', 'active_id': ref('outgoing_shipment'), 'active_ids': [ref('outgoing_shipment')]}) +- + !record {model: stock.partial.picking, id: partial_outgoing}: + move_ids: + - quantity: 2.0 + product_id: product.product_product_24 + product_uom: product.product_uom_unit + move_id: outgoing_shipment_card + location_id: stock.stock_location_stock + location_dest_id: stock.location_inventory +- + !python {model: stock.partial.picking }: | + self.do_partial(cr, uid, [ref('partial_outgoing')], context=context) +- + My picking should have generated a Journal Entry with the same name +- + !python {model: stock.picking}: | + picking_name = self.browse(cr, uid, ref('outgoing_shipment'), context=context).name + a_move_obj = self.pool.get('account.move') + # count those + a_move_ids = a_move_obj.search(cr, uid, [('ref', '=', picking_name)]) + assert len(a_move_ids) == 1, "An outgoing picking should generate a Journal Entry" +- + Now I will consider the location to be Internal +- + !record {model: stock.location, id: stock.location_inventory}: + consider_internal: True +- + I repeate the process above. Now no Journal Entry should be generated. +- + !record {model: stock.picking, id: outgoing_shipment_as_internal}: + type: out +- + !record {model: stock.move, id: outgoing_shipment_as_internal_card}: + picking_id: outgoing_shipment_as_internal + product_id: product.product_product_24 + product_qty: 2.0 + location_id: stock.stock_location_stock + location_dest_id: stock.location_inventory + +- + I confirm outgoing shipment of 2 Graphics Cards from Stock to Inventory Loss +- + !workflow {model: stock.picking, action: button_confirm, ref: outgoing_shipment_as_internal} +- + I process the picking +- + !python {model: stock.partial.picking}: | + context.update({'active_model': 'stock.picking', 'active_id': ref('outgoing_shipment_as_internal'), 'active_ids': [ref('outgoing_shipment_as_internal')]}) +- + !record {model: stock.partial.picking, id: partial_outgoing}: + move_ids: + - quantity: 2.0 + product_id: product.product_product_24 + product_uom: product.product_uom_unit + move_id: outgoing_shipment_as_internal_card + location_id: stock.stock_location_stock + location_dest_id: stock.location_inventory +- + !python {model: stock.partial.picking }: | + self.do_partial(cr, uid, [ref('partial_outgoing')], context=context) +- + Now there should be no Journal Entries with the same name +- + !python {model: stock.picking }: | + picking_name = self.browse(cr, uid, ref('outgoing_shipment_as_internal'), context=context).name + a_move_obj = self.pool.get('account.move') + # count those + a_move_ids = a_move_obj.search(cr, uid, [('ref', '=', picking_name)]) + assert len(a_move_ids) == 0, "Locations treater as internal should generate no Journal Entries"