diff --git a/subscription_package/__manifest__.py b/subscription_package/__manifest__.py index 9b632a5c2..532deb65f 100644 --- a/subscription_package/__manifest__.py +++ b/subscription_package/__manifest__.py @@ -21,7 +21,8 @@ ############################################################################# { 'name': 'Subscription Management', - 'version': '17.0.1.0.1', + 'version': '17.0.1.1.2', + 'category': 'Sales', 'summary': 'Subscription Package Management Module For Odoo17 Community', 'description': 'Subscription Package Management Module specifically ' 'designed for Odoo 17 Community edition. ' @@ -30,7 +31,6 @@ 'providing users with advanced features and ' 'functionalities for efficiently handling subscription ' 'packages in the community version of Odoo 17.', - 'category': 'Sales', 'author': 'Cybrosys Techno solutions', 'company': 'Cybrosys Techno Solutions', 'maintainer': 'Cybrosys Techno Solutions', @@ -39,14 +39,12 @@ 'data': [ 'security/subscription_package_groups.xml', 'security/ir.model.access.csv', - 'data/uom_demo_data.xml', 'data/subscription_package_stop_data.xml', 'data/subscription_stage_data.xml', 'data/mail_subscription_renew_data.xml', 'data/ir_cron_data.xml', 'data/ir_sequence.xml', - 'views/subscription_package_views.xml', 'views/product_template_views.xml', 'views/subscription_package_plan_views.xml', @@ -57,14 +55,12 @@ 'views/recurrence_period_views.xml', 'views/sale_order_views.xml', 'views/product_product_views.xml', - 'report/subscription_report_view.xml', - 'wizard/subscription_close_views.xml', ], 'images': ['static/description/banner.jpg'], 'license': 'AGPL-3', 'installable': True, - 'application': True, 'auto_install': False, + 'application': True, } diff --git a/subscription_package/doc/RELEASE_NOTES.md b/subscription_package/doc/RELEASE_NOTES.md index 2abd8d71d..c9889f79e 100644 --- a/subscription_package/doc/RELEASE_NOTES.md +++ b/subscription_package/doc/RELEASE_NOTES.md @@ -8,3 +8,8 @@ #### Version 17.0.1.0.1 #### ADD - Bug Fix + +#### 13.06.2024 +#### Version 17.0.1.1.2 +#### Update +- Bug Fix, fixed issue in invoicing the subscription sale order multiple times, made the next_invoice_date field in the model subscription.package editable, updated context in xml files. diff --git a/subscription_package/models/__init__.py b/subscription_package/models/__init__.py index 9b1dc2474..ed43af8f3 100644 --- a/subscription_package/models/__init__.py +++ b/subscription_package/models/__init__.py @@ -29,3 +29,4 @@ from . import subscription_package_plan from . import subscription_package_product_line from . import subscription_package_stage from . import subscription_package_stop +from . import sale_order_line diff --git a/subscription_package/models/account_move.py b/subscription_package/models/account_move.py index 93ac1a366..9290cba8f 100644 --- a/subscription_package/models/account_move.py +++ b/subscription_package/models/account_move.py @@ -39,6 +39,7 @@ class AccountMove(models.Model): so_id = self.env['sale.order'].search( [('name', '=', rec.get('invoice_origin'))]) if so_id.is_subscription is True: + so_id.subscription_id.start_date = so_id.subscription_id.next_invoice_date new_vals_list = [{'is_subscription': True, 'subscription_id': so_id.subscription_id.id}] vals_list[0].update(new_vals_list[0]) diff --git a/subscription_package/models/sale_order_line.py b/subscription_package/models/sale_order_line.py new file mode 100644 index 000000000..4083e4078 --- /dev/null +++ b/subscription_package/models/sale_order_line.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: JANISH BABU () +# +# 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, models + + +class SaleOrderLine(models.Model): + _inherit = 'sale.order.line' + + @api.depends('qty_invoiced', 'qty_delivered', 'product_uom_qty', 'state') + def _compute_qty_to_invoice(self): + """Over-write the _compute_qty_to_invoice function + to look weather order is subscriptions""" + for line in self: + if (line.order_id.subscription_id and not + line.order_id.subscription_id.is_closed + and line.order_id.is_subscription): + if line.product_template_id.is_subscription: + line.qty_to_invoice = line.product_uom_qty + else: + if line.state == 'sale' and not line.display_type: + if line.product_id.invoice_policy == 'order': + line.qty_to_invoice = ( + line.product_uom_qty - line.qty_invoiced) + else: + line.qty_to_invoice = ( + line.qty_delivered - line.qty_invoiced) + else: + line.qty_to_invoice = 0 diff --git a/subscription_package/models/subscription_package.py b/subscription_package/models/subscription_package.py index 7d24fab7a..fb126e566 100644 --- a/subscription_package/models/subscription_package.py +++ b/subscription_package/models/subscription_package.py @@ -20,7 +20,7 @@ # ############################################################################# from dateutil.relativedelta import relativedelta -from odoo import api, fields, models, _, SUPERUSER_ID +from odoo import api, fields, models, SUPERUSER_ID, _ from odoo.exceptions import UserError @@ -49,7 +49,8 @@ class SubscriptionPackage(models.Model): store=True, required=True, help='Choose the name for the subscription package.') partner_id = fields.Many2one('res.partner', string='Customer', - help='Select the customer associated with this record.') + help='Select the customer associated with ' + 'this record.') partner_invoice_id = fields.Many2one('res.partner', help='Select the invoice address ' 'associated with this record.', @@ -70,7 +71,8 @@ class SubscriptionPackage(models.Model): ondelete='restrict', readonly=True) next_invoice_date = fields.Date(string='Next Invoice Date', store=True, help='Add next invoice date', - compute="_compute_next_invoice_date") + compute="_compute_next_invoice_date", + inverse="_inverse_next_invoice_date") company_id = fields.Many2one('res.company', string='Company', help='Select the company', default=lambda self: self.env.company, @@ -187,7 +189,7 @@ class SubscriptionPackage(models.Model): rec.current_stage = rec.env['subscription.package.stage'].search( [('id', '=', rec.stage_id.id)]).category - @api.constrains('start_date') + @api.depends('start_date') def _compute_next_invoice_date(self): """The compute function is the next invoice date for subscription packages based on the start date and renewal time.""" @@ -196,6 +198,12 @@ class SubscriptionPackage(models.Model): sub.next_invoice_date = sub.start_date + relativedelta( days=sub.plan_id.renewal_time) + def _inverse_next_invoice_date(self): + """Inverse function for next invoice date""" + for sub in self.env['subscription.package'].search([]): + if sub.start_date: + return + def button_invoice_count(self): """ It displays invoice based on subscription package """ return { @@ -251,6 +259,12 @@ class SubscriptionPackage(models.Model): raise UserError("Empty order lines !! Please add the " "subscription product.") else: + if rec.sale_order_id: + rec.sale_order_id.write({'subscription_id': rec.id, + 'is_subscription': True}) + for line in rec.sale_order_id.order_line.filtered( + lambda x: x.product_template_id.is_subscription == True): + line.qty_to_invoice = line.product_uom_qty rec.write( {'stage_id': stage_id, 'date_started': fields.Date.today(), @@ -362,12 +376,11 @@ class SubscriptionPackage(models.Model): def close_limit_cron(self): """ It Checks renew date, close date. It will send mail when renew - date and also generates invoices based on the plan. - It wil close the subscription automatically if renewal limit is exceeded """ + date and also generates invoices based on the plan. It wil close the + subscription automatically if renewal limit is exceeded""" pending_subscriptions = self.env['subscription.package'].search( [('stage_category', '=', 'progress')]) today_date = fields.Date.today() - # today_date = datetime.datetime.strptime('05102023', '%d%m%Y').date() pending_subscription = False for pending_subscription in pending_subscriptions: get_dates = self.find_renew_date( @@ -400,9 +413,9 @@ class SubscriptionPackage(models.Model): 'currency_id': pending_subscription.partner_invoice_id.currency_id.id, 'invoice_line_ids': this_products_line }) - - pending_subscription.write({'is_to_renew': False, - 'start_date': pending_subscription.next_invoice_date}) + pending_subscription.write({ + 'is_to_renew': False, + 'start_date': pending_subscription.next_invoice_date}) new_date = self.find_renew_date( pending_subscription.next_invoice_date, pending_subscription.date_started, diff --git a/subscription_package/models/subscription_package_product_line.py b/subscription_package/models/subscription_package_product_line.py index cf6e3210e..3f96f9a7e 100644 --- a/subscription_package/models/subscription_package_product_line.py +++ b/subscription_package/models/subscription_package_product_line.py @@ -55,7 +55,7 @@ class SubscriptionPackageProductLine(models.Model): unit_price = fields.Float(string='Unit Price', store=True, readonly=False, related='product_id.list_price', help='Add Product Unit Price') - discount = fields.Float(string="Discount (%)", helo='Add Discount') + discount = fields.Float(string="Discount (%)", help='Add Discount') tax_ids = fields.Many2many('account.tax', string="Taxes", ondelete='restrict', related='product_id.taxes_id', readonly=False, @@ -65,14 +65,15 @@ class SubscriptionPackageProductLine(models.Model): price_tax = fields.Monetary(store=True, readonly=True, string='Price Tax', help='Add Price Tax') currency_id = fields.Many2one('res.currency', string='Currency', - store=True,help='Add Subscription Currency', + store=True, help='Add Subscription Currency', related='subscription_id.currency_id') - total_amount = fields.Monetary(string='Subtotal', store=True,help='Add Total Amount', + total_amount = fields.Monetary(string='Subtotal', store=True, + help='Add Total Amount', compute='_compute_total_amount') sequence = fields.Integer('Sequence', help="Determine the display order", index=True) res_partner_id = fields.Many2one('res.partner', string='Partner', - store=True,help='Choose the Partner', + store=True, help='Choose the Partner', related='subscription_id.partner_id') @api.depends('product_qty', 'unit_price', 'discount', 'tax_ids', diff --git a/subscription_package/views/product_template_views.xml b/subscription_package/views/product_template_views.xml index 4e634f6c2..878a17695 100644 --- a/subscription_package/views/product_template_views.xml +++ b/subscription_package/views/product_template_views.xml @@ -46,7 +46,7 @@ { 'search_default_filter_is_subscription': True, 'search_default_filter_to_sell':1, - 'default_type':'service', + 'default_detailed_type':'service', 'default_is_subscription':True} diff --git a/subscription_package/views/subscription_package_views.xml b/subscription_package/views/subscription_package_views.xml index 0e2d134e3..fe6bb0200 100644 --- a/subscription_package/views/subscription_package_views.xml +++ b/subscription_package/views/subscription_package_views.xml @@ -147,7 +147,7 @@ - + diff --git a/subscription_package/wizard/subscription_close.py b/subscription_package/wizard/subscription_close.py index c1e2c6bd9..e704fbf60 100644 --- a/subscription_package/wizard/subscription_close.py +++ b/subscription_package/wizard/subscription_close.py @@ -52,3 +52,7 @@ class SubscriptionClose(models.TransientModel): ('category', '=', 'closed')]).id) values = {'stage_id': stage, 'is_to_renew': False} sub.write(values) + for lines in sub.sale_order_id.order_line.filtered( + lambda x: x.product_template_id.is_subscription == True): + lines.qty_invoiced = lines.product_uom_qty + lines.qty_to_invoice = 0