diff --git a/mrp_secondary_uom/README.rst b/mrp_secondary_uom/README.rst new file mode 100644 index 000000000..e203ea921 --- /dev/null +++ b/mrp_secondary_uom/README.rst @@ -0,0 +1,29 @@ +====================== +MRP - Secondary UoM v8 +====================== + +This module Manage the Manufacturing process with secondary UoM. + +Installation +============ + +Just select it from available modules to install it, there is no need to extra installations. + +Configuration +============= + +After installing this module, Go to Setting->Configuration->Warehouse->Location & Warehouse-> +Enable the different units of measure for products. + +Features +======== + +* Allows to manage MRP with Secondary UoM. +* Products to Produce With Secondary UoM. +* Produced Products With Secondary UoM. + +Credits +======= +Developer: Nikhil krishnan @ cybrosys, nikhil@cybrosys.in + + diff --git a/mrp_secondary_uom/__init__.py b/mrp_secondary_uom/__init__.py new file mode 100644 index 000000000..b56261568 --- /dev/null +++ b/mrp_secondary_uom/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2009-TODAY Cybrosys Technologies(). +# Author: Nikhil krishnan() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## + +import models diff --git a/mrp_secondary_uom/__openerp__.py b/mrp_secondary_uom/__openerp__.py new file mode 100644 index 000000000..e0c3399ca --- /dev/null +++ b/mrp_secondary_uom/__openerp__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2009-TODAY Cybrosys Technologies(). +# Author: Nikhil krishnan() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## + +{ + 'name': 'MRP - Secondary UoM', + 'version': '8.0.1.0.0', + 'category': 'Manufacturing', + 'summary': 'Secondary UoM in Manufacturing order', + 'description': """ +Manage the Manufacturing process with secondary UoM +=================================================== +This module allows you to cover planning, ordering, stocks and the manufacturing with a Secondary UoM. It handles the +Products to Produce & Produced Products according to the production with Secondary UoM +----------------------------------------------------------------------------------------- +* Allows to manage MRP with Secondary UoM +* Products to Produce With Secondary UoM +* Produced Products With Secondary UoM +""", + 'author': 'Cybrosys Techno Solutions', + 'website': "http://www.yourcompany.com", + 'company': 'Cybrosys Techno Solutions', + 'depends': ['mrp'], + 'data': ['views/mrp_sec_uom.xml'], + 'images': ['static/description/banner.jpg'], + 'license': 'AGPL-3', + 'installable': True, + 'application': False, +} diff --git a/mrp_secondary_uom/models/__init__.py b/mrp_secondary_uom/models/__init__.py new file mode 100644 index 000000000..8cb045157 --- /dev/null +++ b/mrp_secondary_uom/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2009-TODAY Cybrosys Technologies(). +# Author: Nikhil krishnan() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +import mrp_sec_uom +import change_production_qnty diff --git a/mrp_secondary_uom/models/change_production_qnty.py b/mrp_secondary_uom/models/change_production_qnty.py new file mode 100644 index 000000000..ea1bd717c --- /dev/null +++ b/mrp_secondary_uom/models/change_production_qnty.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2009-TODAY Cybrosys Technologies(). +# Author: Nikhil krishnan() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## + +from openerp.osv import fields, osv +from openerp.tools.translate import _ + + +class ChangeProductionQty(osv.osv_memory): + _inherit = 'change.production.qty' + + _columns = { + 'mrp_sec_qty': fields.float('Product Secondary Qty'), + 'mrp_sec_uom': fields.many2one('product.uom', 'Secondary Unit'), + } + + def default_get(self, cr, uid, fields, context=None): + if context is None: + context = {} + res = super(ChangeProductionQty, self).default_get(cr, uid, fields, context=context) + prod_obj = self.pool.get('mrp.production') + prod = prod_obj.browse(cr, uid, context.get('active_id'), context=context) + if 'product_qty' in fields: + res.update({'product_qty': prod.product_qty}) + if 'mrp_sec_qty' in fields: + res.update({'mrp_sec_qty': prod.mrp_sec_qty}) + if 'mrp_sec_uom' in fields: + res.update({'mrp_sec_uom': prod.mrp_sec_uom.id}) + return res + + def _update_product_to_produce(self, cr, uid, prod, qty, sec_qty, sec_uom, context=None): + move_lines_obj = self.pool.get('stock.move') + ratio = sec_qty/qty + for m in prod.move_created_ids: + move_lines_obj.write(cr, uid, [m.id], {'product_uom_qty': qty, 'stock_move_sec_uom': sec_uom.id, + 'stock_move_sec_qty': sec_qty, 'ratio_sec_uom': ratio}) + + def change_prod_qty(self, cr, uid, ids, context=None): + + """ + Changes the Quantity of Product, and Secondary Quantity of Product And Uom + @param self: The object pointer. + @param cr: A database cursor + @param uid: ID of the user currently logged in + @param ids: List of IDs selected + @param context: A standard dictionary + @return: + """ + record_id = context and context.get('active_id', False) + assert record_id, _('Active Id not found') + prod_obj = self.pool.get('mrp.production') + bom_obj = self.pool.get('mrp.bom') + move_obj = self.pool.get('stock.move') + for wiz_qty in self.browse(cr, uid, ids, context=context): + prod = prod_obj.browse(cr, uid, record_id, context=context) + print "LLLL", prod + prod_obj.write(cr, uid, [prod.id], {'product_qty': wiz_qty.product_qty, + 'mrp_sec_qty': wiz_qty.mrp_sec_qty, + 'mrp_sec_uom': wiz_qty.mrp_sec_uom.id, + }) + prod_obj.action_compute(cr, uid, [prod.id]) + + for move in prod.move_lines: + bom_point = prod.bom_id + bom_id = prod.bom_id.id + if not bom_point: + bom_id = bom_obj._bom_find(cr, uid, product_id=prod.product_id.id, context=context) + if not bom_id: + raise osv.except_osv(_('Error!'), _("Cannot find bill of material for this product.")) + prod_obj.write(cr, uid, [prod.id], {'bom_id': bom_id}) + bom_point = bom_obj.browse(cr, uid, [bom_id])[0] + + if not bom_id: + raise osv.except_osv(_('Error!'), _("Cannot find bill of material for this product.")) + + factor = prod.product_qty * prod.product_uom.factor / bom_point.product_uom.factor + product_details, workcenter_details = \ + bom_obj._bom_explode(cr, uid, bom_point, prod.product_id, factor / bom_point.product_qty, [], context=context) + for r in product_details: + if r['product_id'] == move.product_id.id: + move_obj.write(cr, uid, [move.id], {'product_uom_qty': r['product_qty']}) + if prod.move_prod_id: + print "LOLLOLprod.move_prod_idprod.move_prod_idOLO", prod.move_prod_id + move_obj.write(cr, uid, [prod.move_prod_id.id], {'product_uom_qty': wiz_qty.product_qty}) + self._update_product_to_produce(cr, uid, prod, wiz_qty.product_qty, wiz_qty.mrp_sec_qty, + wiz_qty.mrp_sec_uom, context=context) + return {} diff --git a/mrp_secondary_uom/models/mrp_sec_uom.py b/mrp_secondary_uom/models/mrp_sec_uom.py new file mode 100644 index 000000000..a9f514b76 --- /dev/null +++ b/mrp_secondary_uom/models/mrp_sec_uom.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2009-TODAY Cybrosys Technologies(). +# Author: Nikhil krishnan() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## + +from openerp import models, fields, api + + +class MRPSecUOM(models.Model): + _inherit = 'mrp.production' + + # name = fields.Char('Reference', required=True, readonly=True, states={'draft': [('readonly', False)]}, copy=False) + + def compute_to_produce_product(self): + for s in self: + if s.move_created_ids: + for moves in s.move_created_ids: + s.to_produce_product += moves.product_uom_qty + else: + s.to_produce_product = 0 + + def compute_produced_product(self): + for s in self: + if s.move_created_ids2: + for moves in s.move_created_ids2: + if moves.state != 'cancel': + s.produced_product += moves.product_uom_qty + else: + s.produced_product = 0 + + def compute_to_produce_product2(self): + for s in self: + if s.move_created_ids: + for moves in s.move_created_ids: + s.to_produce_product2 += moves.stock_move_sec_qty + else: + s.to_produce_product2 = 0 + + def compute_produced_product2(self): + for s in self: + if s.move_created_ids2: + for moves in s.move_created_ids2: + s.produced_product2 += moves.stock_move_sec_qty + else: + s.produced_product2 = 0 + + mrp_sec_qty = fields.Float('Secondary Quantity', readonly=True, states={'draft': [('readonly', False)]}) + mrp_sec_uom = fields.Many2one('product.uom', 'Secondary Unit', readonly=True, + states={'draft': [('readonly', False)]}) + to_produce_product = fields.Float('Product To produce', compute="compute_to_produce_product") + produced_product = fields.Float('Produced Products', compute="compute_produced_product") + to_produce_product2 = fields.Float('Product To produce(2ndry)') + produced_product2 = fields.Float('Produced Products(2ndry)') + + def _make_production_produce_line(self, cr, uid, production, context=None): + + stock_move = self.pool.get('stock.move') + proc_obj = self.pool.get('procurement.order') + source_location_id = production.product_id.property_stock_production.id + destination_location_id = production.location_dest_id.id + procs = proc_obj.search(cr, uid, [('production_id', '=', production.id)], context=context) + procurement = procs and\ + proc_obj.browse(cr, uid, procs[0], context=context) or False + if production.product_qty: + ratio = production.mrp_sec_qty/production.product_qty + else: + ratio = 0 + data = { + 'name': production.name, + 'date': production.date_planned, + 'product_id': production.product_id.id, + 'product_uom': production.product_uom.id, + 'stock_move_sec_qty': production.mrp_sec_qty, + 'stock_move_sec_uom': production.mrp_sec_uom.id, + 'ratio_sec_uom': ratio, + 'product_uom_qty': production.product_qty, + 'product_uos_qty': production.product_uos and production.product_uos_qty or False, + 'product_uos': production.product_uos and production.product_uos.id or False, + 'location_id': source_location_id, + 'location_dest_id': destination_location_id, + 'move_dest_id': production.move_prod_id.id, + 'procurement_id': procurement and procurement.id, + 'company_id': production.company_id.id, + 'production_id': production.id, + 'origin': production.name, + 'group_id': procurement and procurement.group_id.id, + } + move_id = stock_move.create(cr, uid, data, context=context) + # a phantom bom cannot be used in mrp order so it's ok to assume the list returned by action_confirm + # is 1 element long, so we can take the first. + return stock_move.action_confirm(cr, uid, [move_id], context=context)[0] + + +class StockMoveSecUOM(models.Model): + _inherit = 'stock.move' + + stock_move_sec_qty = fields.Float('2ndry Quantity', compute='compute_stock_move_sec_qty') + stock_move_sec_uom = fields.Many2one('product.uom', '2ndry Unit') + ratio_sec_uom = fields.Float('Ratio 2ndry Quantity') + + def compute_stock_move_sec_qty(self): + for rec in self: + rec.stock_move_sec_qty = rec.ratio_sec_uom * rec.product_qty + + +class MRPProductProduceSecUOM(models.TransientModel): + _inherit = 'mrp.product.produce' + + def _get_product_uom(self, cr, uid, context=None): + + if context is None: + context = {} + prod = self.pool.get('mrp.production').browse(cr, uid, + context['active_id'], context=context) + return prod.product_uom.id + + def _get_product_produce_sec_uom(self, cr, uid, context=None): + + if context is None: + context = {} + prod = self.pool.get('mrp.production').browse(cr, uid, + context['active_id'], context=context) + return prod.mrp_sec_uom.id + + def _get_product_produce_sec_qty(self, cr, uid, context=None): + + if context is None: + context = {} + prod = self.pool.get('mrp.production').browse(cr, uid, + context['active_id'], context=context) + done = 0.0 + for move in prod.move_created_ids2: + if move.product_id == prod.product_id: + if not move.scrapped: + done += move.product_uom_qty + select_qty = prod.product_qty - done + return (prod.mrp_sec_qty/prod.product_qty) * select_qty + # return prod.to_produce_product2 + + product_uom = fields.Many2one('product.uom') + product_produce_sec_qty = fields.Float('2ndry Quantity') + product_produce_sec_uom = fields.Many2one('product.uom', '2ndry UoM') + + _defaults = { + 'product_uom': _get_product_uom, + 'product_produce_sec_qty': _get_product_produce_sec_qty, + 'product_produce_sec_uom': _get_product_produce_sec_uom, + } + + @api.multi + def do_produce(self): + result = super(MRPProductProduceSecUOM, self).do_produce() + mrp_prod_obj = self.env['mrp.production'].browse( + self.env.context['active_id']) + for data in self: + to_produce = mrp_prod_obj.to_produce_product2 - data.product_produce_sec_qty + produced = mrp_prod_obj.produced_product2 + data.product_produce_sec_qty + mrp_prod_obj.write({'to_produce_product2': to_produce}) + mrp_prod_obj.write({'produced_product2': produced}) + return result + + def on_change_qty(self, cr, uid, ids, product_qty, consume_lines, context=None): + res = super(MRPProductProduceSecUOM, self).on_change_qty(cr, uid, ids, product_qty, consume_lines, + context=context) + rec = self.browse(cr, uid, context['active_id'], context=context) + prod = self.pool.get('mrp.production').browse(cr, uid, context['active_id'], context=context) + + if prod.product_qty != 0: + valss = (prod.mrp_sec_qty/prod.product_qty) * product_qty + res['value']['product_produce_sec_qty'] = valss + return res + diff --git a/mrp_secondary_uom/static/description/1.png b/mrp_secondary_uom/static/description/1.png new file mode 100644 index 000000000..6c2823975 Binary files /dev/null and b/mrp_secondary_uom/static/description/1.png differ diff --git a/mrp_secondary_uom/static/description/2.png b/mrp_secondary_uom/static/description/2.png new file mode 100644 index 000000000..062f30468 Binary files /dev/null and b/mrp_secondary_uom/static/description/2.png differ diff --git a/mrp_secondary_uom/static/description/3.jpg b/mrp_secondary_uom/static/description/3.jpg new file mode 100644 index 000000000..8af8d2f32 Binary files /dev/null and b/mrp_secondary_uom/static/description/3.jpg differ diff --git a/mrp_secondary_uom/static/description/4.png b/mrp_secondary_uom/static/description/4.png new file mode 100644 index 000000000..c08a12610 Binary files /dev/null and b/mrp_secondary_uom/static/description/4.png differ diff --git a/mrp_secondary_uom/static/description/5.png b/mrp_secondary_uom/static/description/5.png new file mode 100644 index 000000000..61f94a526 Binary files /dev/null and b/mrp_secondary_uom/static/description/5.png differ diff --git a/mrp_secondary_uom/static/description/6.jpg b/mrp_secondary_uom/static/description/6.jpg new file mode 100644 index 000000000..f7b8df614 Binary files /dev/null and b/mrp_secondary_uom/static/description/6.jpg differ diff --git a/mrp_secondary_uom/static/description/banner.jpg b/mrp_secondary_uom/static/description/banner.jpg new file mode 100644 index 000000000..0da6606d2 Binary files /dev/null and b/mrp_secondary_uom/static/description/banner.jpg differ diff --git a/mrp_secondary_uom/static/description/cybro_logo.png b/mrp_secondary_uom/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/mrp_secondary_uom/static/description/cybro_logo.png differ diff --git a/mrp_secondary_uom/static/description/icon.png b/mrp_secondary_uom/static/description/icon.png new file mode 100644 index 000000000..65c6a9f52 Binary files /dev/null and b/mrp_secondary_uom/static/description/icon.png differ diff --git a/mrp_secondary_uom/static/description/index.html b/mrp_secondary_uom/static/description/index.html new file mode 100644 index 000000000..660286f78 --- /dev/null +++ b/mrp_secondary_uom/static/description/index.html @@ -0,0 +1,124 @@ +
+
+
+

