diff --git a/manufacturing_indent/README.rst b/manufacturing_indent/README.rst new file mode 100644 index 000000000..76c09d2c6 --- /dev/null +++ b/manufacturing_indent/README.rst @@ -0,0 +1,18 @@ +Indent Management - MRP v10 +=========================== +The aim is to have a complete module to manage all MRP product indents. When we create a MRP +order, it automatically create a indent to the warehouse manager to approve the raw materials. +And also if the Manufacturing team need a product for there internal use, they can also create a +indent to the warehouse team for the same. + +Features +======== + +* MRP indents create automatically. +* Each MRP indent can approve by the warehouse manager. +* Raw materials available only after the approval of indent by warehouse manager. +* Manufacturing Plants need some goods for internal purpose, then they can indent it too with reason. + +Credits +======= +Nikhil Krishnan @ cybrosys, nikhil@cybrosys.in \ No newline at end of file diff --git a/manufacturing_indent/__init__.py b/manufacturing_indent/__init__.py new file mode 100644 index 000000000..db6e2e68e --- /dev/null +++ b/manufacturing_indent/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-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/manufacturing_indent/__manifest__.py b/manufacturing_indent/__manifest__.py new file mode 100644 index 000000000..a2c8462ed --- /dev/null +++ b/manufacturing_indent/__manifest__.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-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': 'Indent Management - MRP', + 'version': '10.0.1.0.0', + 'summary': """Create MRP Indents To Warehouse Team.""", + 'description': """When we create a MRP Order, MRP team need raw material and if we check the availability, + an indnet is created automatically and only Warehouse manager can approve the indent""", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'category': 'Manufacturing', + 'depends': ['stock', 'mrp'], + 'license': 'LGPL-3', + 'data': [ + 'security/ir.model.access.csv', + 'views/mrp_production_views.xml', + 'views/manufacturing_indent_menu.xml', + 'views/stock_indent_menu.xml', + 'views/mrp_indent_sequence.xml', + ], + 'demo': [], + 'images': ['static/description/banner.jpg'], + 'installable': True, + 'auto_install': False, +} diff --git a/manufacturing_indent/__manifest__.py~ b/manufacturing_indent/__manifest__.py~ new file mode 100644 index 000000000..916c60c25 --- /dev/null +++ b/manufacturing_indent/__manifest__.py~ @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-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': 'Indent Management - MRP', + 'version': '10.0.1.0.0', + 'summary': """Manufacturing Team Can Create Indents To Warehouse""", + 'description': """When we create a MRP Order, MRP team need raw material and if we check the availability, + an indnet is created automatically and only Warehouse manager can approve the indent""", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'category': 'Manufacturing', + 'depends': ['stock', 'mrp'], + 'license': 'LGPL-3', + 'data': [ + 'security/ir.model.access.csv', + 'views/mrp_production_views.xml', + 'views/manufacturing_indent_menu.xml', + 'views/stock_indent_menu.xml', + 'views/mrp_indent_sequence.xml', + ], + 'demo': [], + 'images': ['static/description/banner.jpg'], + 'installable': True, + 'auto_install': False, +} diff --git a/manufacturing_indent/models/__init__.py b/manufacturing_indent/models/__init__.py new file mode 100644 index 000000000..17c1bb08c --- /dev/null +++ b/manufacturing_indent/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-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 manufacturing_indent diff --git a/manufacturing_indent/models/manufacturing_indent.py b/manufacturing_indent/models/manufacturing_indent.py new file mode 100644 index 000000000..55afdc951 --- /dev/null +++ b/manufacturing_indent/models/manufacturing_indent.py @@ -0,0 +1,344 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-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 datetime +from datetime import datetime +from odoo import models, fields, api, exceptions, _ +from odoo.exceptions import Warning +from odoo.exceptions import UserError +import odoo.addons.decimal_precision as dp + + +class MrpProduction(models.Model): + """ Manufacturing Orders """ + _inherit = 'mrp.production' + + @api.multi + def _indent_count(self): + for order in self: + indent_count = self.env['mrp.indent'].search([('origin', '=', order.id)]) + order.mrp_indent_order_count = len(indent_count) + + @api.multi + def mrp_indent_confirm(self): + for order in self: + indent_id = self.env['mrp.indent'].search([('origin', '=', order.id)]) + if indent_id: + for indent in indent_id: + if not indent.move_lines: + raise exceptions.Warning(_("Warning " + "You cannot confirm an indent %s which has no line." % indent.name)) + else: + indent.write({'state': 'waiting_approval'}) + self.indent_state = 'waiting_approval' + + @api.multi + def action_before_assign(self): + indent_count = self.env['mrp.indent'].search([('origin', '=', self.id)]) + if not indent_count: + self.indent_state = 'indent_created' + vals = { + 'origin': self.id, + 'required_date': self.date_planned_start, + 'item_for': 'mrp', + 'company_id': self.company_id.id, + } + indent_obj = self.env['mrp.indent'].create(vals) + for move in self.move_raw_ids: + move.write({'mrp_indent_id': indent_obj.id}) + else: + if self.indent_state == 'indent_created': + raise UserError(_("Indent already created, Please Check and Confirm your indent")) + else: + raise UserError(_("Indent already created, Please wait for the store team approval")) + + @api.multi + def action_cancel(self): + indent_ids = self.env['mrp.indent'].search([('origin', '=', self.id)]) + if indent_ids: + for indent in indent_ids: + indent.write({'state': 'cancel'}) + self.indent_state = 'cancel' + return super(MrpProduction, self).action_cancel() + + mrp_indent_order_count = fields.Integer(string='# of Indent Orders', compute='_indent_count') + indent_state = fields.Selection( + [('draft', 'Not indented'), + ('indent_created', 'Indent Created'), + ('waiting_approval', 'Waiting for Approval'), + ('done', 'Indent Approved'), + ('cancel', 'Indent Canceled'), + ('reject', 'Indent Rejected')], string='Indent Status', readonly=True, copy=False, default='draft') + + +class MrpIndent(models.Model): + _name = "mrp.indent" + + @api.multi + def action_assign(self): + for production in self: + move_to_assign = production.move_lines.filtered(lambda x: x.state in ('confirmed', 'waiting', 'assigned')) + move_to_assign.action_assign() + if self.origin.availability == 'assigned': + self.issued_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + self.state = 'done' + self.origin.write({'indent_state': 'done'}) + return True + + @api.model + def create(self, vals): + vals['name'] = self.env['ir.sequence'].next_by_code('mrp.indent') or '/' + return super(MrpIndent, self).create(vals) + + name = fields.Char(string='name', readonly=True, copy=False) + indent_date = fields.Datetime(string='Indent Date', required=True, default=fields.Datetime.now, readonly=True, + states={'draft': [('readonly', False)]}) + required_date = fields.Datetime(string='Required Date', required=True, readonly=True, default=fields.Datetime.now, + states={'draft': [('readonly', False)]}) + origin = fields.Many2one('mrp.production', string='Source Document', readonly=True, copy=False, states={'draft': [('readonly', False)]}) + issued_date = fields.Datetime(string='Approve Date', readonly=True) + issued_by = fields.Many2one('res.users', string='Issued by', readonly=True) + requirement = fields.Selection([('1', 'Ordinary'), ('2', 'Urgent')], 'Requirement', readonly=True, default='1', + states={'draft': [('readonly', False)]}) + item_for = fields.Selection([('mrp', 'Produce'), ('other', 'Other')], string='Order for', default='other', + readonly=True, states={'draft': [('readonly', False)]}) + move_lines = fields.One2many('stock.move', 'mrp_indent_id', string='Moves', copy=False, readonly=True) + product_lines = fields.One2many('mrp.indent.product.lines', 'indent_id', string='Product', copy=False) + description = fields.Text(string='Additional Information', readonly=True, + states={'draft': [('readonly', False)], 'waiting_approval': [('readonly', False)]}) + company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id, + readonly=True, states={'draft': [('readonly', False)]}) + + state = fields.Selection( + [('draft', 'Draft'), + ('waiting_approval', 'Waiting for Approval'), + ('inprogress', 'Ready to Transfer'), + ('move_created', 'Moves Created'), + ('done', 'Done'), + ('cancel', 'Cancel'), + ('reject', 'Rejected')], string='State', readonly=True, default='draft', track_visibility='onchange') + + @api.multi + def mrp_indent_confirm(self): + for indent in self: + if indent.item_for == 'mrp': + if not indent.move_lines: + raise exceptions.Warning(_("Warning " + "You cannot confirm an indent %s which has no line." % indent.name)) + else: + indent.write({'state': 'waiting_approval'}) + indent.origin.write({'indent_state': 'waiting_approval'}) + else: + if not indent.product_lines: + raise exceptions.Warning(_("Warning " + "You cannot confirm an indent %s which has " + "no product line." % indent.name)) + else: + indent.write({'state': 'waiting_approval'}) + + @api.one + def mrp_indent_inprogress(self): + todo = [] + for o in self: + if not any(line for line in o.product_lines): + raise exceptions.Warning(_('Error!'), + _('You cannot Approve a order without any order line.')) + + for line in o.product_lines: + if line: + todo.append(line.id) + + appr_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + self.env['mrp.indent.product.lines'].action_confirm(todo) + + for id in self.ids: + self.write({'state': 'inprogress', 'issued_date': appr_date}) + return True + + @api.one + def indent_reject(self): + if self.move_lines: + for line in self.move_lines: + if line.state == 'cancel': + pass + elif line.state == 'done': + pass + else: + line.action_cancel() + self.write({'state': 'reject'}) + if self.origin: + self.origin.action_cancel() + + @api.multi + def indent_transfer(self): + name = self.name + move_lines_obj = self.env['stock.move'] + if self.product_lines: + for line in self.product_lines: + if line.product_id.type != 'service': + if line.location_id: + if line.location_dest_id: + tot_qty = 0 + obj_quant = self.env['stock.quant'].search([('product_id', '=', line.product_id.id), + ('location_id', '=', line.location_id.id)]) + for obj in obj_quant: + tot_qty += obj.qty + move_line = {} + if line.product_id.type == 'consu': + move_line = { + 'product_id': line.product_id.id, + 'state': "draft", + 'product_uom_qty': line.product_uom_qty, + 'product_uom': line.product_id.uom_id.id, + 'name': line.product_id.name, + 'location_id': line.location_id.id, + 'location_dest_id': line.location_dest_id.id, + 'date': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + 'date_expected': self.required_date, + 'invoice_state': "none", + 'origin': name, + 'mrp_indent_id': self.id + } + move_lines_obj.create(move_line) + else: + move_line = {} + if tot_qty >= line.product_uom_qty: + move_line = { + 'product_id': line.product_id.id, + 'state': "draft", + 'product_uom_qty': line.product_uom_qty, + 'product_uom': line.product_id.uom_id.id, + 'name': line.product_id.name, + 'location_id': line.location_id.id, + 'location_dest_id': line.location_dest_id.id, + 'date': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + 'date_expected': self.required_date, + 'invoice_state': "none", + 'origin': name, + 'mrp_indent_id': self.id + } + move_lines_obj.create(move_line) + else: + if tot_qty: + raise exceptions.Warning((" No sufficient stock for product ' %s ' in '%s'. " + "Available quantity is %s %s.") % + (line.product_id.name, line.location_id.name, tot_qty, + line.product_uom.name)) + else: + raise exceptions.Warning( + (" No stock for product ' %s ' in '%s'." + " Please continue with another location ") % (line.product_id.name, + line.location_id.name)) + else: + raise exceptions.Warning((" Destination Location is not set properly for' %s '. " + "So Plese cancel this indent and create a new one please.") + % line.product_id.name) + else: + raise exceptions.Warning(("Source Location is not set properly for ' %s '. " + "Please go and set Source Location.") + % line.product_id.name) + else: + raise exceptions.Warning("This product is a service type product.") + else: + raise exceptions.Warning('You cannot Transfer a order without any product line.') + self.write({'state': 'move_created'}) + + @api.multi + def indent_transfer_move_confirm(self): + if self.move_lines: + for line in self.move_lines: + if line.state == 'cancel': + pass + elif line.state == 'done': + pass + else: + line.action_done() + else: + raise Warning(_('Error!'), + _('You cannot Confirm a order without any move lines.')) + self.write({'state': 'done'}) + + +class IndentProductLines(models.Model): + _name = 'mrp.indent.product.lines' + _description = 'Indent Product Lines' + + @api.one + def action_confirm(self, todo): + self.write({'state': 'inprogress'}) + return True + + indent_id = fields.Many2one('mrp.indent', string='Indent', required=True, ondelete='cascade') + name = fields.Text(string='Description', required=True, readonly=True, + states={'draft': [('readonly', False)], 'waiting_approval': [('readonly', False)]}) + product_id = fields.Many2one('product.product', string='Product', required=True, readonly=True, + states={'draft': [('readonly', False)], 'waiting_approval': [('readonly', False)]}) + original_product_id = fields.Many2one('product.product', string='Product to be Manufactured', readonly=True, + states={'draft': [('readonly', False)], 'waiting_approval': [('readonly', False)]}) + product_uom_qty = fields.Float(string='Quantity Required', digits_compute=dp.get_precision('Product UoS'), required=True, + readonly=True, states={'draft': [('readonly', False)], + 'waiting_approval': [('readonly', False)], + 'inprogress': [('readonly', False)]}) + product_uom = fields.Many2one('product.uom', string='Unit of Measure', required=True, readonly=True, + states={'draft': [('readonly', False)], 'waiting_approval': [('readonly', False)], + 'inprogress': [('readonly', False)]}) + location_id = fields.Many2one('stock.location', string='Source Location', readonly=True, + states={'inprogress': [('readonly', False)]}) + location_dest_id = fields.Many2one('stock.location', string='Destination Location', required=True, readonly=True, + states={'draft': [('readonly', False)], + 'waiting_approval': [('readonly', False)]}) + + delay = fields.Float(string='Lead Time') + purpose = fields.Text(string='Purpose') + state = fields.Selection( + [('draft', 'Draft'), + ('waiting_approval', 'Waiting for Approval'), + ('inprogress', 'Ready to Transfer'), + ('move_created', 'Moves Created'), + ('done', 'Done'), + ('cancel', 'Cancel'), + ('reject', 'Rejected')], string='State', default='draft', related='indent_id.state') + + sequence = fields.Integer('Sequence') + + def onchange_product_id(self, product_id=False, product_uom_qty=0.0, product_uom=False, name=''): + product_obj = self.env['product.product'] + value = {} + if not product_id: + return {'value': {'product_uom_qty': 1.0, 'product_uom': False, + 'name': '', 'specification': '', 'delay': 0.0}} + + product = product_obj.browse(product_id) + value['name'] = product.name_get()[0][1] + value['product_uom'] = product.uom_id.id + value['specification'] = product.name_get()[0][1] + + return {'value': value} + + +class StockMove(models.Model): + _inherit = 'stock.move' + + mrp_indent_id = fields.Many2one('mrp.indent', 'Indent') diff --git a/manufacturing_indent/security/ir.model.access.csv b/manufacturing_indent/security/ir.model.access.csv new file mode 100644 index 000000000..0761934ac --- /dev/null +++ b/manufacturing_indent/security/ir.model.access.csv @@ -0,0 +1,8 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_mrp_indent_store,manufacturing_indent.mrp.indent.stock,model_mrp_indent,stock.group_stock_user,1,1,1,1 +access_mrp_indent_line_store,manufacturing_indent.mrp.indent.product.lines.stock,model_mrp_indent_product_lines,stock.group_stock_user,1,1,1,1 + +access_mrp_indent_mrp,manufacturing_indent.mrp.indent.mrp,model_mrp_indent,mrp.group_mrp_user,1,1,1,1 +access_mrp_indent_line_mrp,manufacturing_indent.mrp.indent.product.lines.mrp,model_mrp_indent_product_lines,mrp.group_mrp_user,1,1,1,1 + +access_stock_scrap_mrp,manufacturing_indent.stock.scrap.mrp,stock.model_stock_scrap,mrp.group_mrp_user,1,1,1,1 \ No newline at end of file diff --git a/manufacturing_indent/static/description/Direct indent order.png b/manufacturing_indent/static/description/Direct indent order.png new file mode 100644 index 000000000..873615d1b Binary files /dev/null and b/manufacturing_indent/static/description/Direct indent order.png differ diff --git a/manufacturing_indent/static/description/Indent tree.png b/manufacturing_indent/static/description/Indent tree.png new file mode 100644 index 000000000..fc33b4318 Binary files /dev/null and b/manufacturing_indent/static/description/Indent tree.png differ diff --git a/manufacturing_indent/static/description/MRP indent.png b/manufacturing_indent/static/description/MRP indent.png new file mode 100644 index 000000000..df1862719 Binary files /dev/null and b/manufacturing_indent/static/description/MRP indent.png differ diff --git a/manufacturing_indent/static/description/banner.jpg b/manufacturing_indent/static/description/banner.jpg new file mode 100644 index 000000000..426719aaf Binary files /dev/null and b/manufacturing_indent/static/description/banner.jpg differ diff --git a/manufacturing_indent/static/description/cybro_logo.png b/manufacturing_indent/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/manufacturing_indent/static/description/cybro_logo.png differ diff --git a/manufacturing_indent/static/description/icon.png b/manufacturing_indent/static/description/icon.png new file mode 100644 index 000000000..319e4220d Binary files /dev/null and b/manufacturing_indent/static/description/icon.png differ diff --git a/manufacturing_indent/static/description/indent form view in store.png b/manufacturing_indent/static/description/indent form view in store.png new file mode 100644 index 000000000..21ecd7c2a Binary files /dev/null and b/manufacturing_indent/static/description/indent form view in store.png differ diff --git a/manufacturing_indent/static/description/indent order.png b/manufacturing_indent/static/description/indent order.png new file mode 100644 index 000000000..3f7032811 Binary files /dev/null and b/manufacturing_indent/static/description/indent order.png differ diff --git a/manufacturing_indent/static/description/index.html b/manufacturing_indent/static/description/index.html new file mode 100644 index 000000000..0b11f72de --- /dev/null +++ b/manufacturing_indent/static/description/index.html @@ -0,0 +1,129 @@ +
+
+

