diff --git a/purchase_date_planned_update/__init__.py b/purchase_date_planned_update/__init__.py new file mode 100644 index 0000000..3b4c3ed --- /dev/null +++ b/purchase_date_planned_update/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import wizard diff --git a/purchase_date_planned_update/__openerp__.py b/purchase_date_planned_update/__openerp__.py new file mode 100644 index 0000000..4f73a85 --- /dev/null +++ b/purchase_date_planned_update/__openerp__.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Purchase Date Planned Update module for Odoo +# Copyright (C) 2015-2016 Akretion (http://www.akretion.com) +# @author Alexis de Lattre +# +# 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': 'Purchase Date Planned Update', + 'version': '0.1', + 'category': 'Purchase', + 'license': 'AGPL-3', + 'summary': "Update of date planned on PO line updates date on stock move", + 'description': """ +Purchase Date Planned Update +============================ + +This module adds a wizard on confirmed purchase orders to update the date planned on one or several purchase order lines: it will update the scheduled date of the purchase order lines and the expected date of the related stock moves that are not already received. + +This module has been written by Alexis de Lattre from Akretion +. + """, + 'author': 'Akretion', + 'website': 'http://www.akretion.com', + 'depends': ['purchase'], + 'data': [ + 'wizard/purchase_date_planned_update_view.xml', + 'purchase_view.xml', + ], + 'installable': True, +} diff --git a/purchase_date_planned_update/purchase.py b/purchase_date_planned_update/purchase.py new file mode 100644 index 0000000..6c3ce8e --- /dev/null +++ b/purchase_date_planned_update/purchase.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Purchase Date Planned Update module for Odoo +# Copyright (C) 2015 Akretion (http://www.akretion.com) +# @author Alexis de Lattre +# @author Sébastien Beau +# +# 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 orm +from openerp.tools.translate import _ +from openerp import SUPERUSER_ID + + +class PurchaseOrderLine(orm.Model): + _inherit = 'purchase.order.line' + + def write(self, cr, uid, ids, vals, context=None): + if vals.get('date_planned'): + if not isinstance(ids, list): + ids = [ids] + polines = self.browse(cr, uid, ids, context=context) + move_ids = [] + for poline in polines: + # Add msg in chatter + poline.order_id.message_post(_( + "Updated Scheduled Date of line %s from %s " + "to %s" + % (poline.name, poline.date_planned, + vals['date_planned']))) + move_ids += [ + sm.id for sm in poline.move_ids if sm.state != 'done'] + if move_ids: + # update related stock move + self.pool['stock.move'].write(cr, SUPERUSER_ID, move_ids, { + 'date_expected': vals['date_planned'], + }, context=context) + return super(PurchaseOrderLine, self).write( + cr, uid, ids, vals, context=context) diff --git a/purchase_date_planned_update/purchase_view.xml b/purchase_date_planned_update/purchase_view.xml new file mode 100644 index 0000000..19be085 --- /dev/null +++ b/purchase_date_planned_update/purchase_view.xml @@ -0,0 +1,26 @@ + + + + + + + + date_planned_update.purchase.order.form + purchase.order + + + + + + + + + diff --git a/purchase_date_planned_update/wizard/__init__.py b/purchase_date_planned_update/wizard/__init__.py new file mode 100644 index 0000000..64bb52f --- /dev/null +++ b/purchase_date_planned_update/wizard/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import purchase_date_planned_update diff --git a/purchase_date_planned_update/wizard/purchase_date_planned_update.py b/purchase_date_planned_update/wizard/purchase_date_planned_update.py new file mode 100644 index 0000000..96c0bb3 --- /dev/null +++ b/purchase_date_planned_update/wizard/purchase_date_planned_update.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Purchase Date Planned Update module for Odoo +# Copyright (C) 2015-2016 Akretion (http://www.akretion.com) +# @author Alexis de Lattre +# +# 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 models, fields, api, _ +from openerp.exceptions import Warning as UserError +import openerp.addons.decimal_precision as dp + + +class PurchaseDatePlannedUpdate(models.TransientModel): + _name = 'purchase.date.planned.update' + _description = 'Update Scheduled Date on PO' + + date_planned = fields.Date(string='New Scheduled Date For All Lines') + line_ids = fields.One2many( + 'purchase.line.date.planned.update', 'parent_id', string="Lines") + + @api.model + def default_get(self, fields): + res = super(PurchaseDatePlannedUpdate, self).default_get(fields) + po = self.env['purchase.order'].browse(self._context['active_id']) + lines = [] + for line in po.order_line: + if line.move_ids: + if all([move.state == 'done' for move in line.move_ids]): + continue + lines.append({ + 'purchase_line_id': line.id, + 'product_id': line.product_id.id, + 'name': line.name, + 'product_qty': line.product_qty, + 'date_planned': line.date_planned, + 'product_uom': line.product_uom.id, + 'price_unit': line.price_unit, + }) + if not lines: + raise UserError(_( + "All purchase order lines have been fully received.")) + res.update(line_ids=lines) + return res + + @api.onchange('date_planned') + def date_planned_change(self): + if self.date_planned: + for line in self.line_ids: + line.date_planned = self.date_planned + + @api.multi + def run(self): + self.ensure_one() + for wline in self.line_ids: + if wline.date_planned != wline.purchase_line_id.date_planned: + pline = wline.purchase_line_id + pline.order_id.message_post(_( + "Updated Scheduled Date of line %s from %s " + "to %s") + % (pline.name, pline.date_planned, wline.date_planned)) + # Update PO line + pline.date_planned = wline.date_planned + # Update move lines + if pline.move_ids: + moves = pline.move_ids.filtered( + lambda x: x.state != 'done') + moves.write({'date_expected': wline.date_planned}) + return True + + +class PurchaseLineDatePlannedUpdate(models.TransientModel): + _name = 'purchase.line.date.planned.update' + _description = 'Purchase Line Date Planned Update' + + parent_id = fields.Many2one( + 'purchase.date.planned.update', string='Parent') + purchase_line_id = fields.Many2one( + 'purchase.order.line', string='Purchase Order Line', readonly=True) + product_id = fields.Many2one( + 'product.product', string='Product', readonly=True) + name = fields.Text('Description', readonly=True) + product_qty = fields.Float( + string='Quantity', digits=dp.get_precision('Product Unit of Measure'), + readonly=True) + date_planned = fields.Date(string='Scheduled Date', required=True) + product_uom = fields.Many2one( + 'product.uom', string='Product Unit of Measure', readonly=True) + price_unit = fields.Float( + string='Unit Price', readonly=True, + digits=dp.get_precision('Product Price')) diff --git a/purchase_date_planned_update/wizard/purchase_date_planned_update_view.xml b/purchase_date_planned_update/wizard/purchase_date_planned_update_view.xml new file mode 100644 index 0000000..6213181 --- /dev/null +++ b/purchase_date_planned_update/wizard/purchase_date_planned_update_view.xml @@ -0,0 +1,49 @@ + + + + + + + + purchase_date_planned_update_form + purchase.date.planned.update + +
+ + +
+
+
+
+
+ + + Update Scheduled Date + purchase.date.planned.update + form + new + + +
+