Skip to content

Commit

Permalink
temp rebasing PR 778 (541daec)
Browse files Browse the repository at this point in the history
  • Loading branch information
roboadhoc committed Apr 22, 2024
2 parents 9788bc8 + 541daec commit 2818bff
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 38 deletions.
3 changes: 2 additions & 1 deletion sale_timesheet_ux/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ Sales Timesheet UX
==================

* When confirming a sale order with a product with Product Type = "Service" and Create on Order = "Project & Task", if the SO has an analytic account that is related to one project, then the system won't create a new project but use the analytic's account project to create the task inside.
* When confirming a sale order with a product with Product Type = "Service" and Create on Order = "Project & Task" both the proyect and the task will remain related to the SO when "Billable" is turned off from the project settings (works both for a new proyect and task as for a new task in an existing proyect).
* When confirming a sale order with a product with Product Type = "Service" and Create on Order = "Project & Task", the project and the task will remain related to the SO and the customer will remain related to the project (stays related in the backend even though is hidden by default) when "Billable" is turned off from the project settings (works both for a new proyect and task as for a new task in an existing proyect).
* When (and only when) "Billable" is active can't be edited. Instead adds a button to change its value with an alert message to confirm the disabling of the "Billable" option in the project settings.
* Se protegen las lineas de las ordenes de ventas que estan asociadas a los partes de horas en los siguientes casos (no se borran las horas imputadas a esa linea de la OV) (esta proteccion se habilita desde las configuraciones del parte de horas):

1) Si a un proyecto se le desmarga el facturable en su configuración: si un proyecto esta como facturable, y tiene tareas con partes de horas asociados a ordenes de venta, al destildarle el facturable la orden de venta seguira teniendo cargadas las horas imputadas en esa tarea.
Expand Down
7 changes: 5 additions & 2 deletions sale_timesheet_ux/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Sales Timesheet UX",
"summary": "",
"version": "16.0.1.2.0",
"version": "17.0.1.0.0",
"website": "www.adhoc.com.ar",
"license": "AGPL-3",
"author": "ADHOC SA",
Expand All @@ -10,10 +10,13 @@
"sale_timesheet",
],
"data": [
'security/ir.model.access.csv',
'views/project_inherit.xml',
"wizards/res_config_settings_views.xml",
"wizards/project_change_biillable_views.xml",
],
"demo": [
],
"application": False,
'installable': False,
'installable': True,
}
21 changes: 20 additions & 1 deletion sale_timesheet_ux/models/project_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,27 @@ def write(self, values):
self = self.with_context(write_allow_billiable=True)
res = super().write(values)
if 'allow_billable' in values:
for rec in self:
for rec in self:
if rec.allow_billable:
for task in rec.task_ids:
task.order_id = task.sale_order_id
return res

def _compute_partner_id(self):
for project in self:
project_partner_id = project.partner_id or project.analytic_account_id.partner_id or project.sale_order_id.partner_id
super()._compute_partner_id()
project.partner_id = project_partner_id

def change_allow_billable(self):
if self.allow_billable == True:
wiz = self.env['allow.billable.wizard'].create({'project_id': self.id})
return {
'name': _('Project'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'views': [(self.env.ref('sale_timesheet_ux.change_allow_billable_wizzard').id, 'form')],
'res_model': 'allow.billable.wizard',
'res_id': wiz.id,
'target': 'new',
}
31 changes: 11 additions & 20 deletions sale_timesheet_ux/models/project_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,15 @@ def _get_timesheet(self):
recs = recs.filtered(lambda x: not x.is_so_line_edited)
return recs

def _compute_sale_order_id(self):
# Store allow_billable task's state to mantain the relation
# between the task with the SO that originated it when allow_billable is changed in project
billable_condition = {x: x.allow_billable for x in self}
self.allow_billable = True
super()._compute_sale_order_id()
for k, v in billable_condition.items():
k.allow_billable = v

def _compute_partner_id(self):
for task in self:
task_partner_id = task.partner_id or task.project_id.partner_id or task.sale_order_id.partner_id
super()._compute_partner_id()
task.partner_id = task_partner_id

def _compute_sale_line(self):
# Override this method to combine the behavior between sale_project and sale_timesheet
# so the change of value of "allow_billable" to True doesn't unlink the sale_line_id of the task
# with the SO that originated it
billable_tasks = self.filtered('allow_billable')
for task in billable_tasks:
if not task.sale_line_id:
# if the display_project_id is set then it means the task is classic task or a subtask with another project than its parent.
task.sale_line_id = task.display_project_id.sale_line_id or task.parent_id.sale_line_id or task.project_id.sale_line_id or task.milestone_id.sale_line_id
# check sale_line_id and customer are coherent
if task.sale_line_id.order_partner_id.commercial_partner_id != task.partner_id.commercial_partner_id:
task.sale_line_id = False
for task in self:
sale_line = task.sale_line_id or task.parent_id.sale_line_id or task.project_id.sale_line_id or task.milestone_id.sale_line_id
super()._compute_sale_line()
if not task.sale_line_id or task.sale_line_id != sale_line:
task.sale_line_id = sale_line
2 changes: 1 addition & 1 deletion sale_timesheet_ux/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ class SaleOrder(models.Model):
@api.depends('order_line.product_id.project_id')
def _compute_tasks_ids(self):
for order in self:
order.tasks_ids = self.env['project.task'].search(['&', ('display_project_id', '!=', 'False'), '|','|', ('sale_line_id', 'in', order.order_line.ids), ('sale_order_id', '=', order.id), ('order_id', '=', order.id)])
order.tasks_ids = self.env['project.task'].search(['&', ('project_id', '!=', 'False'), '|','|', ('sale_line_id', 'in', order.order_line.ids), ('sale_order_id', '=', order.id), ('order_id', '=', order.id)])
order.tasks_count = len(order.tasks_ids)
2 changes: 2 additions & 0 deletions sale_timesheet_ux/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_allow_billable_wizard,access_allow_billable_wizard,model_allow_billable_wizard,base.group_user,1,1,1,0
17 changes: 17 additions & 0 deletions sale_timesheet_ux/views/project_inherit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<record id="view_edit_project_billable_inherit_form" model="ir.ui.view">
<field name="name">project.project.view.inherit</field>
<field name="model">project.project</field>
<field name="inherit_id" ref="sale_project.view_edit_project_inherit_form"/>
<field name="arch" type="xml">
<field name="allow_billable" position="attributes">
<attribute name="readonly">allow_billable</attribute>
<attribute name="force_save">1</attribute>
</field>
<field name="allow_billable" position="after">
<button string="Deactivate Billable" name="change_allow_billable" type="object" class="btn-primary" invisible="not allow_billable"/>
</field>
</field>
</record>
</odoo>
1 change: 1 addition & 0 deletions sale_timesheet_ux/wizards/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import res_config_settings
from . import project_change_billable
25 changes: 25 additions & 0 deletions sale_timesheet_ux/wizards/project_change_biillable_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<data>

<record id="change_allow_billable_wizzard" model="ir.ui.view">
<field name="name">allow.billable.wizard.form</field>
<field name="model">allow.billable.wizard</field>
<field name="arch" type="xml">
<form>
<field name="project_id" invisible="1"/>
<group>
<label for='project_id' string="Confirm Allow Billable Change"/>
<p>Are you sure you want to change the 'Allow Billable' field to False for this project?</p>
</group>
<footer>
<button name="confirm_change" string="Yes, Change it" type="object" class="btn-primary"/>
<button name="cancel_change" string="Cancel" type="object" class="btn btn-default"/>
</footer>
</form>
</field>
</record>

</data>

</odoo>
20 changes: 20 additions & 0 deletions sale_timesheet_ux/wizards/project_change_billable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from odoo import models, fields, api

class AllowBillableWizard(models.TransientModel):
_name = 'allow.billable.wizard'
_description = 'Confirmar cambio de valor de Allow Billable'

project_id = fields.Many2one('project.project', string='Project', default=lambda self: self.default_get_project_id())

@api.model
def default_get_project_id(self):
project = self.env['project.project'].search([('id', '=', self.env.context.get('project_id'))])
return project

def confirm_change(self):
self.project_id.allow_billable = False
return {'type': 'ir.actions.act_window_close'}

def cancel_change(self):
self.project_id.allow_billable = True
return {'type': 'ir.actions.act_window_close'}
18 changes: 5 additions & 13 deletions sale_timesheet_ux/wizards/res_config_settings_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,11 @@
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="sale_timesheet.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div name="timesheet_billing" position="inside">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="timesheet_protect_so_line"/>
</div>
<div class="o_setting_right_pane">
<label for="timesheet_protect_so_line"/>
<div class="text-muted">
By default changes on project, task, and tickets related to billing information are synced to timesheet lines. This can cause automated modification of the sale line associated to a timesheet. Activate this option if you want to protect timesheet lines so that changes won't modify the associated sales lines (highly recommended especially for Prepaid/Fixed Price use cases)
</div>
</div>
</div>
</div>
<xpath expr="//setting[@name='invoice_policy']" position="after">
<setting help="By default changes on project, task, and tickets related to billing information are synced to timesheet lines. This can cause automated modification of the sale line associated to a timesheet. Activate this option if you want to protect timesheet lines so that changes won't modify the associated sales lines (highly recommended especially for Prepaid/Fixed Price use cases)" name="timesheet_protect_so_line">
<field name="timesheet_protect_so_line"/>
</setting>
</xpath>
</field>
</record>
</odoo>

0 comments on commit 2818bff

Please sign in to comment.