Indent Management - MRP

+

MRP indents created automatically from MRP orders to warehouse team

+

Author : Cybrosys Techno Solutions , www.cybrosys.com

+
+

Features:

+
    +
  •    MRP indents create automatically.
  • +
  •    Each MRP indent can approve by the warehouse manager.
  • +
  •    Raw materials available only after the approval of indent by warehouse manager.
  • +
  •    Goods required by Manufacturing Plants for internal purpose, can be made as an indent with a note.
  • +
+
+
+
+ +
+
+

MRP Indent to the Warehouse Team

+
+
+
+ +
+
+
+

+ The aim is to have a complete module to manage all MRP product indents. + When we create a MRP order, it automatically create an indent to the warehouse manager + to approve the raw materials. In addition if the Manufacturing team requires products for + internal use, an indent can be created to the warehouse team. +

+
+ +
+
+
+ +
+
+

Why need MRP indent..? How to create MRP indent?.

+
+
+
+ +
+
+
+

+ Usually MRP team does not require permission, but check the product’s availability in the stock. + This module helps to make order for the raw materials automatically. A smart button option is + include to check the indent status. +

+
+
+
+
+ +
+
+
+

Indent from MRP order

+
+ +
+

+

It automatically creates the MRP indents. Warehouse manager can approve the indent. + This indent is used to make order for the raw materials. Warehouse manager need to sanction it to + start the production process.

