Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[10.0][ADD] Add sale_project_fixed_price_task_completed_invoicing #485

Conversation

leemannd
Copy link
Contributor

@leemannd leemannd commented May 30, 2017

Main Goal

The main goal of this module is to add the possibility to link a sale.order.line
to a project.task considering the delivery.
Unless sale_timesheet, the quantity shipped won't be linked to a Timesheet nor
to the time spent on the task. The price is fixed on the sale.order.line and it
will be considered as shipped once the task is accomplished.sale.order.line. The sale.order.line is going to be delivered once the task is accomplished.

Nota Bene

  1. The main links between sale.order, sale.order.line, project and tasks is done in sale_timesheet. In order to ensure compatibility in the future and between them, it has been choosen to inherit from it.
  2. There is an auto_install issue with project_timesheet_analytic_partner from oca project when I launched tests in local.

@leemannd leemannd force-pushed the 10_add_sale_project_fixed_price_task_completed_invoicing branch 2 times, most recently from 3b5488e to 84cfae1 Compare May 30, 2017 16:36
def toggle_invoiceable(self):
for task in self:
# We dont' want to modify when the related SOLine is invoiced
if not task.sale_line_id or task.sale_line_id.state in ('done'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in ('done', )

missing training comma. Probably 'cancel' should be handled in the same way.

for task in self:
# We dont' want to modify when the related SOLine is invoiced
if not task.sale_line_id or task.sale_line_id.state in ('done'):
continue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raise a UserError to give the user some feedback.

SOLine = self.env['sale.order.line']
so_line = SOLine.browse(vals.get('sale_line_id'))
# We don't want to add a project.task to an already invoiced line
if so_line and so_line.state in ('done'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

('done', 'cancel')

def write(self, vals):
for task in self:
if (vals.get('sale_line_id') and
task.sale_line_id.state in ('done')):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

('done', 'cancel')

line.product_uom_qty != 1.0):
raise ValidationError('Error! You cannot have more than one '
'"track_service" sold in one Sale Order '
'Line')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error message must be translatable

_('The quantity for 'Complete Task' products must be exactly one')

@api.constrains('product_id')
def _onchange_product_id(self):
for line in self:
if ('track_service' == line.product_id.track_service and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'complete_task' ?

@leemannd leemannd force-pushed the 10_add_sale_project_fixed_price_task_completed_invoicing branch 6 times, most recently from 54c7ca8 to f14b1bd Compare May 31, 2017 12:40
Copy link
Contributor

@simahawk simahawk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, but: some indentation error and above all, any tests?

def _need_procurement(self):
for product in self:
if (product.type == 'service' and
product.track_service == 'completed_task'):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix indentation

for task in self:
# We dont' want to modify when the related SOLine is invoiced
if (not task.sale_line_id or
task.sale_line_id.state in ('done', 'cancel')):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix indentation

def write(self, vals):
for task in self:
if (vals.get('sale_line_id') and
task.sale_line_id.state in ('done', 'cancel')):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again

@leemannd leemannd force-pushed the 10_add_sale_project_fixed_price_task_completed_invoicing branch from f14b1bd to c8b8583 Compare May 31, 2017 13:24
@leemannd leemannd force-pushed the 10_add_sale_project_fixed_price_task_completed_invoicing branch from c8b8583 to 66af3bd Compare May 31, 2017 13:24
@simahawk
Copy link
Contributor

BTW I'd say that "sale_project_fixed_price" would be enough for module name :)

@leemannd leemannd force-pushed the 10_add_sale_project_fixed_price_task_completed_invoicing branch 3 times, most recently from 44b83ea to 920fd90 Compare May 31, 2017 14:42
@leemannd
Copy link
Contributor Author

leemannd commented Jun 1, 2017

@pedrobaeza Hello, this is a base new module. The base code is set and the next days I'm building tests. Is is possible to have a first review/opinion about it?

@pedrobaeza
Copy link
Member

Well, not these days due to the Spanish Odoo days and the big queue I have after the code sprint, and it's not a current interest, but I suggest meanwhile to fix bots.

@leemannd leemannd force-pushed the 10_add_sale_project_fixed_price_task_completed_invoicing branch 7 times, most recently from f4a7892 to 7198e0a Compare June 2, 2017 12:31
@leemannd leemannd changed the title [WIP][10.0][ADD] Add sale_project_fixed_price_task_completed_invoicing [10.0][ADD] Add sale_project_fixed_price_task_completed_invoicing Jun 2, 2017
@leemannd leemannd force-pushed the 10_add_sale_project_fixed_price_task_completed_invoicing branch from 7198e0a to 93ea2e5 Compare June 2, 2017 12:50
@leemannd
Copy link
Contributor Author

leemannd commented Jun 2, 2017

In order to fix tests in local I had to change a module in project OCA/project#286
error seems related to tinyerp/erppeek#95 and odoo/odoo#17230

@leemannd leemannd force-pushed the 10_add_sale_project_fixed_price_task_completed_invoicing branch 4 times, most recently from cd6670a to 1448f8e Compare June 6, 2017 13:06
_inherit = 'sale.order.line'

@api.model
def create(self, vals):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's append if you create sale.order.line and then update product? and updated product has diferent track_service

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@angelmoya it works fine. This bit is only when you create a line in state 'sale' and not draft, although I'm not quite sure when this can happen. @leemannd can you enlighten us?

Copy link
Contributor Author

@leemannd leemannd Jun 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@angelmoya It takes the logic from sale_timesheet and overrides it in order to make it work with the new selection in line.product_id.track_service You'll find there the commit from odoo implementing it. odoo/odoo@9013074

Before this revision, a small function in sale was extended by
sale_timesheet to know when to (or not to) create an analytic
account for a SO.

This was nice, but since it was extended only in this module,
there's no real need for the added complexity (*reading
complexity*)

@gurneyalex
Copy link
Member

@rafaelbn Unless I'm mistaken, with the setting you propose, all the lines will be flagged as invoiceable in that setting, which means that when the sales try to create an invoice, all the lines with products invoiced based on sold quantity are there, regardless of the "delivered quantity" (i.e. the hours set on the timesheet).

Another difference is that with this the quantity sold and the hours on the timesheets are disconnected. Say you are selling a "milestone" with UOM = Unit and qty = 1 for a fixed price. It is annoying to have the qty delivered set to 100 (implicitely 'hours') on the sale order line.

I agree with you about the unsetting of 'invoiceable' when the related line has not yet been invoiced. @leemannd can you change this?

@gurneyalex
Copy link
Member

@rafaelbn @angelmoya thanks for taking the time to review the PR, by the way.

@rafaelbn
Copy link
Member

rafaelbn commented Jun 7, 2017

Fist of all, I would like to help because I'm sales manager in Tecnativa and I have same headache as the one who need this solution. "Invoice sales order when the task are flagged to be invoiced independently the quantity". As I'm also project manager, I really would like to get for OCA a solution with a general approach! 🙏 🤞

@rafaelbn Unless I'm mistaken, with the setting you propose, all the lines will be flagged as invoiceable in that setting,

Hi @gurneyalex , you are mistaken 😄 . Each sale order line is related with a task so only will be flagged as invoiceable the lines of the task that the "task user" has flagged. If you have 4 sale order lines, then you have 4 tasks and maybe you only set 1 of 4 to invoiceable.

  • One objetive set: The possibility of flag in the tasks when they become invoiceable and transfer this flag to the sale order line related. This objective is independent of "Invoicing policy".

which means that when the sales try to create an invoice, all the lines with products invoiced based on sold quantity are there, regardless of the "delivered quantity" (i.e. the hours set on the timesheet).

  • The objetive is that when the sales try to create an invoice, only the sale order lines which are flagged as invoiceable will be in the invoice
  • How many? Quantity? Just ordered!! (not the hours set on the timesheets) or just delivered!! here depends on "Invoice policy".

I really wish that you are getting my idea in this point to simplify. Trust me I have all cases 😭

Another difference is that with this the quantity sold and the hours on the timesheets are disconnected. Say you are selling a "milestone" with UOM = Unit and qty = 1 for a fixed price. It is annoying to have the qty delivered set to 100 (implicitly 'hours') on the sale order line.

YES! You can send a quotation of 20 hours or just 1 unit of Training (maybe 20, maybe 30 hours) This case in my side is (but of course could be improved in Odoo/OCA):

  • A product with ordered qty policy. 1 unit with cost 3000€ for ex. When I confirm sale order Odoo creates a task of 1. Then you work and spend 100 hours but when you go to invoice Odoo just invoice for you 1 unit of 3000€ and not 100 hours. Here will help a lot ! this module because the user which set this task as invoiveable indicate to me (sales man) that I can invoice. And I don't mind how many hours! just what it's in quotation. Is very simple!

I agree with you about the unsetting of 'invoiceable' when the related line has not yet been invoiced. @leemannd can you change this?

I open to make a hangout or similar with you to explain it if you consider it 😃

I just would like to cover this need as simple as possible

Thanks!

@leemannd
Copy link
Contributor Author

leemannd commented Jun 7, 2017

@rafaelbn @gurneyalex You can now unset 'invoiceable' on tasks when the sale.order.line is not shipped.
@rafaelbn Thanks for the review and the propositions.

@leemannd leemannd force-pushed the 10_add_sale_project_fixed_price_task_completed_invoicing branch from 1448f8e to 80c99c9 Compare June 7, 2017 15:37
Copy link
Member

@guewen guewen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(only code review)

@sergio-teruel
Copy link
Contributor

Can you look at this approach?
#500
Would there be any use cases that are not covered?

@leemannd
Copy link
Contributor Author

@sergio-teruel I looked at it and seems pretty nice work. As I don't have the full specs from @gurneyalex I must wait for his opinion about it.

@gurneyalex
Copy link
Member

@sergio-teruel I gave your module a look. I see two issues there:

  1. the definition of 'finished' : you module seems to use "in a stage with folded = True" which is debatable (could have cancelled tasks in there for instance)
  2. sometimes you want to flag as invoiceable something which is not 'finished', which is why I used a different concept when I wrote the specification of the module in [10.0][ADD] Add sale_project_fixed_price_task_completed_invoicing #485 : it lets the project manager flag the task as invoiceable, and then the invoicing / sales people will generate an invoice with the correct amount.

A typical example could be : you have a milestone for a project which was delivered, in a QA instance, and your customer is taking a lot of time to validate the milestone. In this case you could have the task not done (it is not in production), but you still want to invoice the work.

Copy link

@didierdonze didierdonze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the great work. From a business point of view, I approve the functionality.

@sergio-teruel
Copy link
Contributor

@gurneyalex Ok, I understand and I have made changes, can you take a look? Thanks.
This is the commit: 0318a02

@leemannd
Copy link
Contributor Author

@gurneyalex @pedrobaeza Hello, as reviews are done, is it possible to have this PR merged? Thank you.

@carlosdauden
Copy link
Contributor

Will we finally have two modules to cover the same need?
#500

@gurneyalex
Copy link
Member

I discussed this with @rafaelbn and @sergio-teruel => #500 suits my needs and covers an additional use case I don't have but they do => I'll close this PR in favor of #500 once I've updated the customers who need it.

@pedrobaeza
Copy link
Member

Can we finally close this?

@leemannd
Copy link
Contributor Author

leemannd commented Oct 1, 2018

@pedrobaeza Yes, I'm closing it

@leemannd leemannd closed this Oct 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants