diff --git a/product_combo_pack/README.rst b/product_combo_pack/README.rst index ed831385e..23cbb8f9f 100644 --- a/product_combo_pack/README.rst +++ b/product_combo_pack/README.rst @@ -1,29 +1,34 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + Product Pack ============ * Create product pack which is a great way to raise average sales price per product, to serve customers with products that make their lives easier, and to leverage current products into new and different ones. Installation ============ - - www.odoo.com/documentation/16.0/setup/install.html + - www.odoo.com/documentation/13.0/setup/install.html - Install our custom addon License ======= GNU AFFERO GENERAL PUBLIC LICENSE, Version 3 (AGPLv3) -(http://www.gnu.org/licenses/agpl.html) +(https://www.gnu.org/licenses/agpl-3.0-standalone.html) Company ------- -* 'Cybrosys Techno Solutions `__ +* `Cybrosys Techno Solutions `__ Credits ------- -* Developer: -Afras @ Cybrosys, Contact: afras@cybrosys.in +* Developer: Jumana jabin MP @ Cybrosys, +* Contact: odoo@cybrosys.com Contacts -------- * Mail Contact : odoo@cybrosys.com +* Website : https://cybrosys.com Bug Tracker ----------- @@ -31,11 +36,12 @@ Bugs are tracked on GitHub Issues. In case of trouble, please check there if you Maintainer ========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com This module is maintained by Cybrosys Technologies. For support and more information, please visit https://www.cybrosys.com Further information =================== -HTML Description: ``__ - +HTML Description: ``__ \ No newline at end of file diff --git a/product_combo_pack/__init__.py b/product_combo_pack/__init__.py index ef00b0bee..c13aaf71a 100644 --- a/product_combo_pack/__init__.py +++ b/product_combo_pack/__init__.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -################################################################################### +################################################################################ # # Cybrosys Technologies Pvt. Ltd. # -# Copyright (C) 2022-TODAY Cybrosys Technologies (). -# Author: Afras Habis (odoo@cybrosys.com) +# Copyright (C) 2023-TODAY Cybrosys Technologies () +# Author: Jumana Jabin MP (odoo@cybrosys.com) # # This program is free software: you can modify # it under the terms of the GNU Affero General Public License (AGPL) as @@ -19,7 +19,5 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # -################################################################################### - +################################################################################ from . import models -from . import wizard diff --git a/product_combo_pack/__manifest__.py b/product_combo_pack/__manifest__.py index a0ed41fb2..e5ab53311 100644 --- a/product_combo_pack/__manifest__.py +++ b/product_combo_pack/__manifest__.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -################################################################################### +################################################################################ # # Cybrosys Technologies Pvt. Ltd. # -# Copyright (C) 2022-TODAY Cybrosys Technologies (). -# Author: Afras Habis (odoo@cybrosys.com) +# Copyright (C) 2023-TODAY Cybrosys Technologies () +# Author: Jumana jabin MP (odoo@cybrosys.com) # # This program is free software: you can modify # it under the terms of the GNU Affero General Public License (AGPL) as @@ -19,11 +19,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # -################################################################################### - +################################################################################ { 'name': 'Product Pack', - 'version': '16.0.1.0.2', + 'version': '16.0.1.0.3', 'summary': 'Manage Products as Pack', 'description': 'Manage Products as Pack', 'category': 'Sales', @@ -34,12 +33,12 @@ 'depends': ['base', 'sale_management', 'stock'], 'data': [ 'security/ir.model.access.csv', - 'views/product_form_view.xml', - 'wizard/select_product_pack_view.xml', - 'views/sale_order_view.xml', + 'views/product_form_views.xml', + 'views/sale_order_views.xml', ], 'images': ['static/description/banner.png'], - 'installable': True, 'license': 'AGPL-3', + 'installable': True, 'auto_install': False, + 'application': True, } diff --git a/product_combo_pack/doc/RELEASE_NOTES.md b/product_combo_pack/doc/RELEASE_NOTES.md index 416cd449c..9d915408d 100644 --- a/product_combo_pack/doc/RELEASE_NOTES.md +++ b/product_combo_pack/doc/RELEASE_NOTES.md @@ -1,10 +1,5 @@ ## Module -#### 23.08.2022 +#### 14.07.2023 #### Version 16.0.1.0.0 -Initial Commit for product_combo_pack - -#### 01.12.2022 -#### Version 16.0.1.0.1 -#### UPDT -- Product pack duplication issue \ No newline at end of file + - Initial Commit for Product Pack \ No newline at end of file diff --git a/product_combo_pack/models/__init__.py b/product_combo_pack/models/__init__.py index 4aaad3f5e..88adcea91 100644 --- a/product_combo_pack/models/__init__.py +++ b/product_combo_pack/models/__init__.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -################################################################################### +################################################################################ # # Cybrosys Technologies Pvt. Ltd. # -# Copyright (C) 2022-TODAY Cybrosys Technologies (). -# Author: Afras Habis (odoo@cybrosys.com) +# Copyright (C) 2023-TODAY Cybrosys Technologies () +# Author: Jumana Jabin MP (odoo@cybrosys.com) # # This program is free software: you can modify # it under the terms of the GNU Affero General Public License (AGPL) as @@ -19,8 +19,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # -################################################################################### - -from . import product_form +################################################################################ from . import pack_products +from . import product_template from . import sale_order diff --git a/product_combo_pack/models/pack_products.py b/product_combo_pack/models/pack_products.py index efeac0310..33b28cdd5 100644 --- a/product_combo_pack/models/pack_products.py +++ b/product_combo_pack/models/pack_products.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -################################################################################### +################################################################################ # # Cybrosys Technologies Pvt. Ltd. # -# Copyright (C) 2022-TODAY Cybrosys Technologies (). -# Author: Afras Habis (odoo@cybrosys.com) +# Copyright (C) 2023-TODAY Cybrosys Technologies () +# Author: Jumana Jabin MP (odoo@cybrosys.com) # # This program is free software: you can modify # it under the terms of the GNU Affero General Public License (AGPL) as @@ -19,33 +19,46 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # -################################################################################### - +################################################################################ from odoo import api, fields, models, _ -from odoo.exceptions import UserError, ValidationError +from odoo.exceptions import ValidationError class PackProducts(models.Model): + """Model for selecting pack products.This model allows users to select + and manage pack products. """ _name = 'pack.products' _rec_name = 'product_tmpl_id' _description = 'Select Pack Products' - product_id = fields.Many2one('product.product', string='Product', required=True, - domain=[('is_pack', '=', False)]) - product_tmpl_id = fields.Many2one('product.template', string='Product') - price = fields.Float('Price', compute='compute_price', store=True) - quantity = fields.Integer('Quantity', default=1) - qty_available = fields.Float('Quantity Available', compute='compute_quantity_of_product', store=True, - readonly=False) - total_available_quantity = fields.Float('Total Quantity') + product_id = fields.Many2one('product.product', string='Product', + required=True, + domain=[('is_pack', '=', False)], + help='The specific product being referenced.') + product_tmpl_id = fields.Many2one('product.template', string='Product', + help='The template of the product.') + price = fields.Float('Price', compute='compute_price', store=True, + help='The calculated price of the product.') + quantity = fields.Integer('Quantity', default=1, + help='The quantity of the product.') + qty_available = fields.Float('Quantity Available', + compute='compute_quantity_of_product', + store=True, readonly=False, + help='The available quantity of the product.') + total_available_quantity = fields.Float('Total Quantity', + help='The total available quantity.') - @api.depends('product_id', 'total_available_quantity', 'product_id.qty_available') + @api.depends('product_id', 'total_available_quantity', + 'product_id.qty_available') def compute_quantity_of_product(self): + """Compute the available quantity for each record based on the + product and location. """ for record in self: location_id = record.product_tmpl_id.pack_location_id if location_id: stock_quant = self.env['stock.quant'].search( - [('product_id', '=', record.product_id.id), ('location_id', '=', location_id.id)]) + [('product_id', '=', record.product_id.id), + ('location_id', '=', location_id.id)]) if stock_quant: record.qty_available = stock_quant.quantity else: @@ -55,14 +68,19 @@ class PackProducts(models.Model): @api.depends('product_id', 'quantity') def compute_price(self): + """ Compute the price for each record based on the product and quantity. + """ for record in self: record.price = record.product_id.lst_price * record.quantity @api.onchange('quantity') def set_price(self): + """ Update the price field when the quantity changes.""" self.price = self.product_id.lst_price * self.quantity @api.constrains('quantity') def _check_positive_qty(self): + """Ensure that the quantity is always positive.Raises a validation + error if any of the records have a negative quantity.""" if any([ml.quantity < 0 for ml in self]): raise ValidationError(_('You can not enter negative quantities.')) diff --git a/product_combo_pack/models/product_form.py b/product_combo_pack/models/product_template.py similarity index 52% rename from product_combo_pack/models/product_form.py rename to product_combo_pack/models/product_template.py index b5beaa508..4d70a52e7 100644 --- a/product_combo_pack/models/product_form.py +++ b/product_combo_pack/models/product_template.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -################################################################################### +################################################################################ # # Cybrosys Technologies Pvt. Ltd. # -# Copyright (C) 2022-TODAY Cybrosys Technologies (). -# Author: Afras Habis (odoo@cybrosys.com) +# Copyright (C) 2023-TODAY Cybrosys Technologies () +# Author: Jumana jabin MP (odoo@cybrosys.com) # # This program is free software: you can modify # it under the terms of the GNU Affero General Public License (AGPL) as @@ -19,31 +19,46 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # -################################################################################### - +################################################################################ from odoo import api, fields, models, _ from odoo.exceptions import UserError class ProductPack(models.Model): + """Model for extending the product template to include + pack-related fields.""" _inherit = 'product.template' def default_pack_location(self): + """ Get the default pack location for the current company.""" company_user = self.env.company - warehouse = self.env['stock.warehouse'].search([('company_id', '=', company_user.id)], limit=1) + warehouse = self.env['stock.warehouse'].search([( + 'company_id', '=', company_user.id)], limit=1) if warehouse: return warehouse.lot_stock_id.id - is_pack = fields.Boolean('Is a Pack') - pack_price = fields.Integer(string="Pack Price", compute='set_pack_price', store=True) - pack_products_ids = fields.One2many('pack.products', 'product_tmpl_id', string='Pack Products', copy=True) - pack_quantity = fields.Integer('Pack Quantity') + is_pack = fields.Boolean('Is a Pack', help='Indicates whether the' + ' product is a pack or not.') + pack_price = fields.Integer(string="Pack Price", compute='set_pack_price', + store=True, + help='The calculated price of the pack.') + pack_products_ids = fields.One2many('pack.products', 'product_tmpl_id', + string='Pack Products', copy=True, + help='The list of products included ' + 'in the pack.') + pack_quantity = fields.Integer('Pack Quantity', + help='The quantity of the product' + ' in the pack.') pack_location_id = fields.Many2one('stock.location', - domain=[('usage', 'in', ['internal', 'transit'])], - default=default_pack_location) + domain=[('usage', 'in', + ['internal', 'transit'])], + default=default_pack_location, + string='Pack Location', + help='The default location for the pack.') @api.depends('pack_products_ids', 'pack_products_ids.price') def set_pack_price(self): + """Compute the pack price based on the prices of the pack products.""" price = 0 for record in self: for line in record.pack_products_ids: @@ -52,30 +67,39 @@ class ProductPack(models.Model): @api.model def create(self, values): + """Override the create method to add validation for pack products.""" if values.get('is_pack', False): if not values.get('pack_products_ids', []): raise UserError(_( 'You need to add atleast one product in the Pack...!')) if values.get('type', False) == 'service': - raise UserError(_('You cannot define a pack product as a service..!')) + raise UserError( + _('You cannot define a pack product as a service..!')) return super(ProductPack, self).create(values) def write(self, values): + """Override the write method to add validation for pack products.""" super(ProductPack, self).write(values) - if self.is_pack: - if not self.pack_products_ids: - raise UserError(_( - 'You need to add atleast one product in the Pack...!')) - if self.type == 'service': - raise UserError(_('You cannot define a pack product as a service..!')) + for rec in self: + if rec.is_pack: + if not rec.pack_products_ids: + raise UserError(_( + 'You need to add at least one product in the Pack...!')) + if rec.type == 'service': + raise UserError( + _('You cannot define a pack product as a service..!')) def update_price_product(self): + """Update the list price of the product with the pack price.""" self.list_price = self.pack_price def get_quantity(self): + """Calculate the pack quantity based on the availability of + pack products.""" total_quantity = 1 flag = 1 - while flag: + max_iterations = 1000 + while flag and total_quantity < max_iterations: for line in self.pack_products_ids: if line.qty_available >= line.quantity * total_quantity: continue @@ -85,30 +109,37 @@ class ProductPack(models.Model): flag = 0 break if flag: - total_quantity = total_quantity + 1 + total_quantity += 1 self.pack_quantity = total_quantity - 1 def update_quantity(self): + """Update the pack quantity in the specified pack location.""" company_user = self.env.company - product_id = len(self.product_variant_ids) == 1 and self.product_variant_id.id + product_id = len( + self.product_variant_ids) == 1 and self.product_variant_id.id location_id = self.pack_location_id.id if not location_id: - warehouse = self.env['stock.warehouse'].search([('company_id', '=', company_user.id)], limit=1) + warehouse = self.env['stock.warehouse'].search([( + 'company_id', '=', company_user.id)], limit=1) location_id = warehouse.lot_stock_id.id if not location_id: raise UserError(_( 'You need to select the location to update the pack quantity...!')) - self.env['stock.quant'].with_context(inventory_mode=True).sudo().create({ - 'product_id': product_id, - 'location_id': location_id, - 'inventory_quantity': self.pack_quantity, - }) + self.env['stock.quant'].with_context(inventory_mode=True).sudo().create( + { + 'product_id': product_id, + 'location_id': location_id, + 'inventory_quantity': self.pack_quantity, + }) @api.onchange('pack_location_id') def change_quantity_based_on_location(self): + """Update the total available quantity of pack products based + on the selected pack location.""" for line in self.pack_products_ids: stock_quant = self.env['stock.quant'].search( - [('product_id', '=', line.product_id.id), ('location_id', '=', self.pack_location_id.id)]) + [('product_id', '=', line.product_id.id), ( + 'location_id', '=', self.pack_location_id.id)]) if stock_quant: line.total_available_quantity = stock_quant.quantity else: diff --git a/product_combo_pack/models/sale_order.py b/product_combo_pack/models/sale_order.py index accae1043..bd0102ae1 100644 --- a/product_combo_pack/models/sale_order.py +++ b/product_combo_pack/models/sale_order.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -################################################################################### +################################################################################ # # Cybrosys Technologies Pvt. Ltd. # -# Copyright (C) 2022-TODAY Cybrosys Technologies (). -# Author: Afras Habis (odoo@cybrosys.com) +# Copyright (C) 2023-TODAY Cybrosys Technologies () +# Author: Jumana Jabin MP (odoo@cybrosys.com) # # This program is free software: you can modify # it under the terms of the GNU Affero General Public License (AGPL) as @@ -19,15 +19,36 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # -################################################################################### - +################################################################################ from odoo import api, fields, models class SalePack(models.Model): + """Model for extending the sale order to include a selection of packs.""" _inherit = 'sale.order' + product_pack_id = fields.Many2one('product.product', string='Select Pack', + domain=[('is_pack', '=', True)], + required=True, + help='The selected pack product for' + ' the sale order.') + + @api.onchange('product_pack_id') + def onchange_product_pack_id(self): + """Perform actions when the selected pack product changes.""" + if self.product_pack_id: + self.order_line = [(0, 0, { + 'product_id': self.product_pack_id.id, + 'name': self.product_pack_id.name, + 'product_uom_qty': 1, + 'price_unit': self.product_pack_id.list_price, + })] + elif not self.product_pack_id: + self.order_line = [(5, 0, 0)] + def action_confirm(self): + """Override the action_confirm method to create stock moves + for pack products.""" super(SalePack, self).action_confirm() for line in self.order_line: if line.product_id.is_pack: diff --git a/product_combo_pack/security/ir.model.access.csv b/product_combo_pack/security/ir.model.access.csv index 9748d6a5f..b737db5c9 100644 --- a/product_combo_pack/security/ir.model.access.csv +++ b/product_combo_pack/security/ir.model.access.csv @@ -1,3 +1,2 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_pack_products,access.pack.products,model_pack_products,base.group_user,1,1,1,1 -access_select_product_pack,access.select.product.pack,model_select_product_pack,base.group_user,1,1,1,1 \ No newline at end of file +access_pack_products,access.pack.products,model_pack_products,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/product_combo_pack/static/description/assets/screenshots/1.png b/product_combo_pack/static/description/assets/screenshots/1.png new file mode 100644 index 000000000..4dcf4607b Binary files /dev/null and b/product_combo_pack/static/description/assets/screenshots/1.png differ diff --git a/product_combo_pack/static/description/assets/screenshots/2.png b/product_combo_pack/static/description/assets/screenshots/2.png new file mode 100644 index 000000000..125fe52dd Binary files /dev/null and b/product_combo_pack/static/description/assets/screenshots/2.png differ diff --git a/product_combo_pack/static/description/assets/screenshots/3.png b/product_combo_pack/static/description/assets/screenshots/3.png new file mode 100644 index 000000000..0b2f41049 Binary files /dev/null and b/product_combo_pack/static/description/assets/screenshots/3.png differ diff --git a/product_combo_pack/static/description/assets/screenshots/4.png b/product_combo_pack/static/description/assets/screenshots/4.png new file mode 100644 index 000000000..f21da6be1 Binary files /dev/null and b/product_combo_pack/static/description/assets/screenshots/4.png differ diff --git a/product_combo_pack/static/description/assets/screenshots/5.png b/product_combo_pack/static/description/assets/screenshots/5.png new file mode 100644 index 000000000..06b5e860a Binary files /dev/null and b/product_combo_pack/static/description/assets/screenshots/5.png differ diff --git a/product_combo_pack/static/description/assets/screenshots/6.png b/product_combo_pack/static/description/assets/screenshots/6.png new file mode 100644 index 000000000..aba65ffb8 Binary files /dev/null and b/product_combo_pack/static/description/assets/screenshots/6.png differ diff --git a/product_combo_pack/static/description/assets/screenshots/7.png b/product_combo_pack/static/description/assets/screenshots/7.png new file mode 100644 index 000000000..7c7a87143 Binary files /dev/null and b/product_combo_pack/static/description/assets/screenshots/7.png differ diff --git a/product_combo_pack/static/description/assets/screenshots/hero.gif b/product_combo_pack/static/description/assets/screenshots/hero.gif index c7fd9fd64..e857debce 100644 Binary files a/product_combo_pack/static/description/assets/screenshots/hero.gif and b/product_combo_pack/static/description/assets/screenshots/hero.gif differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-1.png b/product_combo_pack/static/description/assets/screenshots/screenshot-1.png deleted file mode 100644 index 2b353cf7c..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-1.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-10.png b/product_combo_pack/static/description/assets/screenshots/screenshot-10.png deleted file mode 100644 index 3af1c8494..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-10.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-11.png b/product_combo_pack/static/description/assets/screenshots/screenshot-11.png deleted file mode 100644 index eef2bb4d4..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-11.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-12.png b/product_combo_pack/static/description/assets/screenshots/screenshot-12.png deleted file mode 100644 index 93530f56f..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-12.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-13.png b/product_combo_pack/static/description/assets/screenshots/screenshot-13.png deleted file mode 100644 index c0a6a4ae9..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-13.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-14.png b/product_combo_pack/static/description/assets/screenshots/screenshot-14.png deleted file mode 100644 index b60787bb6..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-14.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-2.png b/product_combo_pack/static/description/assets/screenshots/screenshot-2.png deleted file mode 100644 index 84481fe33..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-2.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-3.png b/product_combo_pack/static/description/assets/screenshots/screenshot-3.png deleted file mode 100644 index b335c2962..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-3.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-4.png b/product_combo_pack/static/description/assets/screenshots/screenshot-4.png deleted file mode 100644 index efbc55ce4..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-4.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-5.png b/product_combo_pack/static/description/assets/screenshots/screenshot-5.png deleted file mode 100644 index 6a27ee134..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-5.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-6.png b/product_combo_pack/static/description/assets/screenshots/screenshot-6.png deleted file mode 100644 index 93514e309..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-6.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-7.png b/product_combo_pack/static/description/assets/screenshots/screenshot-7.png deleted file mode 100644 index 6d3a0c36e..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-7.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-8.png b/product_combo_pack/static/description/assets/screenshots/screenshot-8.png deleted file mode 100644 index 304708ed0..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-8.png and /dev/null differ diff --git a/product_combo_pack/static/description/assets/screenshots/screenshot-9.png b/product_combo_pack/static/description/assets/screenshots/screenshot-9.png deleted file mode 100644 index 9cdd9637e..000000000 Binary files a/product_combo_pack/static/description/assets/screenshots/screenshot-9.png and /dev/null differ diff --git a/product_combo_pack/static/description/index.html b/product_combo_pack/static/description/index.html index 1c5f50426..612fb8fde 100644 --- a/product_combo_pack/static/description/index.html +++ b/product_combo_pack/static/description/index.html @@ -1,86 +1,91 @@
- + style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;"> +
+ class="mr-2"> Community
+ class="mr-2"> Enterprise
+ class="mr-2"> Odoo.sh
- -

Product Pack

-

Manage Products as Pack

+

+ Product Pack

+

+ Manage Products as Pack

+ style="width: 75%; height: auto; position: absolute; margin-left: auto; margin-right: auto; top: 45%; left: 12%; right: auto;"/>
-
+
- + style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> +
-

Explore This +

+ Explore This Module

@@ -88,67 +93,85 @@ -
+
- + style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> +
-

Overview +

+ Overview

-
+
- Selling products in a pack is a great way to raise average sales price per product, to serve customers with products that make their lives easier, and to leverage current products into new and different ones. They are profitable for smaller businesses as well as large ones. + Selling products in a pack is a great way to raise average sales price + per product, to serve customers with products that make their lives + easier, and to leverage current products into new and different ones. + They are profitable for smaller businesses as well as large ones.
-
+
- + style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> +
-

Features +

+ Features

-
+
- -
- + +
+ Create a Product Pack Easily.
-
- +
+ Manage the stock of the Product.
-
- +
+ Compute the Price of the Pack.
-
- +
+ Compute the Quantity of the Pack with respect to the quantity of Pack items.
-
- +
+ Update the quantity of pack easily.
-
- +
+ Adding Pack into Sale order Easily.
-
- +
+ Filter Pack from Products.
@@ -157,122 +180,97 @@ -
+
- + style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> +
-

Screenshots +

+ Screenshots

-

Product Pack Menu. -

- - +

+ Product Pack Menu. +

+ +
-

Check if the product is a pack. -

- - +

+ Check if the product is a pack. +

+ +
-

Product Pack Page for Consumable(if not managing the stock of pack)

- - -
- -
-

Product Pack Page for Storable. -

- - -
- -
-

Adding products into the pack. -

- - -
- -
-

Computing the price with respect to - the product in the pack.

- - -
- -
-

Update the price of the pack. -

- - -
- -
-

Get the quantity of pack with repect to the quantity of pack products.

- - -
-
-

Update the quantity of pack directly with the computed quantity to the selected location.

- - -
-
-

Adding Pack to sale order. -

- - -
-
-

Select the Pack and Quantity and click on 'ADD' to add the pack into sale order.

- +

+ Product Pack Page for Consumable(if not managing the stock of + pack)

- -
-
-

Pack added to the sale order. -

- - +
-
-

Delivery of pack. -

- - -
-
-

Stock reduced for both pack and pack products.

- - + +
+

+ Product Pack Page for Storable. +

+ +
- +
+

+ Adding products into the pack. +

+ +
+
+

+ Adding Pack to sale order. +

+ +
+
+

+ Delivery of pack. +

+ +
-
+
- + style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> +
-

Related +

+ Related Products

@@ -282,52 +280,71 @@