diff --git a/sale_discount_total/README.rst b/sale_discount_total/README.rst new file mode 100644 index 000000000..52e6fbc37 --- /dev/null +++ b/sale_discount_total/README.rst @@ -0,0 +1,53 @@ +.. 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 Discount on Total Amount +============================= +Discount on Total in Sale and Invoice With Discount Limit and Approval + +Configuration +============= +- No additional configuration required + +Company +------- +* `Cybrosys Techno Solutions `__ + +License +------- +GNU Affero General Public License v3.0 (AGPL v3) +(http://www.gnu.org/licenses/agpl-3.0-standalone.html) + +Credits +------- +* Developer: + Faslu Rahman, + (V14) Muhammed P, + (V15) Sreerag E, + (V16) Sahla Sherin, + (V17) Jumana Haseen, + Contact : odoo@cybrosys.com + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com +* Website : https://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 `Our Website `__ + +Further information +=================== +HTML Description: ``__ diff --git a/sale_discount_total/__init__.py b/sale_discount_total/__init__.py new file mode 100644 index 000000000..cd247d2c5 --- /dev/null +++ b/sale_discount_total/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 reports diff --git a/sale_discount_total/__manifest__.py b/sale_discount_total/__manifest__.py new file mode 100644 index 000000000..ed3a2a453 --- /dev/null +++ b/sale_discount_total/__manifest__.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 Discount on Total Amount', + 'version': '17.0.1.0.0', + 'category': 'Sales Management', + 'summary': "Discount on Total in Sale and Invoice With Discount Limit " + "and Approval", + 'description': "This module is designed to manage discounts on the total " + "amount in sales. It will include features to apply " + "discounts either as a specific amount or a percentage. " + "This module will enhance the functionality of Odoo's sales " + "module, allowing users to easily manage and apply discounts" + " to sales orders based on their requirements.", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'live_test_url': 'https://www.youtube.com/watch?v=CigmHe9iC4s&feature=youtu.be', + 'depends': ['sale_management', 'account'], + 'data': [ + 'views/res_config_settings_views.xml', + 'views/sale_order_views.xml', + 'views/account_move_views.xml', + 'views/account_move_templates.xml', + 'views/sale_order_templates.xml', + ], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/sale_discount_total/doc/RELEASE_NOTES.md b/sale_discount_total/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..203c3c755 --- /dev/null +++ b/sale_discount_total/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 14.03.2024 +#### Version 17.0.1.0.0 +#### ADD +- Initial commit for Sale Discount On Total Amount diff --git a/sale_discount_total/models/__init__.py b/sale_discount_total/models/__init__.py new file mode 100644 index 000000000..6c18c6cbe --- /dev/null +++ b/sale_discount_total/models/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 account_move +from . import res_company +from . import res_config_settings +from . import sale_order +from . import sale_order_line diff --git a/sale_discount_total/models/account_move.py b/sale_discount_total/models/account_move.py new file mode 100644 index 000000000..afa612dc7 --- /dev/null +++ b/sale_discount_total/models/account_move.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 AccountInvoice(models.Model): + """This class inherits "account.move" model and adds discount_type, + discount_rate, amount_discount + """ + _inherit = "account.move" + + discount_type = fields.Selection( + [('percent', 'Percentage'), ('amount', 'Amount')], + string='Discount type', + default='percent', help="Type of discount.") + discount_rate = fields.Float('Discount Rate', digits=(16, 2), + help="Give the discount rate.") + amount_discount = fields.Monetary(string='Discount', store=True, + compute='_compute_amount', readonly=True, + help="Give the amount to be discounted.") + + @api.depends( + 'line_ids.matched_debit_ids.debit_move_id.move_id.payment_' + 'id.is_matched', + 'line_ids.matched_debit_ids.debit_move_id.move_id.line_' + 'ids.amount_residual', + 'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_' + 'residual_currency', + 'line_ids.matched_credit_ids.credit_move_id.move_id.payment_id.is_' + 'matched', + 'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_' + 'residual', + 'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_' + 'residual_currency', + 'line_ids.balance', + 'line_ids.currency_id', + 'line_ids.amount_currency', + 'line_ids.amount_residual', + 'line_ids.amount_residual_currency', + 'line_ids.payment_id.state', + 'line_ids.full_reconcile_id') + def _compute_amount(self): + """This function computes amount based on taxed,untaxed""" + for move in self: + total_untaxed, total_untaxed_currency = 0.0, 0.0 + total_tax, total_tax_currency = 0.0, 0.0 + total_residual, total_residual_currency = 0.0, 0.0 + total, total_currency = 0.0, 0.0 + total_to_pay = move.amount_total + currencies = set() + for line in move.line_ids: + if move.is_invoice(True): + # === Invoices === + if line.display_type == 'tax' or ( + line.display_type == 'rounding' and + line.tax_repartition_line_id): + # Tax amount. + total_tax += line.balance + total_tax_currency += line.amount_currency + total += line.balance + total_currency += line.amount_currency + elif line.display_type in ('product', 'rounding'): + # Untaxed amount. + total_untaxed += line.balance + total_untaxed_currency += line.amount_currency + total += line.balance + total_currency += line.amount_currency + elif line.display_type == 'payment_term': + # Residual amount. + total_residual += line.amount_residual + total_residual_currency += line.amount_residual_currency + else: + # === Miscellaneous journal entry === + if line.debit: + total += line.balance + total_currency += line.amount_currency + sign = move.direction_sign + move.amount_untaxed = sign * (total_untaxed_currency if len( + currencies) == 1 else total_untaxed) + move.amount_tax = sign * ( + total_tax_currency if len(currencies) == 1 else total_tax) + move.amount_total = sign * total_currency + move.amount_residual = -sign * total_residual_currency + move.amount_untaxed_signed = -total_untaxed + move.amount_tax_signed = -total_tax + move.amount_total_signed = abs( + total) if move.move_type == 'entry' else -total + move.amount_residual_signed = total_residual + move.amount_total_in_currency_signed = abs( + move.amount_total) if move.move_type == 'entry' else -( + sign * move.amount_total) + currency = (len( + currencies) == 1 and currencies.pop() or + move.company_id.currency_id) + new_pmt_state = 'not_paid' if move.move_type != 'entry' else False + if move.is_invoice( + include_receipts=True) and move.state == 'posted': + if currency.is_zero(move.amount_residual): + if all(payment.is_matched for payment in + move._get_reconciled_payments()): + new_pmt_state = 'paid' + else: + new_pmt_state = move._get_invoice_in_payment_state() + elif currency.compare_amounts(total_to_pay, + abs(total_residual)) != 0: + new_pmt_state = 'partial' + if new_pmt_state == 'paid' and move.move_type in ( + 'in_invoice', 'out_invoice', 'entry'): + reverse_type = (move.move_type == 'in_invoice' and 'in_refund' + or move.move_type == 'out_invoice' and + 'out_refund' or 'entry') + reverse_moves = self.env['account.move'].search( + [('reversed_entry_id', '=', move.id), + ('state', '=', 'posted'), + ('move_type', '=', reverse_type)]) + # We only set 'reversed' state in case of 1 to 1 full + # reconciliation with a reverse entry; otherwise, we use the + # regular 'paid' state + reverse_moves_full_recs = reverse_moves.mapped( + 'line_ids.full_reconcile_id') + if reverse_moves_full_recs.mapped( + 'reconciled_line_ids.move_id').filtered( + lambda x: x not in ( + reverse_moves + reverse_moves_full_recs.mapped( + 'exchange_move_id'))) == move: + new_pmt_state = 'reversed' + move.payment_state = new_pmt_state + + @api.onchange('discount_type', 'discount_rate', 'invoice_line_ids') + def _supply_rate(self): + """This function calculates supply rates based on change of + discount_type, + discount_rate and invoice_line_ids""" + for inv in self: + if inv.discount_type == 'percent': + discount_totals = 0 + for line in inv.invoice_line_ids: + line.discount = inv.discount_rate + total_price = line.price_unit * line.quantity + discount_total = total_price - line.price_subtotal + discount_totals = discount_totals + discount_total + inv.amount_discount = discount_totals + line._compute_totals() + else: + total = 0.0 + for line in inv.invoice_line_ids: + total += (line.quantity * line.price_unit) + if inv.discount_rate != 0: + discount = (inv.discount_rate / total) * 100 + else: + discount = inv.discount_rate + for line in inv.invoice_line_ids: + line.discount = discount + inv.amount_discount = inv.discount_rate + line._compute_totals() + inv._compute_tax_totals() + + def button_dummy(self): + """The button_dummy method is intended to perform some action related + to the supply rate and always return True""" + self.supply_rate() + return True + + +class AccountInvoiceLine(models.Model): + """This class inherits "account.move.line" model and adds discount field""" + _inherit = "account.move.line" + discount = fields.Float(string='Discount (%)', digits=(16, 20), default=0.0, + help="Give the discount needed") diff --git a/sale_discount_total/models/res_company.py b/sale_discount_total/models/res_company.py new file mode 100644 index 000000000..a7c40c056 --- /dev/null +++ b/sale_discount_total/models/res_company.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 ResCompany(models.Model): + """This class inherits 'res.company' and adds so_double_validation, + so_double_validation_limit to add validation limits""" + _inherit = 'res.company' + + so_double_validation = fields.Selection([ + ('one_step', 'Confirm sale orders in one step'), + ('two_step', 'Get 2 levels of approvals to confirm a sale order') + ], string="Levels of Approvals", default='one_step', + help="Provide a double validation mechanism for sales discount.") + so_double_validation_limit = fields.Float( + string="Percentage of Discount that requires double validation'", + help="Minimum discount percentage for which a double validation is " + "required.") diff --git a/sale_discount_total/models/res_config_settings.py b/sale_discount_total/models/res_config_settings.py new file mode 100644 index 000000000..f334bea0d --- /dev/null +++ b/sale_discount_total/models/res_config_settings.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 ResConfigSettings(models.TransientModel): + """This class inherits 'res.config.settings' model and adds fields + to the settings""" + _inherit = 'res.config.settings' + + so_order_approval = fields.Boolean( + string="Sale Discount Approval", + default=lambda self: self.env.user.company_id.so_double_validation == + 'two_step', help="Activate/disable " + "sale order approval.") + so_double_validation = fields.Selection( + related='company_id.so_double_validation', + string="Levels of Approvals *", readonly=False, + help="Provide a double validation mechanism for sales discount.") + so_double_validation_limit = fields.Float( + string="Discount limit requires approval in %", + related='company_id.so_double_validation_limit', readonly=False, + help="Minimum discount percentage for which a double validation is " + "required." + ) + + def set_values(self): + """Function to set values""" + super(ResConfigSettings, self).set_values() + self.so_double_validation = 'two_step' if self.so_order_approval \ + else 'one_step' diff --git a/sale_discount_total/models/sale_order.py b/sale_discount_total/models/sale_order.py new file mode 100644 index 000000000..aab14959f --- /dev/null +++ b/sale_discount_total/models/sale_order.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 SaleOrder(models.Model): + """Inherit 'sale.order' model and add fields needed""" + _inherit = "sale.order" + + @api.depends('order_line.price_total') + def _amount_all(self): + """Compute the total amounts of the SO.""" + for order in self: + amount_untaxed = amount_tax = amount_discount = 0.0 + for line in order.order_line: + amount_untaxed += line.price_subtotal + amount_tax += line.price_tax + amount_discount += ( + line.product_uom_qty * line.price_unit * line.discount) / 100 + order.update({ + 'amount_untaxed': amount_untaxed, + 'amount_tax': amount_tax, + 'amount_discount': amount_discount, + 'amount_total': amount_untaxed + amount_tax, + }) + + state = fields.Selection(selection_add=[ + ('waiting', 'Waiting Approval'), + ], string='Status', readonly=True, copy=False, index=True, + default='draft', help="Status of quotation.") + discount_type = fields.Selection( + [('percent', 'Percentage'), ('amount', 'Amount')], + string='Discount type', + default='percent', help="Type of discount.") + discount_rate = fields.Float('Discount Rate', digits=(16, 2), + help="Give the discount rate.") + amount_discount = fields.Monetary(string='Discount', store=True, + compute='_amount_all', readonly=True, + help="Give the amount to be discounted.") + amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, + readonly=True, compute='_amount_all', + help="Untaxed amount displayed.") + amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, + compute='_amount_all', + help="Taxes of product.") + amount_total = fields.Monetary(string='Total', store=True, readonly=True, + compute='_amount_all', + help="Total amount provided.") + + def action_confirm(self): + """This function super action_confirm method""" + discount = 0.0 + no_line = 0.0 + if self.company_id.so_double_validation == 'two_step': + for line in self.order_line: + no_line += 1 + discount += line.discount + discount = (discount / no_line) + if (self.company_id.so_double_validation_limit and discount > + self.company_id.so_double_validation_limit): + self.state = 'waiting' + return True + super(SaleOrder, self).action_confirm() + + def action_approve(self): + """This super the class and calls the action_confirm method on clicking + approve button""" + super(SaleOrder, self).action_confirm() + return + + def _can_be_confirmed(self): + """This function _can_be_confirmed adds waiting state """ + self.ensure_one() + return self.state in {'draft', 'sent', 'waiting'} + + @api.onchange('discount_type', 'discount_rate', 'order_line') + def supply_rate(self): + """This function calculates supply rates based on change of + discount_type, discount_rate and invoice_line_ids""" + for order in self: + if order.discount_type == 'percent': + for line in order.order_line: + line.discount = order.discount_rate + else: + total = 0.0 + for line in order.order_line: + total += round((line.product_uom_qty * line.price_unit)) + if order.discount_rate != 0: + discount = ( + order.discount_rate / total) * 100 if total > 0 else 0 + else: + discount = order.discount_rate + for line in order.order_line: + line.discount = discount + new_sub_price = (line.price_unit * (discount / 100)) + line.total_discount = line.price_unit - new_sub_price + + def _prepare_invoice(self, ): + """Super sale order class and update with fields""" + invoice_vals = super(SaleOrder, self)._prepare_invoice() + invoice_vals.update({ + 'discount_type': self.discount_type, + 'discount_rate': self.discount_rate, + 'amount_discount': self.amount_discount, + }) + return invoice_vals + + def button_dummy(self): + """The button_dummy method is intended to perform some action related + to the supply rate and always return True""" + self.supply_rate() + return True diff --git a/sale_discount_total/models/sale_order_line.py b/sale_discount_total/models/sale_order_line.py new file mode 100644 index 000000000..bcd8dfb0c --- /dev/null +++ b/sale_discount_total/models/sale_order_line.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 SaleOrderLine(models.Model): + """This class inherits "sale.order.line" and adds fields discount, + total_discount """ + _inherit = "sale.order.line" + + discount = fields.Float(string='Discount (%)', digits=(16, 20), default=0.0, + help="Discount needed.") + total_discount = fields.Float(string="Total Discount", default=0.0, + store=True, help="Total discount can be" + "specified here.") diff --git a/sale_discount_total/reports/__init__.py b/sale_discount_total/reports/__init__.py new file mode 100644 index 000000000..a4ef010bb --- /dev/null +++ b/sale_discount_total/reports/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 account_invoice_report +from . import sale_report diff --git a/sale_discount_total/reports/account_invoice_report.py b/sale_discount_total/reports/account_invoice_report.py new file mode 100644 index 000000000..ead4acf98 --- /dev/null +++ b/sale_discount_total/reports/account_invoice_report.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 AccountInvoiceReport(models.Model): + """This class inherits the model 'account.invoice.report'""" + _inherit = 'account.invoice.report' + + discount = fields.Float('Discount', readonly=True, + help="Specify the discount.") + + def _select(self): + """This allows the report to include the discount information in its + SQL query when fetching data from the database. """ + res = super(AccountInvoiceReport, self)._select() + select_str = res + """, line.discount AS discount """ + return select_str diff --git a/sale_discount_total/reports/sale_report.py b/sale_discount_total/reports/sale_report.py new file mode 100644 index 000000000..07b1f4158 --- /dev/null +++ b/sale_discount_total/reports/sale_report.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies(). +# Author: Jumana Haseen(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 DiscountSaleReport(models.Model): + """This class inherits 'sale.report' and adds field discount""" + _inherit = 'sale.report' + + discount = fields.Float('Discount', readonly=True, + help="Specify the discount amount.") + + def _select(self): + """It extends the behavior of a method in the class by adding a + new column, discount, to the SQL query. This new column represents + the total discount for sales transactions, calculated based on + various factors and values related to the sale. """ + res = super(DiscountSaleReport, self)._select() + select_str = res + """,sum(l.product_uom_qty / u.factor * u2.factor * cr.rate * l.price_unit * l.discount / 100.0) + as discount""" + return select_str diff --git a/sale_discount_total/static/description/assets/icons/capture (1).png b/sale_discount_total/static/description/assets/icons/capture (1).png new file mode 100644 index 000000000..8824deafc Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/capture (1).png differ diff --git a/sale_discount_total/static/description/assets/icons/check.png b/sale_discount_total/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/check.png differ diff --git a/sale_discount_total/static/description/assets/icons/chevron.png b/sale_discount_total/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/chevron.png differ diff --git a/sale_discount_total/static/description/assets/icons/cogs.png b/sale_discount_total/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/cogs.png differ diff --git a/sale_discount_total/static/description/assets/icons/consultation.png b/sale_discount_total/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/consultation.png differ diff --git a/sale_discount_total/static/description/assets/icons/ecom-black.png b/sale_discount_total/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/ecom-black.png differ diff --git a/sale_discount_total/static/description/assets/icons/education-black.png b/sale_discount_total/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/education-black.png differ diff --git a/sale_discount_total/static/description/assets/icons/hotel-black.png b/sale_discount_total/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/hotel-black.png differ diff --git a/sale_discount_total/static/description/assets/icons/img.png b/sale_discount_total/static/description/assets/icons/img.png new file mode 100644 index 000000000..70197f477 Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/img.png differ diff --git a/sale_discount_total/static/description/assets/icons/license.png b/sale_discount_total/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/license.png differ diff --git a/sale_discount_total/static/description/assets/icons/lifebuoy.png b/sale_discount_total/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/lifebuoy.png differ diff --git a/sale_discount_total/static/description/assets/icons/manufacturing-black.png b/sale_discount_total/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/manufacturing-black.png differ diff --git a/sale_discount_total/static/description/assets/icons/photo-capture.png b/sale_discount_total/static/description/assets/icons/photo-capture.png new file mode 100644 index 000000000..06c111758 Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/photo-capture.png differ diff --git a/sale_discount_total/static/description/assets/icons/pos-black.png b/sale_discount_total/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/pos-black.png differ diff --git a/sale_discount_total/static/description/assets/icons/puzzle.png b/sale_discount_total/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/puzzle.png differ diff --git a/sale_discount_total/static/description/assets/icons/restaurant-black.png b/sale_discount_total/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/restaurant-black.png differ diff --git a/sale_discount_total/static/description/assets/icons/service-black.png b/sale_discount_total/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/service-black.png differ diff --git a/sale_discount_total/static/description/assets/icons/trading-black.png b/sale_discount_total/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/trading-black.png differ diff --git a/sale_discount_total/static/description/assets/icons/training.png b/sale_discount_total/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/training.png differ diff --git a/sale_discount_total/static/description/assets/icons/update.png b/sale_discount_total/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/update.png differ diff --git a/sale_discount_total/static/description/assets/icons/user.png b/sale_discount_total/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/user.png differ diff --git a/sale_discount_total/static/description/assets/icons/wrench.png b/sale_discount_total/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/sale_discount_total/static/description/assets/icons/wrench.png differ diff --git a/sale_discount_total/static/description/assets/misc/Cybrosys R.png b/sale_discount_total/static/description/assets/misc/Cybrosys R.png new file mode 100644 index 000000000..da4058087 Binary files /dev/null and b/sale_discount_total/static/description/assets/misc/Cybrosys R.png differ diff --git a/sale_discount_total/static/description/assets/misc/email.svg b/sale_discount_total/static/description/assets/misc/email.svg new file mode 100644 index 000000000..15291cdc3 --- /dev/null +++ b/sale_discount_total/static/description/assets/misc/email.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sale_discount_total/static/description/assets/misc/phone.svg b/sale_discount_total/static/description/assets/misc/phone.svg new file mode 100644 index 000000000..b7bd7f251 --- /dev/null +++ b/sale_discount_total/static/description/assets/misc/phone.svg @@ -0,0 +1,3 @@ + + + diff --git a/sale_discount_total/static/description/assets/misc/star (1) 2.svg b/sale_discount_total/static/description/assets/misc/star (1) 2.svg new file mode 100644 index 000000000..5ae9f507a --- /dev/null +++ b/sale_discount_total/static/description/assets/misc/star (1) 2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/sale_discount_total/static/description/assets/misc/support (1) 1.svg b/sale_discount_total/static/description/assets/misc/support (1) 1.svg new file mode 100644 index 000000000..7d37a8f30 --- /dev/null +++ b/sale_discount_total/static/description/assets/misc/support (1) 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/sale_discount_total/static/description/assets/misc/support-email.svg b/sale_discount_total/static/description/assets/misc/support-email.svg new file mode 100644 index 000000000..eb70370d6 --- /dev/null +++ b/sale_discount_total/static/description/assets/misc/support-email.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/sale_discount_total/static/description/assets/misc/tick-mark.svg b/sale_discount_total/static/description/assets/misc/tick-mark.svg new file mode 100644 index 000000000..2dbb40187 --- /dev/null +++ b/sale_discount_total/static/description/assets/misc/tick-mark.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/sale_discount_total/static/description/assets/misc/whatsapp 1.svg b/sale_discount_total/static/description/assets/misc/whatsapp 1.svg new file mode 100644 index 000000000..0bfaf8fc6 --- /dev/null +++ b/sale_discount_total/static/description/assets/misc/whatsapp 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/sale_discount_total/static/description/assets/misc/whatsapp.svg b/sale_discount_total/static/description/assets/misc/whatsapp.svg new file mode 100644 index 000000000..b618aea1d --- /dev/null +++ b/sale_discount_total/static/description/assets/misc/whatsapp.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sale_discount_total/static/description/assets/modules/m1.png b/sale_discount_total/static/description/assets/modules/m1.png new file mode 100644 index 000000000..acb4c76c6 Binary files /dev/null and b/sale_discount_total/static/description/assets/modules/m1.png differ diff --git a/sale_discount_total/static/description/assets/modules/m2.png b/sale_discount_total/static/description/assets/modules/m2.png new file mode 100644 index 000000000..3ef91f771 Binary files /dev/null and b/sale_discount_total/static/description/assets/modules/m2.png differ diff --git a/sale_discount_total/static/description/assets/modules/m3.png b/sale_discount_total/static/description/assets/modules/m3.png new file mode 100644 index 000000000..72febf6ae Binary files /dev/null and b/sale_discount_total/static/description/assets/modules/m3.png differ diff --git a/sale_discount_total/static/description/assets/modules/m4.png b/sale_discount_total/static/description/assets/modules/m4.png new file mode 100644 index 000000000..f7d7f9241 Binary files /dev/null and b/sale_discount_total/static/description/assets/modules/m4.png differ diff --git a/sale_discount_total/static/description/assets/modules/m5.png b/sale_discount_total/static/description/assets/modules/m5.png new file mode 100644 index 000000000..1d3324e88 Binary files /dev/null and b/sale_discount_total/static/description/assets/modules/m5.png differ diff --git a/sale_discount_total/static/description/assets/modules/m6.png b/sale_discount_total/static/description/assets/modules/m6.png new file mode 100644 index 000000000..80938c15a Binary files /dev/null and b/sale_discount_total/static/description/assets/modules/m6.png differ diff --git a/sale_discount_total/static/description/assets/screenshots/1.png b/sale_discount_total/static/description/assets/screenshots/1.png new file mode 100644 index 000000000..b1ae01e1a Binary files /dev/null and b/sale_discount_total/static/description/assets/screenshots/1.png differ diff --git a/sale_discount_total/static/description/assets/screenshots/2.png b/sale_discount_total/static/description/assets/screenshots/2.png new file mode 100644 index 000000000..fbee35e4f Binary files /dev/null and b/sale_discount_total/static/description/assets/screenshots/2.png differ diff --git a/sale_discount_total/static/description/assets/screenshots/3.png b/sale_discount_total/static/description/assets/screenshots/3.png new file mode 100644 index 000000000..9a8cf8f12 Binary files /dev/null and b/sale_discount_total/static/description/assets/screenshots/3.png differ diff --git a/sale_discount_total/static/description/assets/screenshots/4.png b/sale_discount_total/static/description/assets/screenshots/4.png new file mode 100644 index 000000000..730d81b7e Binary files /dev/null and b/sale_discount_total/static/description/assets/screenshots/4.png differ diff --git a/sale_discount_total/static/description/assets/screenshots/hero.gif b/sale_discount_total/static/description/assets/screenshots/hero.gif new file mode 100644 index 000000000..84fa5b285 Binary files /dev/null and b/sale_discount_total/static/description/assets/screenshots/hero.gif differ diff --git a/sale_discount_total/static/description/banner.png b/sale_discount_total/static/description/banner.png new file mode 100644 index 000000000..2cd293552 Binary files /dev/null and b/sale_discount_total/static/description/banner.png differ diff --git a/sale_discount_total/static/description/icon.png b/sale_discount_total/static/description/icon.png new file mode 100644 index 000000000..ff26bdbee Binary files /dev/null and b/sale_discount_total/static/description/icon.png differ diff --git a/sale_discount_total/static/description/index.html b/sale_discount_total/static/description/index.html new file mode 100644 index 000000000..3ccecee67 --- /dev/null +++ b/sale_discount_total/static/description/index.html @@ -0,0 +1,715 @@ + + + + + + + Odoo App 3 Index + + + + + + + + +
+
+
+
+
+ +
+
+
+ Community +
+
+ Enterprise +
+
+
+
+
+
+

+ Sale Discount on Total Amount

+

+ This module allows you to mention discount on total of sale + order and + customer invoice as percentage or as amount. +

+
+ +
+
+
+
+
+

+ Key Highlights +

+
+
+
+
+
+ +
+
+

+ Global Discount In Sale.

+
+
+
+
+
+
+ +
+
+

+ Select Percentage or amount from Discount type + and give discount percentage or amount as + Discount rate.

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

+ Enable Sale Discount Approval and + Discounts

+

+ The module also allows you to set a limit + for total discount in percentage. + Exceeding this limit will require + approval.

+
+
+
+
+
+
+ +
+
+

+ Sale Order +

+

+ Select Percentage or amount from Discount + type and give discount percentage or + amount as Discount rate.

+
+
+
+
+
+
+ +
+
+

+ Customer Invoice

+

+ Select Percentage or amount from Discount + type and give discount percentage or + amount as Discount rate.

+
+
+
+
+
+
+ +
+
+

+ Manager level users can approve sale + orders in 'Waiting Approval' stage.

+
+
+
+
+
+
+
    +
  • + Sale Order and + Customer Invoice contains limit for total + discount in percentage. +
  • +
  • + Manager level + users can approve sale orders in + 'Waiting Approval' stage. +
  • +
  • + Sale Discount + on Total Amount +
      +
    • This module allows you to mention + discount on total of sale order and + customer invoice as percentage or as + amount. +
    • +
    +
  • +
+
+
+
+
+
+
Version + 17.0.1.0.0|Released on:08th March 2024 +
+

+ Initial Commit for Sale Discount + on Total Amount +

+
+
+
+
+
+
+
+

+ Related Products

+
+
+ +
+
+

+ Our Services

+ +
+
+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Customization

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Implementation

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Support

+
+
+
+
+
+
+ service-icon +
+
+

Hire + Odoo Developer

+
+
+
+
+ +
+
+ service-icon +
+
+

Odoo + Integration

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Migration

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Consultancy

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Implementation

+
+
+
+
+
+
+ service-icon +
+
+

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

+
+
+
+
+
+
+

+ Support

+
+
+
+
+
+
+
+ +
+ Need + Help? +

Got + questions or need help? Get in touch.

+
odoo@cybrosys.com +
+
+
+
+
+
+
+
+ +
+ WhatsApp +

Say hi to + us on WhatsApp!

+
+91 + 99456767686 +
+
+
+
+
+
+
+
+
+ + + + + + diff --git a/sale_discount_total/views/account_move_templates.xml b/sale_discount_total/views/account_move_templates.xml new file mode 100644 index 000000000..1e57d99b6 --- /dev/null +++ b/sale_discount_total/views/account_move_templates.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/sale_discount_total/views/account_move_views.xml b/sale_discount_total/views/account_move_views.xml new file mode 100644 index 000000000..0d3f55603 --- /dev/null +++ b/sale_discount_total/views/account_move_views.xml @@ -0,0 +1,24 @@ + + + + + account.move.view.form.inherit.sale.discount.total + + account.move + + + + [16, 2] + + + + + + + + + + + + + diff --git a/sale_discount_total/views/res_config_settings_views.xml b/sale_discount_total/views/res_config_settings_views.xml new file mode 100644 index 000000000..1cd5ac15d --- /dev/null +++ b/sale_discount_total/views/res_config_settings_views.xml @@ -0,0 +1,34 @@ + + + + + + res.config.settings.view.form.inherit.sale.discount.total + + res.config.settings + + + + + + +
+
+
+
+
+
+
+
+
diff --git a/sale_discount_total/views/sale_order_templates.xml b/sale_discount_total/views/sale_order_templates.xml new file mode 100644 index 000000000..ad7380647 --- /dev/null +++ b/sale_discount_total/views/sale_order_templates.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/sale_discount_total/views/sale_order_views.xml b/sale_discount_total/views/sale_order_views.xml new file mode 100644 index 000000000..e282074d6 --- /dev/null +++ b/sale_discount_total/views/sale_order_views.xml @@ -0,0 +1,68 @@ + + + + + sale.order.view.form.inherit.sale.discount.total + + sale.order + + + +