+

+
+
+

Direct creation of Indent

+
+ +
+

+

Manufacturing team may need some products for their internal purpose. They can create a new + indent and add the products in line and wait for the sanction from the warehouse team.

+

+
+
+
+ +
+
+

Indent from Manufacturing

+
+

+ Warehouse team have an extra menu for handling the indent. Warehouse team can select + the source location, and can move product to the destination mentioned in the indent. +

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

Need Any Help?

+ +
diff --git a/manufacturing_indent/views/manufacturing_indent_menu.xml b/manufacturing_indent/views/manufacturing_indent_menu.xml new file mode 100644 index 000000000..e3d56a212 --- /dev/null +++ b/manufacturing_indent/views/manufacturing_indent_menu.xml @@ -0,0 +1,165 @@ + + + + + + + mrp.indent.form + mrp.indent + +
+
+
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + + + + + +
+
+ +
+ + + + + + +
+
+ +
+
+ + + + mrp.indent.tree + mrp.indent + + + + + + + + + + + + + + Indents + mrp.indent + form + tree,form + [('state', 'in', ('draft','waiting_approval','inprogress','move_created','done','reject'))] + + + +

+ Click to create a new indent. +

+
+
+ + + +
+
\ No newline at end of file diff --git a/manufacturing_indent/views/mrp_indent_sequence.xml b/manufacturing_indent/views/mrp_indent_sequence.xml new file mode 100644 index 000000000..e674db583 --- /dev/null +++ b/manufacturing_indent/views/mrp_indent_sequence.xml @@ -0,0 +1,12 @@ + + + + + + Indent + + MRP_indent/%(year)s/ + mrp.indent + + + \ No newline at end of file diff --git a/manufacturing_indent/views/mrp_production_views.xml b/manufacturing_indent/views/mrp_production_views.xml new file mode 100644 index 000000000..7e61ab790 --- /dev/null +++ b/manufacturing_indent/views/mrp_production_views.xml @@ -0,0 +1,116 @@ + + + + + mrp.indent.form + mrp.indent + +
+
+
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + +
+
+
+
+
+ + + mrp.indent.tree + mrp.indent + + + + + + + + + + + + + Indent Orders + mrp.indent + form + tree,form + + [('origin', '=', active_id)] + + + + mrp.production.form + mrp.production + + + + + + + +
+
diff --git a/manufacturing_indent/views/stock_indent_menu.xml b/manufacturing_indent/views/stock_indent_menu.xml new file mode 100644 index 000000000..e738fe408 --- /dev/null +++ b/manufacturing_indent/views/stock_indent_menu.xml @@ -0,0 +1,149 @@ + + + + + + mrp.indent.form + mrp.indent + +
+
+
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + + + + + +
+
+ +
+ + + + + + +
+
+ +
+
+ + + + Indents + mrp.indent + form + tree,form + [('state', 'in', ('waiting_approval','inprogress','move_created','done','reject'))] + + + +

