| @ -1,10 +1,5 @@ | |||
| ## Module <product_combo_pack> | |||
| 
 | |||
| #### 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 | |||
|  - Initial Commit for Product Pack | |||
| 
 | 
| After Width: | Height: | Size: 438 KiB | 
| After Width: | Height: | Size: 105 KiB | 
| After Width: | Height: | Size: 70 KiB | 
| After Width: | Height: | Size: 83 KiB | 
| After Width: | Height: | Size: 91 KiB | 
| After Width: | Height: | Size: 109 KiB | 
| After Width: | Height: | Size: 94 KiB | 
| Before Width: | Height: | Size: 229 KiB After Width: | Height: | Size: 233 KiB | 
| Before Width: | Height: | Size: 138 KiB | 
| Before Width: | Height: | Size: 53 KiB | 
| Before Width: | Height: | Size: 40 KiB | 
| Before Width: | Height: | Size: 59 KiB | 
| Before Width: | Height: | Size: 41 KiB | 
| Before Width: | Height: | Size: 60 KiB | 
| Before Width: | Height: | Size: 50 KiB | 
| Before Width: | Height: | Size: 16 KiB | 
| Before Width: | Height: | Size: 24 KiB | 
| Before Width: | Height: | Size: 35 KiB | 
| Before Width: | Height: | Size: 35 KiB | 
| Before Width: | Height: | Size: 34 KiB | 
| Before Width: | Height: | Size: 9.5 KiB | 
| Before Width: | Height: | Size: 34 KiB | 
| @ -1,103 +0,0 @@ | |||
| <odoo> | |||
|     <data> | |||
|         <!-- Inherit Form View to Modify it --> | |||
|         <record id="product_product_inherit_pack" model="ir.ui.view"> | |||
|             <field name="name">product.product.inherit.pack</field> | |||
|             <field name="model">product.product</field> | |||
|             <field name="inherit_id" ref="product.product_normal_form_view"/> | |||
|             <field name="arch" type="xml"> | |||
|                 <xpath expr="//div[@name='options']" position="inside"> | |||
|                     <div modifiers="{}"> | |||
|                         <field name="is_pack" modifiers="{}"/> | |||
|                         <label for="is_pack" modifiers="{}"/> | |||
|                     </div> | |||
|                 </xpath> | |||
|             </field> | |||
|         </record> | |||
| 
 | |||
|         <record id="product_template_inherit_pack" model="ir.ui.view"> | |||
|             <field name="name">product.template.inherit.pack</field> | |||
|             <field name="model">product.template</field> | |||
|             <field name="inherit_id" ref="product.product_template_only_form_view"/> | |||
|             <field name="arch" type="xml"> | |||
|                 <xpath expr="//div[@name='options']" position="inside"> | |||
|                     <div modifiers="{}"> | |||
|                         <field name="is_pack" modifiers="{}"/> | |||
|                         <label for="is_pack" modifiers="{}"/> | |||
|                     </div> | |||
|                 </xpath> | |||
|                 <xpath expr="//page[@name='variants']" position="attributes"> | |||
|                     <attribute name="attrs">{'invisible': [('is_pack','=',True)]}</attribute> | |||
|                 </xpath> | |||
|                 <xpath expr="//page[@name='invoicing']" position="after"> | |||
|                     <page string="Product Pack" name="product_pack" attrs="{'invisible' : [('is_pack','=',False)] }"> | |||
|                         <group name="pack_properties"> | |||
|                             <group string="Pack Price"> | |||
|                                 <label for="pack_price"/> | |||
|                                 <div class="o_row"> | |||
|                                     <field name="pack_price"/> | |||
|                                     <button name="update_price_product" type="object" string="Update Price" | |||
|                                             class="oe_link oe_read_only pt-0"/> | |||
|                                 </div> | |||
|                             </group> | |||
|                             <group string="Pack Quantity" attrs="{'invisible' : [('type','!=','product')]}"> | |||
|                                 <field name="pack_location_id" attrs="{'required':[('is_pack','=',True)]}"/> | |||
|                                 <label for="pack_quantity"/> | |||
|                                 <div class="o_row"> | |||
|                                     <field name="pack_quantity"/> | |||
|                                     <button name="get_quantity" type="object" string="Get Quantity" | |||
|                                             help='To get the quantity of Pack with respect to the quantity of pack products'/> | |||
|                                     <button name="update_quantity" type="object" string="Update Quantity" | |||
|                                             class="oe_link oe_read_only pt-0"/> | |||
|                                 </div> | |||
|                             </group> | |||
|                         </group> | |||
|                         <field name="pack_products_ids" nolabel="1" | |||
|                                attrs="{'readonly':[('pack_location_id','=',False)]}"> | |||
|                             <tree editable="botttom"> | |||
|                                 <field name="product_id" string="Product" options='{"no_open":True}'/> | |||
|                                 <field name="quantity" string="Quantity"/> | |||
|                                 <field name="price"/> | |||
|                                 <field name="qty_available"/> | |||
|                                 <field name="total_available_quantity" invisible="True"/> | |||
| 
 | |||
|                             </tree> | |||
|                         </field> | |||
|                     </page> | |||
|                 </xpath> | |||
|             </field> | |||
|         </record> | |||
| 
 | |||
|         <record id="product_pack_action" model="ir.actions.act_window"> | |||
|             <field name="name">Product Pack</field> | |||
|             <field name="type">ir.actions.act_window</field> | |||
|             <field name="res_model">product.template</field> | |||
|             <field name="view_mode">kanban,form</field> | |||
|             <field name="domain">[('is_pack','=',True)]</field> | |||
|             <field name="context">{'default_is_pack' : True}</field> | |||
|             <field name="help" type="html"> | |||
|                 <p class="oe_view_nocontent_create"> | |||
|                     There is no product pack to show...! | |||
|                 </p> | |||
|             </field> | |||
|         </record> | |||
| 
 | |||
|         <record id="product_pack_filter" model="ir.ui.view"> | |||
|             <field name="name">product.template.search.inherit</field> | |||
|             <field name="model">product.template</field> | |||
|             <field name="inherit_id" ref="product.product_template_search_view"/> | |||
|             <field name="arch" type="xml"> | |||
|                 <xpath expr="//search" position="inside"> | |||
|                     <filter string="Is a Pack" name="Is a Pack" domain="[('is_pack','=',True)]"/> | |||
|                 </xpath> | |||
|             </field> | |||
|         </record> | |||
| 
 | |||
|         <menuitem id="pack_product_sale" | |||
|                   name="Product Pack" | |||
|                   parent="sale.product_menu_catalog" | |||
|                   sequence="3" | |||
|                   action="product_pack_action"/> | |||
| 
 | |||
|     </data> | |||
| </odoo> | |||
| @ -0,0 +1,119 @@ | |||
| <?xml version="1.0" encoding="UTF-8" ?> | |||
| <odoo> | |||
|     <!-- Modify product.product form view --> | |||
|     <record id="product_normal_form_view" model="ir.ui.view"> | |||
|         <field name="name"> | |||
|             product.product.form.view.inherit.product.combo.pack | |||
|         </field> | |||
|         <field name="model">product.product</field> | |||
|         <field name="inherit_id" ref="product.product_normal_form_view"/> | |||
|         <field name="arch" type="xml"> | |||
|             <!-- Add the 'is_pack' field to the 'options' div --> | |||
|             <xpath expr="//div[@name='options']" position="inside"> | |||
|                 <div modifiers="{}"> | |||
|                     <field name="is_pack" modifiers="{}"/> | |||
|                     <label for="is_pack" modifiers="{}"/> | |||
|                 </div> | |||
|             </xpath> | |||
|         </field> | |||
|     </record> | |||
|     <!-- Modify product.template form view --> | |||
|     <record id="product_template_only_form_view" model="ir.ui.view"> | |||
|         <field name="name"> | |||
|             product.template.form.view.inherit.product.combo.pack | |||
|         </field> | |||
|         <field name="model">product.template</field> | |||
|         <field name="inherit_id" | |||
|                ref="product.product_template_only_form_view"/> | |||
|         <field name="arch" type="xml"> | |||
|             <xpath expr="//div[@name='options']" position="inside"> | |||
|                 <div modifiers="{}"> | |||
|                     <field name="is_pack" modifiers="{}"/> | |||
|                     <label for="is_pack" modifiers="{}"/> | |||
|                 </div> | |||
|             </xpath> | |||
|             <xpath expr="//page[@name='variants']" position="attributes"> | |||
|                 <attribute name="attrs">{'invisible': | |||
|                     [('is_pack','=',True)]} | |||
|                 </attribute> | |||
|             </xpath> | |||
|             <xpath expr="//page[@name='invoicing']" position="after"> | |||
|                 <page string="Product Pack" name="product_pack" | |||
|                       attrs="{'invisible' : [('is_pack','=',False)] }"> | |||
|                     <group name="pack_properties"> | |||
|                         <group string="Pack Price"> | |||
|                             <label for="pack_price"/> | |||
|                             <div class="o_row"> | |||
|                                 <field name="pack_price"/> | |||
|                                 <button name="update_price_product" | |||
|                                         type="object" | |||
|                                         string="Update Price"/> | |||
|                             </div> | |||
|                         </group> | |||
|                         <group string="Pack Quantity" | |||
|                                attrs="{'invisible' : [('type','!=','product')]}"> | |||
|                             <field name="pack_location_id" | |||
|                                    attrs="{'required':[('is_pack','=',True)]}"/> | |||
|                             <label for="pack_quantity"/> | |||
|                             <div class="o_row"> | |||
|                                 <field name="pack_quantity"/> | |||
|                                 <button name="get_quantity" type="object" | |||
|                                         string="Get Quantity" | |||
|                                         help='To get the quantity of Pack with respect to the quantity of pack products'/> | |||
|                                 <button name="update_quantity" type="object" | |||
|                                         string="Update Quantity"/> | |||
|                             </div> | |||
|                         </group> | |||
|                     </group> | |||
|                     <field name="pack_products_ids" | |||
|                            attrs="{'readonly':[('pack_location_id','=',False)]}"> | |||
|                         <tree editable="botttom"> | |||
|                             <field name="product_id" string="Product" | |||
|                                    options='{"no_open":True}'/> | |||
|                             <field name="quantity" string="Quantity"/> | |||
|                             <field name="price"/> | |||
|                             <field name="qty_available"/> | |||
|                             <field name="total_available_quantity" | |||
|                                    invisible="True"/> | |||
|                         </tree> | |||
|                     </field> | |||
|                 </page> | |||
|             </xpath> | |||
|         </field> | |||
|     </record> | |||
|     <!-- Define an action for the Product Pack menu item --> | |||
|     <record id="product_pack_action" model="ir.actions.act_window"> | |||
|         <field name="name">Product Pack</field> | |||
|         <field name="type">ir.actions.act_window</field> | |||
|         <field name="res_model">product.template</field> | |||
|         <field name="view_mode">kanban,form</field> | |||
|         <field name="domain">[('is_pack','=',True)]</field> | |||
|         <field name="context">{'default_is_pack' : True}</field> | |||
|         <field name="help" type="html"> | |||
|             <p class="oe_view_nocontent_create"> | |||
|                 There is no product pack to show...! | |||
|             </p> | |||
|         </field> | |||
|     </record> | |||
|     <!-- Modify product.template search view --> | |||
|     <record id="product_template_search_view" model="ir.ui.view"> | |||
|         <field name="name"> | |||
|             product.template.search.view.inherit.product.combo.pack | |||
|         </field> | |||
|         <field name="model">product.template</field> | |||
|         <field name="inherit_id" | |||
|                ref="product.product_template_search_view"/> | |||
|         <field name="arch" type="xml"> | |||
|             <xpath expr="//search" position="inside"> | |||
|                 <filter string="Is a Pack" name="Is a Pack" | |||
|                         domain="[('is_pack','=',True)]"/> | |||
|             </xpath> | |||
|         </field> | |||
|     </record> | |||
|     <!-- Add the Product Pack menu item --> | |||
|     <menuitem id="pack_product_sale" | |||
|               name="Product Pack" | |||
|               parent="sale.product_menu_catalog" | |||
|               sequence="3" | |||
|               action="product_pack_action"/> | |||
| </odoo> | |||
| @ -1,15 +0,0 @@ | |||
| <odoo> | |||
|     <data> | |||
|         <!-- Inherit Form View to Modify it --> | |||
|         <record id="product_pack_sale_order" model="ir.ui.view"> | |||
|             <field name="name">Product Pack in sale order</field> | |||
|             <field name="model">sale.order</field> | |||
|             <field name="inherit_id" ref="sale.view_order_form"/> | |||
|             <field name="arch" type="xml"> | |||
|                 <xpath expr="//field[@name='order_line']" position="before"> | |||
|                     <button name="%(action_product_pack_wizard)d" type="action" string="Add Product Pack" style="margin-bottom : 16px;"/> | |||
|                 </xpath> | |||
|             </field> | |||
|         </record> | |||
|     </data> | |||
| </odoo> | |||
| @ -0,0 +1,16 @@ | |||
| <?xml version="1.0" encoding="UTF-8" ?> | |||
| <odoo> | |||
|     <!-- Inherit Form View to Modify it --> | |||
|     <record id="view_order_form" model="ir.ui.view"> | |||
|         <field name="name">sale.order.form.view.inherit.product.combo.pack | |||
|         </field> | |||
|         <field name="model">sale.order</field> | |||
|         <field name="inherit_id" ref="sale.view_order_form"/> | |||
|         <field name="arch" type="xml"> | |||
|             <field name="sale_order_template_id" position="before"> | |||
|                 <field name="product_pack_id" options="{'no_create': True}" | |||
|                 /> | |||
|             </field> | |||
|         </field> | |||
|     </record> | |||
| </odoo> | |||
| @ -1,24 +0,0 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################### | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). | |||
| #    Author: Afras Habis (odoo@cybrosys.com) | |||
| # | |||
| #    This program is free software: you can modify | |||
| #    it under the terms of the GNU Affero General Public License (AGPL) as | |||
| #    published by the Free Software Foundation, either version 3 of the | |||
| #    License, or (at your option) any later version. | |||
| # | |||
| #    This program is distributed in the hope that it will be useful, | |||
| #    but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | |||
| #    GNU Affero General Public License for more details. | |||
| # | |||
| #    You should have received a copy of the GNU Affero General Public License | |||
| #    along with this program.  If not, see <https://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################### | |||
| 
 | |||
