diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/sale/models/sales_team.py | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/sale/models/sales_team.py')
| -rw-r--r-- | addons/sale/models/sales_team.py | 137 |
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))}) |
