summaryrefslogtreecommitdiff
path: root/addons/sale/models/sales_team.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/sale/models/sales_team.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/sale/models/sales_team.py')
-rw-r--r--addons/sale/models/sales_team.py137
1 files changed, 137 insertions, 0 deletions
diff --git a/addons/sale/models/sales_team.py b/addons/sale/models/sales_team.py
new file mode 100644
index 00000000..b7382868
--- /dev/null
+++ b/addons/sale/models/sales_team.py
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from datetime import date
+
+from odoo import api, fields, models, _
+
+
+class CrmTeam(models.Model):
+ _inherit = 'crm.team'
+
+ use_quotations = fields.Boolean(string='Quotations', help="Check this box if you send quotations to your customers rather than confirming orders straight away.")
+ invoiced = fields.Float(
+ compute='_compute_invoiced',
+ string='Invoiced This Month', readonly=True,
+ help="Invoice revenue for the current month. This is the amount the sales "
+ "channel has invoiced this month. It is used to compute the progression ratio "
+ "of the current and target revenue on the kanban view.")
+ invoiced_target = fields.Float(
+ string='Invoicing Target',
+ help="Revenue target for the current month (untaxed total of confirmed invoices).")
+ quotations_count = fields.Integer(
+ compute='_compute_quotations_to_invoice',
+ string='Number of quotations to invoice', readonly=True)
+ quotations_amount = fields.Float(
+ compute='_compute_quotations_to_invoice',
+ string='Amount of quotations to invoice', readonly=True)
+ sales_to_invoice_count = fields.Integer(
+ compute='_compute_sales_to_invoice',
+ string='Number of sales to invoice', readonly=True)
+
+
+ def _compute_quotations_to_invoice(self):
+ query = self.env['sale.order']._where_calc([
+ ('team_id', 'in', self.ids),
+ ('state', 'in', ['draft', 'sent']),
+ ])
+ self.env['sale.order']._apply_ir_rules(query, 'read')
+ _, where_clause, where_clause_args = query.get_sql()
+ select_query = """
+ SELECT team_id, count(*), sum(amount_total /
+ CASE COALESCE(currency_rate, 0)
+ WHEN 0 THEN 1.0
+ ELSE currency_rate
+ END
+ ) as amount_total
+ FROM sale_order
+ WHERE %s
+ GROUP BY team_id
+ """ % where_clause
+ self.env.cr.execute(select_query, where_clause_args)
+ quotation_data = self.env.cr.dictfetchall()
+ teams = self.browse()
+ for datum in quotation_data:
+ team = self.browse(datum['team_id'])
+ team.quotations_amount = datum['amount_total']
+ team.quotations_count = datum['count']
+ teams |= team
+ remaining = (self - teams)
+ remaining.quotations_amount = 0
+ remaining.quotations_count = 0
+
+ def _compute_sales_to_invoice(self):
+ sale_order_data = self.env['sale.order'].read_group([
+ ('team_id', 'in', self.ids),
+ ('invoice_status','=','to invoice'),
+ ], ['team_id'], ['team_id'])
+ data_map = {datum['team_id'][0]: datum['team_id_count'] for datum in sale_order_data}
+ for team in self:
+ team.sales_to_invoice_count = data_map.get(team.id,0.0)
+
+ def _compute_invoiced(self):
+ if not self:
+ return
+
+ query = '''
+ SELECT
+ move.team_id AS team_id,
+ SUM(-line.balance) AS amount_untaxed_signed
+ FROM account_move move
+ JOIN account_move_line line ON line.move_id = move.id
+ JOIN account_account account ON account.id = line.account_id
+ WHERE move.move_type IN ('out_invoice', 'out_refund', 'in_invoice', 'in_refund')
+ AND move.payment_state IN ('in_payment', 'paid', 'reversed')
+ AND move.state = 'posted'
+ AND move.team_id IN %s
+ AND move.date BETWEEN %s AND %s
+ AND line.tax_line_id IS NULL
+ AND line.display_type IS NULL
+ AND account.internal_type NOT IN ('receivable', 'payable')
+ GROUP BY move.team_id
+ '''
+ today = fields.Date.today()
+ params = [tuple(self.ids), fields.Date.to_string(today.replace(day=1)), fields.Date.to_string(today)]
+ self._cr.execute(query, params)
+
+ data_map = dict((v[0], v[1]) for v in self._cr.fetchall())
+ for team in self:
+ team.invoiced = data_map.get(team.id, 0.0)
+
+ def _graph_get_model(self):
+ if self._context.get('in_sales_app'):
+ return 'sale.report'
+ return super(CrmTeam,self)._graph_get_model()
+
+ def _graph_date_column(self):
+ if self._context.get('in_sales_app'):
+ return 'date'
+ return super(CrmTeam,self)._graph_date_column()
+
+ def _graph_y_query(self):
+ if self._context.get('in_sales_app'):
+ return 'SUM(price_subtotal)'
+ return super(CrmTeam,self)._graph_y_query()
+
+ def _extra_sql_conditions(self):
+ if self._context.get('in_sales_app'):
+ return "AND state in ('sale', 'done', 'pos_done')"
+ return super(CrmTeam,self)._extra_sql_conditions()
+
+ def _graph_title_and_key(self):
+ if self._context.get('in_sales_app'):
+ return ['', _('Sales: Untaxed Total')] # no more title
+ return super(CrmTeam, self)._graph_title_and_key()
+
+ def _compute_dashboard_button_name(self):
+ super(CrmTeam,self)._compute_dashboard_button_name()
+ if self._context.get('in_sales_app'):
+ self.update({'dashboard_button_name': _("Sales Analysis")})
+
+ def action_primary_channel_button(self):
+ if self._context.get('in_sales_app'):
+ return self.env["ir.actions.actions"]._for_xml_id("sale.action_order_report_so_salesteam")
+ return super(CrmTeam, self).action_primary_channel_button()
+
+ def update_invoiced_target(self, value):
+ return self.write({'invoiced_target': round(float(value or 0))})