1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/sale_subscription/report/sale_subscription_report.py
2024-12-10 09:04:09 +07:00

128 lines
5.3 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
from odoo.addons.sale_subscription.models.sale_order import SUBSCRIPTION_STATES
class SaleSubscriptionReport(models.Model):
_inherit = "sale.report"
_name = "sale.subscription.report"
_description = "Subscription Analysis"
_auto = False
client_order_ref = fields.Char(string="Customer Reference", readonly=False)
first_contract_date = fields.Date(string='First contract date', readonly=True)
end_date = fields.Date('End Date', readonly=True)
recurring_monthly = fields.Monetary('Monthly Recurring', readonly=True)
recurring_yearly = fields.Monetary('Yearly Recurring', readonly=True)
recurring_total = fields.Monetary('Recurring Revenue', readonly=True)
is_subscription = fields.Boolean(readonly=True)
template_id = fields.Many2one('sale.order.template', 'Subscription Template', readonly=True)
country_id = fields.Many2one('res.country', 'Country', readonly=True)
commercial_partner_id = fields.Many2one('res.partner', 'Customer Company', readonly=True)
industry_id = fields.Many2one('res.partner.industry', 'Industry', readonly=True)
close_reason_id = fields.Many2one('sale.order.close.reason', 'Close Reason', readonly=True)
margin = fields.Float() # not used but we want to avoid creating a bridge module for nothing
subscription_state = fields.Selection(SUBSCRIPTION_STATES, readonly=True)
health = fields.Selection([
('normal', 'Neutral'),
('done', 'Good'),
('bad', 'Bad')], string="Health", readonly=True)
next_invoice_date = fields.Date('Next Invoice Date', readonly=True)
plan_id = fields.Many2one('sale.subscription.plan', 'Plan', readonly=True)
origin_order_id = fields.Many2one('sale.order', string='First contract', readonly=True)
def _select_additional_fields(self):
res = super()._select_additional_fields()
res['is_subscription'] = "s.is_subscription"
res['subscription_state'] = "s.subscription_state"
res['end_date'] = "s.end_date"
res['first_contract_date'] = "s.first_contract_date"
res['health'] = "s.health"
res['template_id'] = "s.sale_order_template_id"
res['close_reason_id'] = "s.close_reason_id"
res['next_invoice_date'] = "s.next_invoice_date"
res['plan_id'] = "s.plan_id"
res['origin_order_id'] = "s.origin_order_id"
res['client_order_ref'] = "s.client_order_ref"
res['margin'] = 0
res['recurring_monthly'] = f"""sum(l.price_subtotal)
/ CASE
WHEN ssp.billing_period_unit = 'week' THEN 7.0 / 30.437
WHEN ssp.billing_period_unit = 'month' THEN 1
WHEN ssp.billing_period_unit = 'year' THEN 12
ELSE 1
END
/ ssp.billing_period_value
/ {self._case_value_or_one('s.currency_rate') }
* {self._case_value_or_one('currency_table.rate') }
"""
res['recurring_yearly'] = f"""sum(l.price_subtotal)
/ CASE
WHEN ssp.billing_period_unit = 'week' THEN 7.0 / 30.437
WHEN ssp.billing_period_unit = 'month' THEN 1
WHEN ssp.billing_period_unit = 'year' THEN 12
ELSE 1
END
/ ssp.billing_period_value
* 12
/ {self._case_value_or_one('s.currency_rate') }
* {self._case_value_or_one('currency_table.rate') }
"""
res['recurring_total'] = f"""
s.recurring_total
/ {self._case_value_or_one('s.currency_rate') }
* {self._case_value_or_one('currency_table.rate') }
"""
return res
def _from_sale(self):
frm = super()._from_sale()
return f"""
{frm}
LEFT JOIN sale_subscription_plan ssp ON ssp.id = s.plan_id
"""
def _where_sale(self):
where = super()._where_sale()
return f"""
{where}
AND s.subscription_state IS NOT NULL
"""
def _group_by_sale(self):
group_by_str = super()._group_by_sale()
group_by_str = f"""{group_by_str},
s.subscription_state,
s.end_date,
s.health,
s.subscription_state,
s.sale_order_template_id,
partner.industry_id,
s.close_reason_id,
s.state,
s.next_invoice_date,
s.plan_id,
s.origin_order_id,
s.first_contract_date,
s.client_order_ref,
ssp.billing_period_unit,
ssp.billing_period_value
"""
return group_by_str
def action_open_subscription_order(self):
self.ensure_one()
if self.order_reference._name == 'sale.order':
action = self.order_reference._get_associated_so_action()
action['views'] = [(self.env.ref('sale_subscription.sale_subscription_primary_form_view').id, 'form')]
action['res_id'] = self.order_reference.id
return action
return {
'res_model': self._name,
'type': 'ir.actions.act_window',
'views': [[False, "form"]],
'res_id': self.id,
}