+ Click to create a new indent. +

+
+
+ + + + + + +
+
\ No newline at end of file diff --git a/pos_product_creation/README.rst b/pos_product_creation/README.rst new file mode 100644 index 000000000..468e6b5c4 --- /dev/null +++ b/pos_product_creation/README.rst @@ -0,0 +1,21 @@ +======================== +Pos Product Creation v10 +======================== + +This module adds product creation button an wizard in pos. + +Installation +============ + +Just select it from available modules to install it, there is no need to extra installations. + +Configuration +============= + +Nothing to configure. + +Credits +======= +Developer: Linto CT @ cybrosys, linto@cybrosys.in + + diff --git a/pos_product_creation/__init__.py b/pos_product_creation/__init__.py new file mode 100644 index 000000000..d1fb7a81f --- /dev/null +++ b/pos_product_creation/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: LINTO C T() +# 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/pos_product_creation/__manifest__.py b/pos_product_creation/__manifest__.py new file mode 100644 index 000000000..f63b09728 --- /dev/null +++ b/pos_product_creation/__manifest__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: LINTO C T() +# 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': 'Create Products From POS', + 'version': '10.0.1.0.0', + 'category': 'Point of Sale', + 'summary': 'Create Products From POS Interface', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'images': ['static/description/banner.jpg'], + 'website': 'https://www.cybrosys.com', + 'depends': ['point_of_sale'], + 'data': [ + 'views/pos_template.xml', + ], + 'qweb': ['static/src/xml/pos.xml'], + 'installable': True, + 'auto_install': False, +} diff --git a/pos_product_creation/models/__init__.py b/pos_product_creation/models/__init__.py new file mode 100644 index 000000000..d1ea13fe7 --- /dev/null +++ b/pos_product_creation/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: LINTO C T() +# 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 product_pos diff --git a/pos_product_creation/models/product_pos.py b/pos_product_creation/models/product_pos.py new file mode 100644 index 000000000..da840a6f2 --- /dev/null +++ b/pos_product_creation/models/product_pos.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: LINTO C T() +# 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 odoo import models + + +class ProductFromPos(models.Model): + _inherit = 'product.product' + + def create_product_pos(self, vals): + type = None + if vals.get('type') == 'Stockable': + type = 'product' + elif vals.get('type') == 'Consumable': + type = 'consu' + elif vals.get('type') == 'Service': + type = 'service' + category = self.env['product.category'].search([('name', '=', vals.get('category'))], limit=1) + uom_id = self.env['product.uom'].search([('name', '=', vals.get('unit'))], limit=1) + new_vals = { + 'name': vals.get('name'), + 'display_name': vals.get('name'), + 'type': type, + 'categ_id': category.id if category else None, + 'list_price': vals.get('price') if vals.get('price') else 1, + 'available_in_pos': True, + 'sale_ok': True, + 'uom_id': uom_id.id, + 'uom_po_id': uom_id.id + } + rec = self.env['product.product'].create(new_vals) + new_vals['id'] = rec.id + new_vals['price'] = vals.get('price') if vals.get('price') else 1 + new_vals['pos_categ_id'] = [rec.pos_categ_id.id] if rec.pos_categ_id else None + new_vals['taxes_id'] = [rec.taxes_id.id] if rec.taxes_id else [] + new_vals['barcode'] = rec.barcode + new_vals['default_code'] = rec.default_code + new_vals['to_weight'] = rec.to_weight + new_vals['uom_id'] = [rec.uom_id.id, rec.uom_id.name] + new_vals['description_sale'] = rec.description_sale + new_vals['description'] = rec.description + new_vals['product_tmpl_id'] = [rec.product_tmpl_id.id] + new_vals['tracking'] = rec.tracking + + return new_vals \ No newline at end of file diff --git a/pos_product_creation/static/description/banner.jpg b/pos_product_creation/static/description/banner.jpg new file mode 100644 index 000000000..7f0b2296a Binary files /dev/null and b/pos_product_creation/static/description/banner.jpg differ diff --git a/pos_product_creation/static/description/cybro_logo.png b/pos_product_creation/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/pos_product_creation/static/description/cybro_logo.png differ diff --git a/pos_product_creation/static/description/icon.png b/pos_product_creation/static/description/icon.png new file mode 100644 index 000000000..bca05e06d Binary files /dev/null and b/pos_product_creation/static/description/icon.png differ diff --git a/pos_product_creation/static/description/index.html b/pos_product_creation/static/description/index.html new file mode 100644 index 000000000..0ef831fd2 --- /dev/null +++ b/pos_product_creation/static/description/index.html @@ -0,0 +1,93 @@ +
+
+