| from . import select_product_pack | |||
| @ -1,58 +0,0 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################### | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). | |||
| #    Author: Afras Habis (odoo@cybrosys.com) | |||
| # | |||
| #    This program is free software: you can modify | |||
| #    it under the terms of the GNU Affero General Public License (AGPL) as | |||
| #    published by the Free Software Foundation, either version 3 of the | |||
| #    License, or (at your option) any later version. | |||
| # | |||
| #    This program is distributed in the hope that it will be useful, | |||
| #    but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | |||
| #    GNU Affero General Public License for more details. | |||
| # | |||
| #    You should have received a copy of the GNU Affero General Public License | |||
| #    along with this program.  If not, see <https://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################### | |||
| 
 | |||
| from odoo import api, fields, models, _ | |||
| from odoo.exceptions import ValidationError | |||
| 
 | |||
| 
 | |||
| class SelectPack(models.TransientModel): | |||
|     _name = 'select.product.pack' | |||
|     _rec_name = 'product_id' | |||
|     _description = 'Add product pack to sale order' | |||
| 
 | |||
|     product_id = fields.Many2one('product.product', string='Select Pack', domain=[('is_pack', '=', True)], | |||
|                                  required=True) | |||
|     quantity = fields.Integer('Quantity', default=1, required=True) | |||
| 
 | |||
|     def add_pack_order(self): | |||
|         active_id = self._context.get('active_id') | |||
|         if active_id: | |||
|             sale_id = self.env['sale.order'].browse(active_id) | |||
|             name = self.product_id.display_name | |||
|             if self.product_id.description_sale: | |||
|                 name += '\n' + self.product_id.description_sale | |||
|             self.env['sale.order.line'].create({ | |||
|                 'product_id': self.product_id.id, | |||
|                 # 'price_unit': self.product_id.lst_price, | |||
|                 # 'pricelist_item_id': self.product_id.lst_price, | |||
|                 'product_uom': self.product_id.uom_id.id, | |||
|                 'product_uom_qty': self.quantity, | |||
|                 'order_id': sale_id.id, | |||
|                 'name': name, | |||
|                 'tax_id': self.product_id.taxes_id.ids | |||
|             }) | |||
| 
 | |||
|     @api.constrains('quantity') | |||
|     def _check_positive_qty(self): | |||
|         if any([ml.quantity < 0 for ml in self]): | |||
|             raise ValidationError(_('You can not enter negative quantities.')) | |||
| @ -1,32 +0,0 @@ | |||
| <odoo> | |||
|     <data> | |||
|         <record id="action_product_pack_wizard" model="ir.actions.act_window"> | |||
|             <field name="name">Select Pack Products</field> | |||
|             <field name="type">ir.actions.act_window</field> | |||
|             <field name="res_model">select.product.pack</field> | |||
|             <field name="view_mode">form</field> | |||
|             <field name="target">new</field> | |||
|         </record> | |||
| 
 | |||
|         <record id="product_pack_product_form" model="ir.ui.view"> | |||
|             <field name="name">Product Pack</field> | |||
|             <field name="model">select.product.pack</field> | |||
|             <field name="arch" type="xml"> | |||
|                 <form> | |||
|                     <group> | |||
|                         <group> | |||
|                             <field name="product_id"/> | |||
|                         </group> | |||
|                         <group> | |||
|                             <field name="quantity"/> | |||
|                         </group> | |||
|                     </group> | |||
|                     <footer> | |||
|                         <button name="add_pack_order" string="ADD" type="object"/> | |||
|                         <button string="Cancel" class="btn-secondary" special="cancel"/> | |||
|                     </footer> | |||
|                 </form> | |||
|             </field> | |||
|         </record> | |||
|     </data> | |||
| </odoo> | |||