144 lines
6.5 KiB
Python
Executable File
144 lines
6.5 KiB
Python
Executable File
from odoo import models, api
|
|
from datetime import datetime, timedelta
|
|
|
|
class SpencoReport(models.AbstractModel):
|
|
_name = 'report.sos_sales.report_spenco'
|
|
_description = 'Spenco Report'
|
|
|
|
@api.model
|
|
def _get_report_values(self, docids, data=None):
|
|
sales_person_id = data.get('sales_person_id')
|
|
from_date = data.get('from_date')
|
|
to_date = data.get('to_date')
|
|
customer_id = data.get('customer_id')
|
|
# Build domain for querying records
|
|
domain = [('status', '!=', 'close')]
|
|
domain.append(('spenco_status', 'not in', ('Suspects', '', False, None)))
|
|
if customer_id:
|
|
domain.append(('customer_name', '=', customer_id))
|
|
if sales_person_id:
|
|
domain.append(('sales_person', '=', sales_person_id))
|
|
if from_date and isinstance(from_date, str):
|
|
from_date = datetime.strptime(from_date, "%Y-%m-%d").date()
|
|
if to_date and isinstance(to_date, str):
|
|
to_date = datetime.strptime(to_date, "%Y-%m-%d").date()
|
|
|
|
if from_date and to_date:
|
|
next_day = to_date + timedelta(days=1)
|
|
matching_lines = self.env['sos_case_diary_line'].search([
|
|
('status_changed_on', '>=', from_date),
|
|
('status_changed_on', '<', next_day),
|
|
('current_state_value', '>', 0.0),
|
|
])
|
|
domain.append(('line_ids', 'in', matching_lines.ids))
|
|
|
|
elif from_date:
|
|
matching_lines = self.env['sos_case_diary_line'].search([
|
|
('status_changed_on', '>=', from_date),
|
|
('current_state_value', '>', 0.0),
|
|
])
|
|
domain.append(('line_ids', 'in', matching_lines.ids))
|
|
|
|
elif to_date:
|
|
next_day = to_date + timedelta(days=1)
|
|
matching_lines = self.env['sos_case_diary_line'].search([
|
|
('status_changed_on', '<', next_day),
|
|
('current_state_value', '>', 0.0),
|
|
])
|
|
domain.append(('line_ids', 'in', matching_lines.ids))
|
|
# Fetch records
|
|
records = self.env['sos_case_diary'].search(domain)
|
|
case_diary_data = []
|
|
totals = {
|
|
'Prospects': 0,
|
|
'Engaged': 0,
|
|
'Negotiation': 0,
|
|
'Commercial Order': 0,
|
|
'Expected Order Value': 0,
|
|
}
|
|
if not records:
|
|
return {
|
|
'doc_ids': docids,
|
|
'doc_model': 'sos_case_diary',
|
|
'docs': records,
|
|
'case_diary_data': [],
|
|
'from_date': from_date,
|
|
'to_date': to_date,
|
|
'totals': totals, # Include totals to avoid template errors
|
|
}
|
|
# Process records to build case_diary_data
|
|
for record in records:
|
|
if record.interested_in == "projects":
|
|
product_or_project = record.project_name
|
|
else:
|
|
product_or_project = record.products
|
|
latest_record = self.env['sos_case_diary_line'].search(
|
|
[('ref_id', '=', record.id)],
|
|
order="id desc",
|
|
limit=1
|
|
)
|
|
if not latest_record:
|
|
continue # Skip if no latest record found
|
|
|
|
current_state_value = round(latest_record.current_state_value, 2)
|
|
spenco_status = latest_record.spenco_status
|
|
|
|
if spenco_status == 'Prospects':
|
|
totals['Prospects'] += current_state_value
|
|
totals['Expected Order Value'] += round(current_state_value * 0.1, 2)
|
|
elif spenco_status == 'Engaged':
|
|
totals['Engaged'] += current_state_value
|
|
totals['Expected Order Value'] += round(current_state_value * 0.3, 2)
|
|
elif spenco_status == 'Negotiation':
|
|
totals['Negotiation'] += current_state_value
|
|
totals['Expected Order Value'] += round(current_state_value * 0.5, 2)
|
|
elif spenco_status == 'Commercial Order':
|
|
totals['Commercial Order'] += current_state_value
|
|
totals['Expected Order Value'] += round(current_state_value, 2)
|
|
|
|
case_diary_data.append({
|
|
'record_id': record.id,
|
|
'quote_no':record.quote_no,
|
|
'customer_name': record.customer_name.customer_name,
|
|
'end_customer_name': record.end_customer_name,
|
|
'customer_city': record.customer_city,
|
|
'lead_generated_by': record.lead_generated_by,
|
|
'products': product_or_project,
|
|
'quantity': record.quantity,
|
|
'sales_person': record.sales_person.name,
|
|
'account_start_date': record.account_start_date,
|
|
'status_changed_on': latest_record.status_changed_on,
|
|
'spenco_status': latest_record.spenco_status,
|
|
'current_state_value': latest_record.current_state_value,
|
|
'status_values': {
|
|
'Prospects': latest_record.current_state_value if latest_record.spenco_status == 'Prospects' else '',
|
|
'Engaged': latest_record.current_state_value if latest_record.spenco_status == 'Engaged' else '',
|
|
'Negotiation': latest_record.current_state_value if latest_record.spenco_status == 'Negotiation' else '',
|
|
'Commercial Order': latest_record.current_state_value if latest_record.spenco_status == 'Commercial Order' else '',
|
|
},
|
|
'expected_order_value': round(
|
|
latest_record.current_state_value * (
|
|
0.1 if latest_record.spenco_status == 'Prospects' else
|
|
0.3 if latest_record.spenco_status == 'Engaged' else
|
|
0.5 if latest_record.spenco_status == 'Negotiation' else
|
|
1.0 if latest_record.spenco_status == 'Commercial Order' else 0
|
|
), 2
|
|
),
|
|
'totals': totals,
|
|
'from_date': from_date,
|
|
'to_date': to_date
|
|
})
|
|
|
|
# Sort by sales_person
|
|
case_diary_data = sorted(case_diary_data, key=lambda x: x['sales_person'])
|
|
|
|
# Return values for the report template
|
|
return {
|
|
'doc_ids': docids,
|
|
'doc_model': 'sos_case_diary',
|
|
'docs': records,
|
|
'case_diary_data': case_diary_data,
|
|
'from_date': from_date,
|
|
'to_date': to_date,
|
|
'sales_person':self.env['res.users'].browse(sales_person_id)
|
|
} |