POS Product Creation

+

Create Products From POS

+

Cybrosys Technologies , www.cybrosys.com

+
+
+ +
+
+
+
+

+ This module allows us to create products from point of sale. A new button is added for this purpose. + When we click on the 'Add Product' button, a new wizard will be appeared in which we can enter the + details of the product such as name, type, category price etc. When we click the confirm button, + a new product will be created with the provided details. +

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

+ The products list will be updated real time. It is not needed to reload the page to + show the newly created product in the point of sale products list. +

+
+ +
+
+
+ +
+

Need Any Help?

+ +
diff --git a/pos_product_creation/static/description/product.png b/pos_product_creation/static/description/product.png new file mode 100644 index 000000000..065db29fc Binary files /dev/null and b/pos_product_creation/static/description/product.png differ diff --git a/pos_product_creation/static/description/wizard.png b/pos_product_creation/static/description/wizard.png new file mode 100644 index 000000000..108e39604 Binary files /dev/null and b/pos_product_creation/static/description/wizard.png differ diff --git a/pos_product_creation/static/src/js/create_product.js b/pos_product_creation/static/src/js/create_product.js new file mode 100644 index 000000000..f69445558 --- /dev/null +++ b/pos_product_creation/static/src/js/create_product.js @@ -0,0 +1,105 @@ +odoo.define('pos_product_creation',function(require) { + +var gui = require('point_of_sale.gui'); +var chrome = require('point_of_sale.chrome'); +var PosBaseWidget = require('point_of_sale.BaseWidget'); +var popups = require('point_of_sale.popups'); +var core = require('web.core'); +var models = require('point_of_sale.models'); +var Model = require('web.DataModel'); +var QWeb = core.qweb; +var _t = core._t; +models.load_models({ + model: 'product.category', + fields: ['name'], + loaded: function(self,categories){ + self.categories = categories; + }, + }); + +chrome.OrderSelectorWidget.include({ + renderElement: function(){ + var self = this; + this._super(); + var categ = []; + var unit = []; + for (var i in self.pos.categories){ + categ.push(self.pos.categories[i].name); + } + for (var i in self.pos.units){ + unit.push(self.pos.units[i].name); + } + this.$('.add-product').click(function(event){ + self.gui.show_popup('product_create',{ + 'category': categ, + 'units':unit, + 'confirm': function(value) { + }, + }); + }); + }, +}); +var ProductCreationWidget = PosBaseWidget.extend({ + template: 'ProductCreationWidget', + init: function(parent, args) { + this._super(parent, args); + this.options = {}; + this.category = []; + this.units = []; + }, + events: { + 'click .button.cancel': 'click_cancel', + 'click .button.confirm': 'click_confirm', + }, + show: function(options){ + options = options || {}; + this._super(options); + this.category = options.category; + this.units = options.units; + this.renderElement(); + this.$('.name').focus(); + }, + close: function(){ + if (this.pos.barcode_reader) { + this.pos.barcode_reader.restore_callbacks(); + } + }, + click_confirm: function(){ + var self = this; + var name = this.$('.name').val(); + var type = this.$('.type').val(); + var category = this.$('.category').val(); + var unit = this.$('.uom').val(); + var price = this.$('.price').val(); + if(isNaN(price) || !price) { + alert("Please check the price !") + } + else { + var product_vals = { + 'name': name, + 'type': type, + 'category': category, + 'price': price, + 'unit': unit + }; + new Model('product.product').call('create_product_pos',[1, product_vals]).then(function(product){ + self.pos.db.add_products([product]); + console.log(self) + }); + console.log(product_vals) + this.gui.close_popup(); + if( this.options.confirm ){ + this.options.confirm.call(this,name); + } + } + }, + click_cancel: function(){ + this.gui.close_popup(); + if (this.options.cancel) { + this.options.cancel.call(this); + } + }, +}); +gui.define_popup({name:'product_create', widget: ProductCreationWidget}); + +}); \ No newline at end of file diff --git a/pos_product_creation/static/src/xml/pos.xml b/pos_product_creation/static/src/xml/pos.xml new file mode 100644 index 000000000..cb482ad49 --- /dev/null +++ b/pos_product_creation/static/src/xml/pos.xml @@ -0,0 +1,54 @@ + + + + +
+ + Add Product + +
+
+
+ + + + +
\ No newline at end of file diff --git a/pos_product_creation/views/pos_template.xml b/pos_product_creation/views/pos_template.xml new file mode 100644 index 000000000..9932b9edf --- /dev/null +++ b/pos_product_creation/views/pos_template.xml @@ -0,0 +1,11 @@ + + + + + + +