MRP - Secondary UoM

+

Manage the Manufacturing process with secondary UoM

+

Author: Cybrosys Technologies , www.cybrosys.com

+
+
+

Major Features:

+
    +
  •   Allows to manage MRP with Secondary UoM.
  • +
  •    Products to Produce With Secondary UoM.
  • +
  •    Produced Products With Secondary UoM.
  • +
+
+
+
+ +
+
+
+

+

This module allows you to cover planning, ordering, stocks and the manufacturing with a Secondary + UoM. It handles the Products to Produce & Produced Products according to the production with Secondary UoM.

+

+ +
+
+
+ +
+
+
+

+

As shown here, When we create a MO with a Primary and Secondary Product Quantities and UOMs. After + confirming the MO, MO will change the state to 'Awaiting Raw Materials'. Same time we can see a record + created in 'Products to Produce' with secondary UoM.

+

+
+
+
+ +
+
+
+
+ +
+
+

+

After confirming we can change the Primary Quantity, Secondary Quantity and Secondary UoM. In edit mode there + will be an 'Update' Button to handle the same.

+
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+

+

In production state, when we click on the 'Produce' button, The same window is appear with Secondary + Quantity and UoM.

+

If we Produce Partially, It automatically calculate the Secondary quantity with same ratio.

+

+
+
+
+ +
+
+
+

+

Update the Products to Produce & Produced Products records.

+

+
+ +
+
+ +
+
+
+
+ +
+

Need Any Help?

+ + +
+ + + + + + diff --git a/mrp_secondary_uom/views/mrp_sec_uom.xml b/mrp_secondary_uom/views/mrp_sec_uom.xml new file mode 100644 index 000000000..b03f510d1 --- /dev/null +++ b/mrp_secondary_uom/views/mrp_sec_uom.xml @@ -0,0 +1,57 @@ + + + + + mrp.production.uom.form + mrp.production + + + + + + + + + + + + + + + + + + + + MRP Product Produce + mrp.product.produce + + + + + + + + + + + + + + Change Product Qty + change.production.qty + + + + + + + + + + \ No newline at end of file