305 lines
16 KiB
Python
Executable File
305 lines
16 KiB
Python
Executable File
from odoo import models, fields, api
|
|
from datetime import date
|
|
from odoo.exceptions import ValidationError
|
|
from collections import defaultdict
|
|
|
|
|
|
class sos_sales_plan_target(models.Model):
|
|
_name = 'sos_sales_plan_target'
|
|
_description = 'Sosaley Sales Target'
|
|
_rec_name='financial_year'
|
|
|
|
|
|
financial_year = fields.Char(string="Financial Year", default=lambda self: self._get_financial_year())
|
|
line_ids = fields.One2many('sos_sales_plan_target_lines', 'ref_id', string="Sales Target Lines",copy=True)
|
|
sales_executive = fields.Many2one(
|
|
'res.users',
|
|
string='Sales Executive',
|
|
default=lambda self: self.env.user,
|
|
readonly=True
|
|
)
|
|
total_april_value = fields.Float(string="April Target", compute="_compute_monthly_totals", store=True)
|
|
total_may_value = fields.Float(string="May Target", compute="_compute_monthly_totals", store=True)
|
|
total_june_value = fields.Float(string="June Target", compute="_compute_monthly_totals", store=True)
|
|
total_july_value = fields.Float(string="July Target", compute="_compute_monthly_totals", store=True)
|
|
total_august_value = fields.Float(string="August Target", compute="_compute_monthly_totals", store=True)
|
|
total_september_value = fields.Float(string="September Target", compute="_compute_monthly_totals", store=True)
|
|
total_october_value = fields.Float(string="October Target", compute="_compute_monthly_totals", store=True)
|
|
total_november_value = fields.Float(string="November Target", compute="_compute_monthly_totals", store=True)
|
|
total_december_value = fields.Float(string="December Target", compute="_compute_monthly_totals", store=True)
|
|
total_january_value = fields.Float(string="January Target", compute="_compute_monthly_totals", store=True)
|
|
total_february_value = fields.Float(string="February Target", compute="_compute_monthly_totals", store=True)
|
|
total_march_value = fields.Float(string="March Target", compute="_compute_monthly_totals", store=True)
|
|
total_annual_value = fields.Float(string="Annual Target", compute="_compute_total_annual_value", store=True)
|
|
total_q1_value = fields.Float(string="Q1 Target", compute="_compute_q1_value", store=True)
|
|
total_q2_value = fields.Float(string="Q2 Target", compute="_compute_q2_value", store=True)
|
|
total_q3_value = fields.Float(string="Q3 Target", compute="_compute_q3_value", store=True)
|
|
total_q4_value = fields.Float(string="Q4 Target", compute="_compute_q4_value", store=True)
|
|
product_summary = fields.Html(string="Product-wise Summary", compute="_compute_product_summary")
|
|
def _compute_product_summary(self):
|
|
for rec in self:
|
|
totals = defaultdict(float)
|
|
for line in rec.line_ids:
|
|
total = sum([
|
|
line.apr_value, line.may_value, line.jun_value, line.jul_value,
|
|
line.aug_value, line.sep_value, line.oct_value, line.nov_value,
|
|
line.dec_value, line.jan_value, line.feb_value, line.mar_value
|
|
])
|
|
totals[line.product] += total
|
|
|
|
rows = "".join(f"<tr><td>{prod}</td><td>₹ {amt:.2f}</td></tr>" for prod, amt in totals.items())
|
|
rec.product_summary = f"""
|
|
<table class="table_custom" style="box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 8px;">
|
|
<thead><tr style="background-color: #635a99;"><td style="color:#fff" colspan="2"><b>Product Wise Target (Rupees In Lakhs)</b></td></tr></thead>
|
|
<thead><tr style="background-color: lavender;"><th class="column">Product</th><th class="column">Total</th></tr></thead>
|
|
<tbody>{rows}</tbody>
|
|
</table>
|
|
"""
|
|
def action_report_sales_plan_btn(self):
|
|
try:
|
|
action = self.env.ref("sos_sales.action_report_sales_plan").with_context(landscape=True).report_action(self)
|
|
return action
|
|
except ValueError as e:
|
|
print(f"Failed to find report action: {e}")
|
|
@api.model
|
|
def create(self, vals):
|
|
month_map = {
|
|
'total_april_value': 'apr_value',
|
|
'total_may_value': 'may_value',
|
|
'total_june_value': 'jun_value',
|
|
'total_july_value': 'jul_value',
|
|
'total_august_value': 'aug_value',
|
|
'total_september_value': 'sep_value',
|
|
'total_october_value': 'oct_value',
|
|
'total_november_value': 'nov_value',
|
|
'total_december_value': 'dec_value',
|
|
'total_january_value': 'jan_value',
|
|
'total_february_value': 'feb_value',
|
|
'total_march_value': 'mar_value',
|
|
}
|
|
|
|
monthly_totals = {key: 0.0 for key in month_map}
|
|
line_items = vals.get('line_ids', [])
|
|
|
|
for command in line_items:
|
|
if isinstance(command, (list, tuple)) and command[0] == 0: # create command
|
|
line_vals = command[2]
|
|
for field_name, month_key in month_map.items():
|
|
monthly_totals[field_name] += line_vals.get(month_key, 0.0)
|
|
|
|
# Assign calculated values into vals
|
|
vals.update(monthly_totals)
|
|
|
|
# Also calculate total_annual_value from monthly values
|
|
total = sum(monthly_totals.values())
|
|
vals['total_annual_value'] = total
|
|
sales_achievement_records = self.env['sos_sales_achievement_report'].search([
|
|
('financial_year', '=', vals['financial_year']),
|
|
('sales_person', '=', self.env.user.id)
|
|
], limit=1)
|
|
if sales_achievement_records:
|
|
sales_achievement_records.write({
|
|
'overall_target':total,
|
|
'planned_target_april':vals['total_april_value'],
|
|
'planned_target_may':vals['total_may_value'],
|
|
'planned_target_june':vals['total_june_value'],
|
|
'planned_target_july':vals['total_july_value'],
|
|
'planned_target_august':vals['total_august_value'],
|
|
'planned_target_september':vals['total_september_value'],
|
|
'planned_target_october':vals['total_october_value'],
|
|
'planned_target_november':vals['total_november_value'],
|
|
'planned_target_december':vals['total_december_value'],
|
|
'planned_target_january':vals['total_january_value'],
|
|
'planned_target_february':vals['total_february_value'],
|
|
'planned_target_march':vals['total_march_value']
|
|
})
|
|
else:
|
|
self.env['sos_sales_achievement_report'].create({
|
|
'financial_year': vals['financial_year'],
|
|
'sales_person': self.env.user.id,
|
|
'overall_target':vals['total_annual_value'],
|
|
'planned_target_april':vals['total_april_value'],
|
|
'planned_target_may':vals['total_may_value'],
|
|
'planned_target_june':vals['total_june_value'],
|
|
'planned_target_july':vals['total_july_value'],
|
|
'planned_target_august':vals['total_august_value'],
|
|
'planned_target_september':vals['total_september_value'],
|
|
'planned_target_october':vals['total_october_value'],
|
|
'planned_target_november':vals['total_november_value'],
|
|
'planned_target_december':vals['total_december_value'],
|
|
'planned_target_january':vals['total_january_value'],
|
|
'planned_target_february':vals['total_february_value'],
|
|
'planned_target_march':vals['total_march_value']
|
|
})
|
|
return super(sos_sales_plan_target, self).create(vals)
|
|
def write(self, vals):
|
|
res = super(sos_sales_plan_target, self).write(vals) # Perform the write first
|
|
|
|
for rec in self:
|
|
achievement = self.env['sos_sales_achievement_report'].search([
|
|
('financial_year', '=', rec.financial_year),
|
|
('sales_person', '=', rec.sales_executive.id)
|
|
], limit=1)
|
|
|
|
vals_to_write = {
|
|
'overall_target': rec.total_annual_value,
|
|
'planned_target_april': rec.total_april_value,
|
|
'planned_target_may': rec.total_may_value,
|
|
'planned_target_june': rec.total_june_value,
|
|
'planned_target_july': rec.total_july_value,
|
|
'planned_target_august': rec.total_august_value,
|
|
'planned_target_september': rec.total_september_value,
|
|
'planned_target_october': rec.total_october_value,
|
|
'planned_target_november': rec.total_november_value,
|
|
'planned_target_december': rec.total_december_value,
|
|
'planned_target_january': rec.total_january_value,
|
|
'planned_target_february': rec.total_february_value,
|
|
'planned_target_march': rec.total_march_value,
|
|
}
|
|
|
|
if achievement:
|
|
achievement.write(vals_to_write)
|
|
else:
|
|
vals_to_write.update({
|
|
'financial_year': rec.financial_year,
|
|
'sales_person': rec.sales_executive.id,
|
|
})
|
|
self.env['sos_sales_achievement_report'].create(vals_to_write)
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@api.constrains('financial_year', 'sales_executive')
|
|
def check_unique_values(self):
|
|
for record in self:
|
|
existing_records = self.search([
|
|
('sales_executive', '=', record.sales_executive.id),
|
|
('financial_year', '=', record.financial_year),
|
|
('id', '!=', record.id) # Exclude self
|
|
])
|
|
print(existing_records)
|
|
if existing_records:
|
|
raise ValidationError("Target of the financial year must be unique.")
|
|
|
|
@api.depends('line_ids.apr_value', 'line_ids.may_value', 'line_ids.jun_value',
|
|
'line_ids.jul_value', 'line_ids.aug_value', 'line_ids.sep_value',
|
|
'line_ids.oct_value', 'line_ids.nov_value', 'line_ids.dec_value',
|
|
'line_ids.jan_value', 'line_ids.feb_value', 'line_ids.mar_value')
|
|
def _compute_total_annual_value(self):
|
|
for rec in self:
|
|
rec.total_annual_value = sum(
|
|
line.apr_value + line.may_value + line.jun_value + line.jul_value +
|
|
line.aug_value + line.sep_value + line.oct_value + line.nov_value +
|
|
line.dec_value + line.jan_value + line.feb_value + line.mar_value
|
|
for line in rec.line_ids
|
|
)
|
|
@api.depends('line_ids.apr_value', 'line_ids.may_value', 'line_ids.jun_value')
|
|
def _compute_q1_value(self):
|
|
for rec in self:
|
|
rec.total_q1_value = sum(
|
|
line.apr_value + line.may_value + line.jun_value
|
|
for line in rec.line_ids
|
|
)
|
|
@api.depends('line_ids.jul_value', 'line_ids.aug_value', 'line_ids.sep_value')
|
|
def _compute_q2_value(self):
|
|
for rec in self:
|
|
rec.total_q2_value = sum(
|
|
line.jul_value + line.aug_value + line.sep_value
|
|
for line in rec.line_ids
|
|
)
|
|
@api.depends('line_ids.oct_value', 'line_ids.nov_value', 'line_ids.dec_value')
|
|
def _compute_q3_value(self):
|
|
for rec in self:
|
|
rec.total_q3_value = sum(
|
|
line.oct_value + line.nov_value + line.dec_value
|
|
for line in rec.line_ids
|
|
)
|
|
@api.depends('line_ids.jan_value', 'line_ids.feb_value', 'line_ids.mar_value')
|
|
def _compute_q4_value(self):
|
|
for rec in self:
|
|
rec.total_q4_value = sum(
|
|
line.jan_value + line.feb_value + line.mar_value
|
|
for line in rec.line_ids
|
|
)
|
|
@api.depends(
|
|
'line_ids.apr_value', 'line_ids.may_value', 'line_ids.jun_value',
|
|
'line_ids.jul_value', 'line_ids.aug_value', 'line_ids.sep_value',
|
|
'line_ids.oct_value', 'line_ids.nov_value', 'line_ids.dec_value',
|
|
'line_ids.jan_value', 'line_ids.feb_value', 'line_ids.mar_value'
|
|
)
|
|
def _compute_monthly_totals(self):
|
|
for rec in self:
|
|
rec.total_april_value = sum(line.apr_value for line in rec.line_ids)
|
|
rec.total_may_value = sum(line.may_value for line in rec.line_ids)
|
|
rec.total_june_value = sum(line.jun_value for line in rec.line_ids)
|
|
rec.total_july_value = sum(line.jul_value for line in rec.line_ids)
|
|
rec.total_august_value = sum(line.aug_value for line in rec.line_ids)
|
|
rec.total_september_value = sum(line.sep_value for line in rec.line_ids)
|
|
rec.total_october_value = sum(line.oct_value for line in rec.line_ids)
|
|
rec.total_november_value = sum(line.nov_value for line in rec.line_ids)
|
|
rec.total_december_value = sum(line.dec_value for line in rec.line_ids)
|
|
rec.total_january_value = sum(line.jan_value for line in rec.line_ids)
|
|
rec.total_february_value = sum(line.feb_value for line in rec.line_ids)
|
|
rec.total_march_value = sum(line.mar_value for line in rec.line_ids)
|
|
|
|
def _get_financial_year(self):
|
|
current_date = date.today()
|
|
start_year = current_date.year if current_date.month >= 4 else current_date.year - 1
|
|
end_year = start_year + 1
|
|
return f"FY {start_year}-{end_year}"
|
|
|
|
class sos_sales_plan_target_Line(models.Model):
|
|
_name = 'sos_sales_plan_target_lines'
|
|
_description = 'Sosaley Sales Target Lines'
|
|
|
|
ref_id = fields.Many2one('sos_sales_plan_target', string="Sales Target")
|
|
region = fields.Char(string="Region / Vertical")
|
|
customer_name = fields.Many2one('sos_customers',string="Customer Name",domain=lambda self: [('responsible', '=', self.env.uid)])
|
|
product = fields.Selection(
|
|
[
|
|
('BHMS 1.2V', 'BHMS 1.2V'),
|
|
('BHMS 2V', 'BHMS 2V'),
|
|
('BHMS 12V', 'BHMS 12V'),
|
|
('BHMS 48V', 'BHMS 48V'),
|
|
('BMS-HV', 'BMS-HV'),
|
|
('BMS-LV 100A', 'BMS-LV 100A'),
|
|
('BMS-LV 40A', 'BMS-LV 40A'),
|
|
('SBMS 55A', 'SBMS 55A'),
|
|
('MC 250W', 'MC 250W'),
|
|
('HeartTarang', 'HeartTarang')
|
|
],
|
|
string="Products")
|
|
location = fields.Char(string="Location")
|
|
date_billed = fields.Date(string="Date (Billed)")
|
|
apr_qty = fields.Integer(string="April Qty")
|
|
apr_value = fields.Float(string="April Value", digits=(12, 2))
|
|
may_qty = fields.Integer(string="May Qty")
|
|
may_value = fields.Float(string="May Value", digits=(12, 2))
|
|
jun_qty = fields.Integer(string="June Qty")
|
|
jun_value = fields.Float(string="June Value", digits=(12, 2))
|
|
jul_qty = fields.Integer(string="July Qty")
|
|
jul_value = fields.Float(string="July Value", digits=(12, 2))
|
|
aug_qty = fields.Integer(string="August Qty")
|
|
aug_value = fields.Float(string="August Value", digits=(12, 2))
|
|
sep_qty = fields.Integer(string="September Qty")
|
|
sep_value = fields.Float(string="September Value", digits=(12, 2))
|
|
oct_qty = fields.Integer(string="October Qty")
|
|
oct_value = fields.Float(string="October Value", digits=(12, 2))
|
|
nov_qty = fields.Integer(string="November Qty")
|
|
nov_value = fields.Float(string="November Value", digits=(12, 2))
|
|
dec_qty = fields.Integer(string="December Qty")
|
|
dec_value = fields.Float(string="December Value", digits=(12, 2))
|
|
jan_qty = fields.Integer(string="January Qty")
|
|
jan_value = fields.Float(string="January Value", digits=(12, 2))
|
|
feb_qty = fields.Integer(string="February Qty")
|
|
feb_value = fields.Float(string="February Value", digits=(12, 2))
|
|
mar_qty = fields.Integer(string="March Qty")
|
|
mar_value = fields.Float(string="March Value", digits=(12, 2))
|
|
@api.onchange('customer_name')
|
|
def _onchange_customer_name(self):
|
|
if self.customer_name:
|
|
self.location = self.customer_name.customer_city or '' |