Skip to content
Extraits de code Groupes Projets
Valider 7dbfabc6 rédigé par Julien - Le Filament's avatar Julien - Le Filament
Parcourir les fichiers

Merge branch '14.0-sale-overview' into '14.0'

[UPD] do not check is projet milestone in sale timesheet overview

See merge request !2
parents 60d04deb 4b8a115a
Branches
Aucune étiquette associée trouvée
1 requête de fusion!2[UPD] do not check is projet milestone in sale timesheet overview
......@@ -7,7 +7,7 @@ from odoo.addons.sale_timesheet.models.project_overview import _to_action_data
class Project(models.Model):
_inherit = 'project.project'
_inherit = "project.project"
# ------------------------------------------------------
# Fields declaration
......@@ -37,9 +37,9 @@ class Project(models.Model):
if not self:
return False
uom_hour = self.env.ref('uom.product_uom_hour')
uom_hour = self.env.ref("uom.product_uom_hour")
company_uom = self.env.company.timesheet_encode_uom_id
is_uom_day = company_uom and company_uom == self.env.ref('uom.product_uom_day')
is_uom_day = company_uom and company_uom == self.env.ref("uom.product_uom_day")
# build SQL query and fetch raw data
query, query_params = self._table_rows_sql_query()
......@@ -54,53 +54,98 @@ class Project(models.Model):
sale_line_ids = set()
sale_order_ids = set()
for key_tuple, row in rows_employee.items():
if row[0]['sale_line_id']:
sale_line_ids.add(row[0]['sale_line_id'])
if row[0]['sale_order_id']:
sale_order_ids.add(row[0]['sale_order_id'])
if row[0]["sale_line_id"]:
sale_line_ids.add(row[0]["sale_line_id"])
if row[0]["sale_order_id"]:
sale_order_ids.add(row[0]["sale_order_id"])
sale_orders = self.env['sale.order'].sudo().browse(sale_order_ids | empty_order_ids)
sale_order_lines = self.env['sale.order.line'].sudo().browse(sale_line_ids | empty_line_ids)
sale_orders = (
self.env["sale.order"].sudo().browse(sale_order_ids | empty_order_ids)
)
sale_order_lines = (
self.env["sale.order.line"].sudo().browse(sale_line_ids | empty_line_ids)
)
map_so_names = {so.id: so.name for so in sale_orders}
map_so_cancel = {so.id: so.state == 'cancel' for so in sale_orders}
map_so_cancel = {so.id: so.state == "cancel" for so in sale_orders}
map_sol = {sol.id: sol for sol in sale_order_lines}
map_sol_names = {sol.id: sol.name.split('\n')[0] if sol.name else _('No Sales Order Line') for sol in
sale_order_lines}
map_sol_names = {
sol.id: sol.name.split("\n")[0] if sol.name else _("No Sales Order Line")
for sol in sale_order_lines
}
map_sol_so = {sol.id: sol.order_id.id for sol in sale_order_lines}
rows_sale_line = {} # (so, sol) -> [INFO, before, M1, M2, M3, Done, M3, M4, M5, After, Forecasted]
rows_sale_line = (
{}
) # (so, sol) -> [INFO, before, M1, M2, M3, Done, M3, M4, M5, After, Forecasted]
for sale_line_id in empty_line_ids: # add service SO line having no timesheet
sale_line_row_key = (map_sol_so.get(sale_line_id), sale_line_id)
sale_line = map_sol.get(sale_line_id)
is_milestone = sale_line.product_id.invoice_policy == 'delivery' and sale_line.product_id.service_type == 'manual' if sale_line else False
rows_sale_line[sale_line_row_key] = [{'label': map_sol_names.get(sale_line_id, _('No Sales Order Line')),
'res_id': sale_line_id, 'res_model': 'sale.order.line',
'type': 'sale_order_line',
'is_milestone': is_milestone}] + default_row_vals[:]
if not is_milestone:
is_milestone = (
sale_line.product_id.invoice_policy == "delivery"
and sale_line.product_id.service_type == "manual"
if sale_line
else False
)
rows_sale_line[sale_line_row_key] = [
{
"label": map_sol_names.get(sale_line_id, _("No Sales Order Line")),
"res_id": sale_line_id,
"res_model": "sale.order.line",
"type": "sale_order_line",
"is_milestone": is_milestone,
}
] + default_row_vals[:]
# ***** Modif Filament *****
rows_sale_line[sale_line_row_key][
-2] = sale_line.product_uom_qty * sale_line.price_unit / sale_line.taux_horaire if sale_line else 0.0
rows_sale_line[sale_line_row_key][-2] = (
sale_line.product_uom_qty
* sale_line.price_unit
/ sale_line.taux_horaire
if sale_line
else 0.0
)
rows_sale_line_all_data = {}
if not employees:
employees = self.env['hr.employee'].sudo().search(self.env['account.analytic.line']._domain_employee_id())
employees = (
self.env["hr.employee"]
.sudo()
.search(self.env["account.analytic.line"]._domain_employee_id())
)
for row_key, row_employee in rows_employee.items():
sale_order_id, sale_line_id, employee_id = row_key
# sale line row
sale_line_row_key = (sale_order_id, sale_line_id)
if sale_line_row_key not in rows_sale_line:
sale_line = map_sol.get(sale_line_id, self.env['sale.order.line'])
is_milestone = sale_line.product_id.invoice_policy == 'delivery' and sale_line.product_id.service_type == 'manual' if sale_line else False
rows_sale_line[sale_line_row_key] = [{'label': map_sol_names.get(sale_line.id) if sale_line else _(
'No Sales Order Line'), 'res_id': sale_line_id, 'res_model': 'sale.order.line',
'type': 'sale_order_line',
'is_milestone': is_milestone}] + default_row_vals[
:] # INFO, before, M1, M2, M3, Done, M3, M4, M5, After, Forecasted
if not is_milestone:
sale_line = map_sol.get(sale_line_id, self.env["sale.order.line"])
is_milestone = (
sale_line.product_id.invoice_policy == "delivery"
and sale_line.product_id.service_type == "manual"
if sale_line
else False
)
rows_sale_line[sale_line_row_key] = [
{
"label": (
map_sol_names.get(sale_line.id)
if sale_line
else _("No Sales Order Line")
),
"res_id": sale_line_id,
"res_model": "sale.order.line",
"type": "sale_order_line",
"is_milestone": is_milestone,
}
] + default_row_vals[
:
] # INFO, before, M1, M2, M3, Done, M3, M4, M5, After, Forecasted
# ***** Modif Filament *****
rows_sale_line[sale_line_row_key][
-2] = sale_line.product_uom_qty * sale_line.price_unit / sale_line.taux_horaire if sale_line else 0.0
rows_sale_line[sale_line_row_key][-2] = (
sale_line.product_uom_qty
* sale_line.price_unit
/ sale_line.taux_horaire
if sale_line
else 0.0
)
if sale_line_row_key not in rows_sale_line_all_data:
rows_sale_line_all_data[sale_line_row_key] = [0] * len(row_employee)
......@@ -108,22 +153,31 @@ class Project(models.Model):
if employee_id in employees.ids:
rows_sale_line[sale_line_row_key][index] += row_employee[index]
rows_sale_line_all_data[sale_line_row_key][index] += row_employee[index]
if not rows_sale_line[sale_line_row_key][0].get('is_milestone'):
rows_sale_line[sale_line_row_key][-1] = rows_sale_line[sale_line_row_key][-2] - \
rows_sale_line_all_data[sale_line_row_key][5]
else:
rows_sale_line[sale_line_row_key][-1] = 0
rows_sale_order = {} # so -> [INFO, before, M1, M2, M3, Done, M3, M4, M5, After, Forecasted]
# ***** Modif Filament *****
rows_sale_line[sale_line_row_key][-1] = (
rows_sale_line[sale_line_row_key][-2]
- rows_sale_line_all_data[sale_line_row_key][5]
)
rows_sale_order = (
{}
) # so -> [INFO, before, M1, M2, M3, Done, M3, M4, M5, After, Forecasted]
for row_key, row_sale_line in rows_sale_line.items():
sale_order_id = row_key[0]
# sale order row
if sale_order_id not in rows_sale_order:
rows_sale_order[sale_order_id] = [{'label': map_so_names.get(sale_order_id, _('No Sales Order')),
'canceled': map_so_cancel.get(sale_order_id, False),
'res_id': sale_order_id, 'res_model': 'sale.order',
'type': 'sale_order'}] + default_row_vals[
:] # INFO, before, M1, M2, M3, Done, M3, M4, M5, After, Forecasted
rows_sale_order[sale_order_id] = [
{
"label": map_so_names.get(sale_order_id, _("No Sales Order")),
"canceled": map_so_cancel.get(sale_order_id, False),
"res_id": sale_order_id,
"res_model": "sale.order",
"type": "sale_order",
}
] + default_row_vals[
:
] # INFO, before, M1, M2, M3, Done, M3, M4, M5, After, Forecasted
for index in range(1, len(row_sale_line)):
rows_sale_order[sale_order_id][index] += row_sale_line[index]
......@@ -134,143 +188,199 @@ class Project(models.Model):
timesheet_forecast_table_rows.append(sale_order_row)
for sale_line_row_key, sale_line_row in rows_sale_line.items():
if sale_order_id == sale_line_row_key[0]:
sale_order_row[0]['has_children'] = True
sale_order_row[0]["has_children"] = True
timesheet_forecast_table_rows.append(sale_line_row)
for employee_row_key, employee_row in rows_employee.items():
if sale_order_id == employee_row_key[0] and sale_line_row_key[1] == employee_row_key[1] and \
employee_row_key[2] in employees.ids:
sale_line_row[0]['has_children'] = True
if (
sale_order_id == employee_row_key[0]
and sale_line_row_key[1] == employee_row_key[1]
and employee_row_key[2] in employees.ids
):
sale_line_row[0]["has_children"] = True
timesheet_forecast_table_rows.append(employee_row)
if is_uom_day:
# convert all values from hours to days
for row in timesheet_forecast_table_rows:
for index in range(1, len(row)):
row[index] = round(uom_hour._compute_quantity(row[index], company_uom, raise_if_failure=False), 2)
row[index] = round(
uom_hour._compute_quantity(
row[index], company_uom, raise_if_failure=False
),
2,
)
# complete table data
return {
'header': self._table_header(),
'rows': timesheet_forecast_table_rows
}
return {"header": self._table_header(), "rows": timesheet_forecast_table_rows}
def _plan_get_stat_button(self):
stat_buttons = []
num_projects = len(self)
if num_projects == 1:
action_data = _to_action_data('project.project', res_id=self.id,
views=[[self.env.ref('project.edit_project').id, 'form']])
action_data = _to_action_data(
"project.project",
res_id=self.id,
views=[[self.env.ref("project.edit_project").id, "form"]],
)
else:
action_data = _to_action_data(action=self.env.ref('project.open_view_project_all_config').sudo(),
domain=[('id', 'in', self.ids)])
action_data = _to_action_data(
action=self.env.ref("project.open_view_project_all_config").sudo(),
domain=[("id", "in", self.ids)],
)
stat_buttons.append({
'name': _('Project') if num_projects == 1 else _('Projects'),
'count': num_projects,
'icon': 'fa fa-puzzle-piece',
'action': action_data
})
stat_buttons.append(
{
"name": _("Project") if num_projects == 1 else _("Projects"),
"count": num_projects,
"icon": "fa fa-puzzle-piece",
"action": action_data,
}
)
# if only one project, add it in the context as default value
tasks_domain = [('project_id', 'in', self.ids)]
tasks_domain = [("project_id", "in", self.ids)]
tasks_context = self.env.context.copy()
tasks_context.pop('search_default_name', False)
late_tasks_domain = [('project_id', 'in', self.ids), ('date_deadline', '<', fields.Date.to_string(fields.Date.today())), ('date_end', '=', False)]
overtime_tasks_domain = [('project_id', 'in', self.ids), ('overtime', '>', 0), ('planned_hours', '>', 0)]
tasks_context.pop("search_default_name", False)
late_tasks_domain = [
("project_id", "in", self.ids),
("date_deadline", "<", fields.Date.to_string(fields.Date.today())),
("date_end", "=", False),
]
overtime_tasks_domain = [
("project_id", "in", self.ids),
("overtime", ">", 0),
("planned_hours", ">", 0),
]
if len(self) == 1:
tasks_context = {**tasks_context, 'default_project_id': self.id}
tasks_context = {**tasks_context, "default_project_id": self.id}
elif len(self):
task_projects_ids = self.env['project.task'].read_group([('project_id', 'in', self.ids)], ['project_id'], ['project_id'])
task_projects_ids = [p['project_id'][0] for p in task_projects_ids]
task_projects_ids = self.env["project.task"].read_group(
[("project_id", "in", self.ids)], ["project_id"], ["project_id"]
)
task_projects_ids = [p["project_id"][0] for p in task_projects_ids]
if len(task_projects_ids) == 1:
tasks_context = {**tasks_context, 'default_project_id': task_projects_ids[0]}
stat_buttons.append({
'name': _('Tasks'),
'count': sum(self.mapped('task_count')),
'icon': 'fa fa-tasks',
'action': _to_action_data(
action=self.env.ref('project.action_view_task').sudo(),
tasks_context = {
**tasks_context,
"default_project_id": task_projects_ids[0],
}
stat_buttons.append(
{
"name": _("Tasks"),
"count": sum(self.mapped("task_count")),
"icon": "fa fa-tasks",
"action": _to_action_data(
action=self.env.ref("project.action_view_task").sudo(),
domain=tasks_domain,
context=tasks_context
context=tasks_context,
),
}
)
})
stat_buttons.append({
'name': [_("Tasks"), _("Late")],
'count': self.env['project.task'].search_count(late_tasks_domain),
'icon': 'fa fa-tasks',
'action': _to_action_data(
action=self.env.ref('project.action_view_task').sudo(),
stat_buttons.append(
{
"name": [_("Tasks"), _("Late")],
"count": self.env["project.task"].search_count(late_tasks_domain),
"icon": "fa fa-tasks",
"action": _to_action_data(
action=self.env.ref("project.action_view_task").sudo(),
domain=late_tasks_domain,
context=tasks_context,
),
})
stat_buttons.append({
'name': [_("Tasks"), _("in Overtime")],
'count': self.env['project.task'].search_count(overtime_tasks_domain),
'icon': 'fa fa-tasks',
'action': _to_action_data(
action=self.env.ref('project.action_view_task').sudo(),
}
)
stat_buttons.append(
{
"name": [_("Tasks"), _("in Overtime")],
"count": self.env["project.task"].search_count(overtime_tasks_domain),
"icon": "fa fa-tasks",
"action": _to_action_data(
action=self.env.ref("project.action_view_task").sudo(),
domain=overtime_tasks_domain,
context=tasks_context,
),
})
}
)
if self.env.user.has_group('sales_team.group_sale_salesman_all_leads'):
if self.env.user.has_group("sales_team.group_sale_salesman_all_leads"):
# read all the sale orders linked to the projects' tasks
task_so_ids = self.env['project.task'].search_read([
('project_id', 'in', self.ids), ('sale_order_id', '!=', False)
], ['sale_order_id'])
task_so_ids = [o['sale_order_id'][0] for o in task_so_ids]
task_so_ids = self.env["project.task"].search_read(
[("project_id", "in", self.ids), ("sale_order_id", "!=", False)],
["sale_order_id"],
)
task_so_ids = [o["sale_order_id"][0] for o in task_so_ids]
sale_ids = self.env['sale.order'].search([('project_id', 'in', self.ids)])
sale_orders = self.mapped('sale_line_id.order_id') | self.env['sale.order'].browse(task_so_ids) | sale_ids
sale_ids = self.env["sale.order"].search([("project_id", "in", self.ids)])
sale_orders = (
self.mapped("sale_line_id.order_id")
| self.env["sale.order"].browse(task_so_ids)
| sale_ids
)
if sale_orders:
stat_buttons.append({
'name': _('Sales Orders'),
'count': len(sale_orders),
'icon': 'fa fa-dollar',
'action': _to_action_data(
action=self.env.ref('sale.action_orders').sudo(),
domain=[('id', 'in', sale_orders.ids)],
context={'create': False, 'edit': False, 'delete': False}
stat_buttons.append(
{
"name": _("Sales Orders"),
"count": len(sale_orders),
"icon": "fa fa-dollar",
"action": _to_action_data(
action=self.env.ref("sale.action_orders").sudo(),
domain=[("id", "in", sale_orders.ids)],
context={"create": False, "edit": False, "delete": False},
),
}
)
})
invoice_ids = self.env['sale.order'].search_read([('id', 'in', sale_orders.ids)], ['invoice_ids'])
invoice_ids = list(itertools.chain(*[i['invoice_ids'] for i in invoice_ids]))
invoice_ids = self.env['account.move'].search_read([('id', 'in', invoice_ids), ('move_type', '=', 'out_invoice')], ['id'])
invoice_ids = list(map(lambda x: x['id'], invoice_ids))
invoice_ids = self.env["sale.order"].search_read(
[("id", "in", sale_orders.ids)], ["invoice_ids"]
)
invoice_ids = list(
itertools.chain(*[i["invoice_ids"] for i in invoice_ids])
)
invoice_ids = self.env["account.move"].search_read(
[("id", "in", invoice_ids), ("move_type", "=", "out_invoice")],
["id"],
)
invoice_ids = list(map(lambda x: x["id"], invoice_ids))
if invoice_ids:
stat_buttons.append({
'name': _('Invoices'),
'count': len(invoice_ids),
'icon': 'fa fa-pencil-square-o',
'action': _to_action_data(
action=self.env.ref('account.action_move_out_invoice_type').sudo(),
domain=[('id', 'in', invoice_ids), ('move_type', '=', 'out_invoice')],
context={'create': False, 'delete': False}
stat_buttons.append(
{
"name": _("Invoices"),
"count": len(invoice_ids),
"icon": "fa fa-pencil-square-o",
"action": _to_action_data(
action=self.env.ref(
"account.action_move_out_invoice_type"
).sudo(),
domain=[
("id", "in", invoice_ids),
("move_type", "=", "out_invoice"),
],
context={"create": False, "delete": False},
),
}
)
})
ts_tree = self.env.ref('hr_timesheet.hr_timesheet_line_tree')
ts_form = self.env.ref('hr_timesheet.hr_timesheet_line_form')
if self.env.company.timesheet_encode_uom_id == self.env.ref('uom.product_uom_day'):
timesheet_label = [_('Days'), _('Recorded')]
ts_tree = self.env.ref("hr_timesheet.hr_timesheet_line_tree")
ts_form = self.env.ref("hr_timesheet.hr_timesheet_line_form")
if self.env.company.timesheet_encode_uom_id == self.env.ref(
"uom.product_uom_day"
):
timesheet_label = [_("Days"), _("Recorded")]
else:
timesheet_label = [_('Hours'), _('Recorded')]
stat_buttons.append({
'name': timesheet_label,
'count': sum(self.mapped('total_timesheet_time')),
'icon': 'fa fa-calendar',
'action': _to_action_data(
'account.analytic.line',
domain=[('project_id', 'in', self.ids)],
views=[(ts_tree.id, 'list'), (ts_form.id, 'form')],
timesheet_label = [_("Hours"), _("Recorded")]
stat_buttons.append(
{
"name": timesheet_label,
"count": sum(self.mapped("total_timesheet_time")),
"icon": "fa fa-calendar",
"action": _to_action_data(
"account.analytic.line",
domain=[("project_id", "in", self.ids)],
views=[(ts_tree.id, "list"), (ts_form.id, "form")],
),
}
)
})
return stat_buttons
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter