diff --git a/multi_pricelist/README.rst b/multi_pricelist/README.rst new file mode 100644 index 000000000..28446ef62 --- /dev/null +++ b/multi_pricelist/README.rst @@ -0,0 +1,45 @@ +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg + :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +Sale Order Multiple Pricelist +------------------------------- +* Multiple pricelists can be applied to the same sale order + +Configuration +------------- +- Need to turn on the option "Multiple Pricelist per Order" from the Sale Order configuration + +License +------- +Affero General Public License, Version 3 (AGPL v3). +(https://www.odoo.com/documentation/user/15.0/legal/licenses/licenses.html) + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developer: (V15) Raveena , + (V15) Anjana P V, +Contact: odoo@cybrosys.com + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +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: ``__ diff --git a/multi_pricelist/__init__.py b/multi_pricelist/__init__.py new file mode 100644 index 000000000..66eab057d --- /dev/null +++ b/multi_pricelist/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Raveena V (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import models +from . import wizards diff --git a/multi_pricelist/__manifest__.py b/multi_pricelist/__manifest__.py new file mode 100644 index 000000000..7b2f32e81 --- /dev/null +++ b/multi_pricelist/__manifest__.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Raveena V (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +{ + 'name': "Sale Order Multiple Pricelist", + 'version': '15.0.1.0.0', + 'category': 'Sales', + 'summary': 'Multiple price lists can be applied to the same sale order', + 'description': """User can apply different price lists for ech order lines + of the same Sale Order.""", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'depends': ['sale_management'], + 'website': 'https://www.cybrosys.com', + 'data': [ + 'security/ir.model.access.csv', + 'views/sale_order_views.xml', + 'views/res_config_settings_views.xml', + 'wizards/pricelist_wizard_views.xml' + ], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/multi_pricelist/doc/RELEASE_NOTES.md b/multi_pricelist/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..9ec3dddcf --- /dev/null +++ b/multi_pricelist/doc/RELEASE_NOTES.md @@ -0,0 +1,5 @@ +## Module +### 20.04.2024 +### Version 15.0.1.0.0 +#### ADD +- Initial Commit for Sale Order Multiple Pricelist diff --git a/multi_pricelist/models/__init__.py b/multi_pricelist/models/__init__.py new file mode 100644 index 000000000..06dcc7fc1 --- /dev/null +++ b/multi_pricelist/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Raveena V (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import res_config_settings +from . import sale_order_line diff --git a/multi_pricelist/models/res_config_settings.py b/multi_pricelist/models/res_config_settings.py new file mode 100644 index 000000000..3ca626f00 --- /dev/null +++ b/multi_pricelist/models/res_config_settings.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Raveena V (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import api, fields, models + + +class ResConfigSettings(models.TransientModel): + """This class inherits res config settings model to add the settings + for multiple price lists""" + _inherit = 'res.config.settings' + + multi_pricelist = fields.Boolean(string="Order", help="Multiple price lists" + "for the same sale order") + + @api.model + def get_values(self): + """Supering the get_values method to get multi_price list field.""" + res = super(ResConfigSettings, self).get_values() + multi_pricelist = self.env[ + 'ir.config_parameter'].sudo().get_param( + 'multi_pricelist.multi_pricelist') + res.update( + multi_pricelist=multi_pricelist, + ) + return res + + def set_values(self): + """Supering the set_values method to set multi_price list field.""" + super(ResConfigSettings, self).set_values() + param = self.env['ir.config_parameter'].sudo() + param.set_param('multi_pricelist.multi_pricelist', + self.multi_pricelist) diff --git a/multi_pricelist/models/sale_order_line.py b/multi_pricelist/models/sale_order_line.py new file mode 100644 index 000000000..e9a444023 --- /dev/null +++ b/multi_pricelist/models/sale_order_line.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Raveena V (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from datetime import datetime +from odoo import fields, models, _ +from odoo.exceptions import UserError + + +class SaleOrderLine(models.Model): + """Inherits Sale order line to add the functions for checking the + visibility of the pricelists in order lines and also apply the + pricelist to order lines""" + _inherit = 'sale.order.line' + + pricelist_visibility = fields.Boolean( + compute="_compute_pricelist_visibility", string="Pricelist Visible", + help="Multi Pricelist enabled or not") + applied_pricelist_id = fields.Many2one('product.pricelist', + string="PriceList", + help="Price lists that is applied to" + "the order line.") + + def _get_display_price(self, product): + """Overwrite the function to set the unit price according to the + applied pricelist from the orderline and the UoM""" + # TO DO: move me in master/saas-16 on sale.order + # awa: don't know if it's still the case since we need the + # "product_no_variant_attribute_value_ids" field now + # to be able to compute the full price + # it is possible that a no_variant attribute is still in a variant if + # the type of the attribute has been changed after creation. + no_variant_attributes_price_extra = [ + ptav.price_extra for ptav in + self.product_no_variant_attribute_value_ids.filtered( + lambda ptav: + ptav.price_extra and + ptav not in product.product_template_attribute_value_ids + ) + ] + if no_variant_attributes_price_extra: + product = product.with_context( + no_variant_attributes_price_extra=tuple( + no_variant_attributes_price_extra) + ) + if self.order_id.pricelist_id.discount_policy == 'with_discount': + if self.applied_pricelist_id: + return product.with_context( + pricelist=self.applied_pricelist_id.id, uom=self.product_uom.id, + quantity=self.product_uom_qty + ).price + else: + return product.with_context( + pricelist=self.order_id.pricelist_id.id, + uom=self.product_uom.id).price + product_context = dict(self.env.context, + partner_id=self.order_id.partner_id.id, + date=self.order_id.date_order, + uom=self.product_uom.id) + final_price, rule_id = self.order_id.pricelist_id.with_context( + product_context).get_product_price_rule(product or self.product_id, + self.product_uom_qty or 1.0, + self.order_id.partner_id) + base_price, currency = self.with_context( + product_context)._get_real_price_currency(product, rule_id, + self.product_uom_qty, + self.product_uom, + self.order_id.pricelist_id.id) + if currency != self.order_id.pricelist_id.currency_id: + base_price = currency._convert( + base_price, self.order_id.pricelist_id.currency_id, + self.order_id.company_id or self.env.company, + self.order_id.date_order or fields.Date.today()) + # negative discounts (= surcharge) are included in the display price + return max(base_price, final_price) + + def apply_pricelist(self): + """This function will help to select all the pricelists + for a product in order line and apply it""" + for rec in self: + date_time_today = datetime.today().strftime("%Y-%m-%d %H:%M:%S") + # find the matching price list for a product + price_ids = self.env['product.pricelist.item'].search( + ['|', '|', ('product_tmpl_id', '=', False), + ('categ_id', '=', rec.product_id.categ_id.id), + ('product_tmpl_id', '=', rec.product_id.product_tmpl_id.id), + ('min_quantity', '<=', rec.product_uom_qty),'|', + ('date_start', '<=', date_time_today), + ('date_start', '=', False), '|', + ('date_end', '>=', date_time_today), + ('date_end', '=', False), + ]) + variant_ids = self.env['product.pricelist.item'].search( + [ + ('product_id', '=', rec.product_id.id), + ('min_quantity', '<=', rec.product_uom_qty), + '|', ('date_start', '<=', date_time_today), + ('date_start', '=', False), '|', + ('date_end', '>=', date_time_today), + ('date_end', '=', False), + ]) + combined_ids = price_ids + variant_ids + if combined_ids: + pricelist_wizard = self.env['pricelist.wizard'].create({ + 'order_line_id': rec.id, + 'line_ids': [(0, 0, { + 'pricelist_id': price.pricelist_id.id, + 'product_id': rec.product_id.id, + 'unit_price': self.unit_price(price), + 'unit_cost': rec.product_id.standard_price, + 'uom_id': rec.product_id.uom_id.id + }) for price in combined_ids], + }) + else: + raise UserError(_( + "No price list is configured for this product!")) + return { + 'type': 'ir.actions.act_window', + 'target': 'new', + 'name': 'Select Pricelist', + 'view_mode': 'form', + 'view_id': self.env.ref( + "multi_pricelist.pricelist_wizard_view_form", False).id, + 'res_model': 'pricelist.wizard', + 'res_id': pricelist_wizard.id, + } + + def _compute_pricelist_visibility(self): + """ Computes pricelist_visibility by checking the config parameter.""" + for rec in self: + rec.pricelist_visibility = self.env[ + 'ir.config_parameter'].sudo().get_param( + 'multi_pricelist.multi_pricelist') + if rec.order_id.state in ['sale', 'done', 'cancel']: + rec.pricelist_visibility = False + + def unit_price(self, price): + """Compute the unit price of the product according to the + price_list_item""" + if price.compute_price == 'fixed': + unt_price = price.fixed_price + elif price.compute_price == 'percentage' and price.percent_price != 0: + unt_price = self.product_id.list_price * ( + 1 - price.percent_price / 100) + elif price.compute_price == 'formula' and price.base == 'list_price': + unt_price = (self.product_id.list_price * ( + 1 - price.price_discount / 100) + price.price_surcharge) + if price.price_min_margin or price.price_max_margin: + if (unt_price < price.price_min_margin + + self.product_id.list_price): + unt_price = (price.price_min_margin + + self.product_id.list_price) + elif (unt_price > price.price_max_margin + + self.product_id.list_price): + unt_price = (price.price_max_margin + + self.product_id.list_price) + else: + unt_price = unt_price + elif price.compute_price == 'formula' and price.base == 'standard_price': + unt_price = (self.product_id.standard_price * ( + 1 - price.price_discount / 100) + price.price_surcharge) + if price.price_min_margin or price.price_max_margin: + if (unt_price < price.price_min_margin + + self.product_id.list_price): + unt_price = (price.price_min_margin + + self.product_id.list_price) + elif (unt_price > price.price_max_margin + + self.product_id.list_price): + unt_price = (price.price_max_margin + + self.product_id.list_price) + else: + unt_price = unt_price + elif price.compute_price == 'formula' and price.base == 'pricelist': + unt_price = (self.unit_price(price.base_pricelist_id.item_ids) * ( + 1 - price.price_discount / 100) + price.price_surcharge) + if price.price_min_margin or price.price_max_margin: + if (unt_price < price.price_min_margin + + self.product_id.list_price): + unt_price = (price.price_min_margin + + self.product_id.list_price) + elif (unt_price > price.price_max_margin + + self.product_id.list_price): + unt_price = (price.price_max_margin + + self.product_id.list_price) + else: + unt_price = unt_price + else: + unt_price = self.product_id.list_price + return unt_price diff --git a/multi_pricelist/security/ir.model.access.csv b/multi_pricelist/security/ir.model.access.csv new file mode 100644 index 000000000..9128b3ac9 --- /dev/null +++ b/multi_pricelist/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_pricelist_wizard_user,access.pricelist.wizard.user,model_pricelist_wizard,base.group_user,1,1,1,1 +access_pricelist_wizard_line_user,access.pricelist.wizard.line.user,model_pricelist_wizard_line,base.group_user,1,1,1,1 diff --git a/multi_pricelist/static/description/assets/icons/check.png b/multi_pricelist/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/check.png differ diff --git a/multi_pricelist/static/description/assets/icons/chevron.png b/multi_pricelist/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/chevron.png differ diff --git a/multi_pricelist/static/description/assets/icons/cogs.png b/multi_pricelist/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/cogs.png differ diff --git a/multi_pricelist/static/description/assets/icons/consultation.png b/multi_pricelist/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/consultation.png differ diff --git a/multi_pricelist/static/description/assets/icons/ecom-black.png b/multi_pricelist/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/ecom-black.png differ diff --git a/multi_pricelist/static/description/assets/icons/education-black.png b/multi_pricelist/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/education-black.png differ diff --git a/multi_pricelist/static/description/assets/icons/hotel-black.png b/multi_pricelist/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/hotel-black.png differ diff --git a/multi_pricelist/static/description/assets/icons/license.png b/multi_pricelist/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/license.png differ diff --git a/multi_pricelist/static/description/assets/icons/lifebuoy.png b/multi_pricelist/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/lifebuoy.png differ diff --git a/multi_pricelist/static/description/assets/icons/logo.png b/multi_pricelist/static/description/assets/icons/logo.png new file mode 100644 index 000000000..478462d3e Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/logo.png differ diff --git a/multi_pricelist/static/description/assets/icons/manufacturing-black.png b/multi_pricelist/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/manufacturing-black.png differ diff --git a/multi_pricelist/static/description/assets/icons/pos-black.png b/multi_pricelist/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/pos-black.png differ diff --git a/multi_pricelist/static/description/assets/icons/puzzle.png b/multi_pricelist/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/puzzle.png differ diff --git a/multi_pricelist/static/description/assets/icons/restaurant-black.png b/multi_pricelist/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/restaurant-black.png differ diff --git a/multi_pricelist/static/description/assets/icons/service-black.png b/multi_pricelist/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/service-black.png differ diff --git a/multi_pricelist/static/description/assets/icons/trading-black.png b/multi_pricelist/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/trading-black.png differ diff --git a/multi_pricelist/static/description/assets/icons/training.png b/multi_pricelist/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/training.png differ diff --git a/multi_pricelist/static/description/assets/icons/update.png b/multi_pricelist/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/update.png differ diff --git a/multi_pricelist/static/description/assets/icons/user.png b/multi_pricelist/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/user.png differ diff --git a/multi_pricelist/static/description/assets/icons/wrench.png b/multi_pricelist/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/multi_pricelist/static/description/assets/icons/wrench.png differ diff --git a/multi_pricelist/static/description/assets/modules/1.png b/multi_pricelist/static/description/assets/modules/1.png new file mode 100644 index 000000000..3ad04ecfd Binary files /dev/null and b/multi_pricelist/static/description/assets/modules/1.png differ diff --git a/multi_pricelist/static/description/assets/modules/2.png b/multi_pricelist/static/description/assets/modules/2.png new file mode 100644 index 000000000..baaef2807 Binary files /dev/null and b/multi_pricelist/static/description/assets/modules/2.png differ diff --git a/multi_pricelist/static/description/assets/modules/3.png b/multi_pricelist/static/description/assets/modules/3.png new file mode 100644 index 000000000..04d502e26 Binary files /dev/null and b/multi_pricelist/static/description/assets/modules/3.png differ diff --git a/multi_pricelist/static/description/assets/modules/4.png b/multi_pricelist/static/description/assets/modules/4.png new file mode 100644 index 000000000..d01ceb1ab Binary files /dev/null and b/multi_pricelist/static/description/assets/modules/4.png differ diff --git a/multi_pricelist/static/description/assets/modules/5.png b/multi_pricelist/static/description/assets/modules/5.png new file mode 100644 index 000000000..230d4dcb3 Binary files /dev/null and b/multi_pricelist/static/description/assets/modules/5.png differ diff --git a/multi_pricelist/static/description/assets/modules/6.png b/multi_pricelist/static/description/assets/modules/6.png new file mode 100644 index 000000000..499b1a72f Binary files /dev/null and b/multi_pricelist/static/description/assets/modules/6.png differ diff --git a/multi_pricelist/static/description/assets/screenshots/ml1.png b/multi_pricelist/static/description/assets/screenshots/ml1.png new file mode 100644 index 000000000..3b35756fe Binary files /dev/null and b/multi_pricelist/static/description/assets/screenshots/ml1.png differ diff --git a/multi_pricelist/static/description/assets/screenshots/ml2.png b/multi_pricelist/static/description/assets/screenshots/ml2.png new file mode 100644 index 000000000..c291f149b Binary files /dev/null and b/multi_pricelist/static/description/assets/screenshots/ml2.png differ diff --git a/multi_pricelist/static/description/assets/screenshots/ml3.png b/multi_pricelist/static/description/assets/screenshots/ml3.png new file mode 100644 index 000000000..2cec38d67 Binary files /dev/null and b/multi_pricelist/static/description/assets/screenshots/ml3.png differ diff --git a/multi_pricelist/static/description/assets/screenshots/mp1.png b/multi_pricelist/static/description/assets/screenshots/mp1.png new file mode 100644 index 000000000..f3f27edf8 Binary files /dev/null and b/multi_pricelist/static/description/assets/screenshots/mp1.png differ diff --git a/multi_pricelist/static/description/assets/screenshots/mp2.png b/multi_pricelist/static/description/assets/screenshots/mp2.png new file mode 100644 index 000000000..ca1870349 Binary files /dev/null and b/multi_pricelist/static/description/assets/screenshots/mp2.png differ diff --git a/multi_pricelist/static/description/assets/screenshots/mp3.png b/multi_pricelist/static/description/assets/screenshots/mp3.png new file mode 100644 index 000000000..19943d190 Binary files /dev/null and b/multi_pricelist/static/description/assets/screenshots/mp3.png differ diff --git a/multi_pricelist/static/description/assets/screenshots/mp4.png b/multi_pricelist/static/description/assets/screenshots/mp4.png new file mode 100644 index 000000000..038c412f3 Binary files /dev/null and b/multi_pricelist/static/description/assets/screenshots/mp4.png differ diff --git a/multi_pricelist/static/description/assets/screenshots/mp5.png b/multi_pricelist/static/description/assets/screenshots/mp5.png new file mode 100644 index 000000000..96aac39e4 Binary files /dev/null and b/multi_pricelist/static/description/assets/screenshots/mp5.png differ diff --git a/multi_pricelist/static/description/assets/screenshots/mp6.png b/multi_pricelist/static/description/assets/screenshots/mp6.png new file mode 100644 index 000000000..ea262d3f3 Binary files /dev/null and b/multi_pricelist/static/description/assets/screenshots/mp6.png differ diff --git a/multi_pricelist/static/description/banner.png b/multi_pricelist/static/description/banner.png new file mode 100644 index 000000000..89e1d1310 Binary files /dev/null and b/multi_pricelist/static/description/banner.png differ diff --git a/multi_pricelist/static/description/icon.png b/multi_pricelist/static/description/icon.png new file mode 100644 index 000000000..daa72766b Binary files /dev/null and b/multi_pricelist/static/description/icon.png differ diff --git a/multi_pricelist/static/description/images/checked.png b/multi_pricelist/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/multi_pricelist/static/description/images/checked.png differ diff --git a/multi_pricelist/static/description/images/cybrosys.png b/multi_pricelist/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/multi_pricelist/static/description/images/cybrosys.png differ diff --git a/multi_pricelist/static/description/index.html b/multi_pricelist/static/description/index.html new file mode 100644 index 000000000..37b71b723 --- /dev/null +++ b/multi_pricelist/static/description/index.html @@ -0,0 +1,672 @@ + + + + + +
+
+
+ +
+
+
+ Community +
+
+ Enterprise +
+ +
+
+
+
+
+
+

+ Sale Order Multiple Price list

+

+ Multiple price lists can be applied for same sale order. +

+ +
+
+ + + + +
+
+

+ Overview +

+
+ +
+

+ This module help you to apply different price lists for each order lines.

+ +
+
+ +
+
+

+ Features +

+
+ +
+
+ +
+
+

+ Multiple price lists per order

+

+ If you want to use different price lists with a single sale order, just enable the multiple price lists per order feature from settings.

+
+
+ +
+
+ +
+
+

+ Each line may have different price lists

+

+ You can select price list for each sale order line by apply price list button.

+
+
+ +
+
+ +
+
+

+ Select from multiple price lists

+

+ If a product in sale order line have multiple price lists, you can select one among them.

+
+
+ +
+
+ +
+
+

+ View Margin in percentage.

+

+ You can view the margin in percentage along with different prices.

+
+
+ +
+ +
+
+

+ Screenshots +

+
+ +
+

+ Enable Multiple price list per order.

+

+ You can enable multiple price list per order feature from configuration settings.

+ + +
+ +
+

+ Configure price lists

+

+ Configuring different price lists. +

+ + +
+ + +
+

+ Create Sale order

+

+ Create and save sale order. +

+ +
+
+

+ Apply Price list

+

+ Apply price list button in each order line.

+ +
+
+

+ Choose price list

+

+ You can choose price list from the popup window.

+ +
+
+

+ Price updated

+

+ Price for that product is updated with that selected price list.

+ +
+
+

+ Apply another price list for next product

+

+ You can apply another price list for next order line of the same sale order.

+ +
+
+

+ Price updated

+

+ Price for that product is updated with that selected price list.

+ +
+
+

+ Unit price and subtotal changed accordingly

+

+ Unit prices as well as total and subtotal changed accordingly.

+ +
+
+ + +
+
+

Suggested Products

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

Our Services

+
+
+ +
+
+ +
+
+ Odoo + Customization
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Support
+
+ + +
+
+ +
+
+ Hire + Odoo + Developer
+
+ +
+
+ +
+
+ Odoo + Integration
+
+ +
+
+ +
+
+ Odoo + Migration
+
+ + +
+
+ +
+
+ Odoo + Consultancy
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+
+ + + +
+
+
+

Our Industries

+
+
+ +
+
+ +
+ Trading +
+

+ Easily procure + and + sell your products

+
+
+ +
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+ +
+
+ +
+ Education +
+

+ A platform for + educational management

+
+
+ +
+
+ +
+ Manufacturing +
+

+ Plan, track and + schedule your operations

+
+
+ +
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+ +
+
+ +
+ Service Management +
+

+ Keep track of + services and invoice

+
+
+ +
+
+ +
+ Restaurant +
+

+ Run your bar or + restaurant methodically

+
+
+ +
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

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

Need Help?

+
+
+
+ + +
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+ +
\ No newline at end of file diff --git a/multi_pricelist/views/res_config_settings_views.xml b/multi_pricelist/views/res_config_settings_views.xml new file mode 100644 index 000000000..3b64e4bb6 --- /dev/null +++ b/multi_pricelist/views/res_config_settings_views.xml @@ -0,0 +1,31 @@ + + + + + res.config.settings.view.form.inherit.multi.pricelist + res.config.settings + + + +
+
+ +
+
+
+
+
+
+
+
diff --git a/multi_pricelist/views/sale_order_views.xml b/multi_pricelist/views/sale_order_views.xml new file mode 100644 index 000000000..8519faeb8 --- /dev/null +++ b/multi_pricelist/views/sale_order_views.xml @@ -0,0 +1,21 @@ + + + + + sale.order.view.form.inherit.multi.pricelist + sale.order + + + + + + + + + + diff --git a/multi_pricelist/wizards/__init__.py b/multi_pricelist/wizards/__init__.py new file mode 100644 index 000000000..2774fd5a6 --- /dev/null +++ b/multi_pricelist/wizards/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# + +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Raveena V (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import pricelist_wizard +from . import pricelist_wizard_line diff --git a/multi_pricelist/wizards/pricelist_wizard.py b/multi_pricelist/wizards/pricelist_wizard.py new file mode 100644 index 000000000..6f4d69e7f --- /dev/null +++ b/multi_pricelist/wizards/pricelist_wizard.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Raveena V (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import fields, models + + +class PricelistWizard(models.TransientModel): + """This class will create a new transient model for the price list wizard""" + _name = 'pricelist.wizard' + _rec_name = 'order_line_id' + _description = 'Price list Wizard' + + order_line_id = fields.Many2one('sale.order.line', + string="Order Line", + help="Order line of the selected order") + line_ids = fields.One2many('pricelist.wizard.line', 'wizard_id', + string="Price lists", help="Pricelist lines") + + diff --git a/multi_pricelist/wizards/pricelist_wizard_line.py b/multi_pricelist/wizards/pricelist_wizard_line.py new file mode 100644 index 000000000..eb7baf48d --- /dev/null +++ b/multi_pricelist/wizards/pricelist_wizard_line.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Raveena V (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import api, fields, models + + +class PricelistWizardLine(models.TransientModel): + _name = 'pricelist.wizard.line' + _rec_name = 'wizard_id' + _description = 'Pricelist Lines' + + wizard_id = fields.Many2one('pricelist.wizard', + string="Price List Selection", + help="Price List Selection") + pricelist_id = fields.Many2one('product.pricelist', + string="PriceList", + help="Price lists that can be applied for " + "the order line.") + product_id = fields.Many2one('product.product', + string="Product", + help="Order line Product") + unit_price = fields.Float(string="Unit Price", + help="Price of the product per unit") + unit_cost = fields.Float(string='Unit Cost', + help="Cost of the product per unit") + margin = fields.Float(compute='_compute_margin', string="Margin %", + help="calculated by ((unit price - unit cost) " + "unit cost)* 100") + uom_id = fields.Many2one('uom.uom', string="UOM", help="Unit Of Measure") + + @api.depends('unit_price', 'unit_cost') + def _compute_margin(self): + """ This function will compute the margin for the product when the + price list applied. + It is calculated by ((unit price - unit cost)/ unit cost)* 100""" + for rec in self: + rec.margin = 100 + if rec.unit_cost: + rec.margin = ((rec.unit_price-rec.unit_cost)/rec.unit_cost)*100 + + def apply_pricelist(self): + """This function will apply the selected pricelist to the order + line.""" + for rec in self: + sale_order_line = rec.wizard_id.order_line_id + rec.wizard_id.order_line_id.update({ + 'applied_pricelist_id': rec.pricelist_id, + }) + rec.wizard_id.order_line_id.update({ + 'price_unit':sale_order_line._get_display_price( + sale_order_line.product_id), + }) diff --git a/multi_pricelist/wizards/pricelist_wizard_views.xml b/multi_pricelist/wizards/pricelist_wizard_views.xml new file mode 100644 index 000000000..2975a173d --- /dev/null +++ b/multi_pricelist/wizards/pricelist_wizard_views.xml @@ -0,0 +1,38 @@ + + + + + pricelist.wizard.view.form + pricelist.wizard + +
+ +

+ Select one Pricelist +

+ + + + + + + + + +