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

[IMP][8.0] pos_margin add margin_percent field and improve installation #207

Closed
wants to merge 6 commits into from

Conversation

legalsylvain
Copy link
Contributor

This PR :

  • add a new field margin_percent on pos order; (with a new decimal precision for this value)
  • display margin and margin percent on pos order tree and form view;
  • make installation faster, if data are present, using SQL request on pre_init_hook, instead of classical ORM;

Note:
This PR fixes purchase_price initialization because before this PR, purchase_price is based on the current purchase_price. (now is based on product_price_history value)

@legalsylvain legalsylvain added this to the 8.0 milestone Aug 23, 2017
@legalsylvain legalsylvain changed the title [IMP] pos_margin add margin_percent field and improve installation [IMP][8.0] pos_margin add margin_percent field and improve installation Aug 23, 2017
@legalsylvain
Copy link
Contributor Author

FYI, time reduction from 6 days -> ~2 hours for a DB with over 2 Millions of pos order line.

@pedrobaeza
Copy link
Member

What I don't like of these hooks is that there's different compute algorithm that on compute method. Isn't there any way to make faster the compute method using read_group or similar things? I will check for our module account_invoice_margin

@legalsylvain
Copy link
Contributor Author

hi @pedrobaeza , thanks for your review.

I'm not sure to understand "different compute algorithm".
Is it because SQL algorithm is based on history, and not the ORM one ? If yes, it could better to use history in the ORM method too.

Otherwise, I'd like to understand better your last comment.

@pedrobaeza
Copy link
Member

Yeah, that's it. We have 2 different pieces of code for making the same computation. We should remove the hook and make faster the compute method. I would like to avoid SQL querys anyway, and that's why I told you about read_group ORM method that is also efficient.

@legalsylvain
Copy link
Contributor Author

Yeah, that's it. We have 2 different pieces of code for making the same computation. We should remove the hook and make faster the compute method

I'm not agree with that point. For me it's like OpenUpgrade SQL script.

  • We add a new feature and we have a _compute function to compute new values.
  • In the meantime, we write an SQL Script to manage anteriority.

I'm ok that SQL scripts quantity should be limited, but in that case, it's interesting. We are talking about populating a huge table. (And furthermore the data "standard_price" is a property, so I guess that access is slower).

@pedrobaeza
Copy link
Member

@legalsylvain the problem is in the maintenance: you have to maintain 2 codes for the same thing. Imagine there's an error on one of them and not the other, and you are not aware of as some of your data has been populated on install and the rest by normal computation. It would be very difficult to debug and locate that.

Another example: you change the computation on one place, but not the other, and you have mixed results.

That's why I say to unify them on compute method. Sometimes that means to reduce a bit the performance, but we can get a balanced formula. We can even use SQL in the compute method if we don't find another way to get enough performance, but please, don't duplicate code (DRY principle).

@legalsylvain
Copy link
Contributor Author

Thanks for giving your point of view, I understand better, but i'm still not agree with you.

Well basically, I'm agree that duplicating algorithm generates more maintenance effort (for the good reasons you gave), and so should be limited. In the other hand, it is sometimes necessary. That's why a lot of existing OCA modules are containing exactly the same hooks as this one, to manage anteriority.

non exhausting list :

  • stock-logistics-warehouse / stock_valuation_account_manual_adjustment (explanation here)
  • stock-logistics-warehouse / stock_removal_location_by_priority
  • stock-logistics-workflow / stock_ownership_availability_rules
  • hr / hr_recruitment_partner
  • ...

Let ask to other OCA members, what they're thinking about that point.

Regards.

@sebastienbeau
Copy link
Member

After talking with @legalsylvain, We think that the solution is to set the purchase_price like a normal field (fill by an onchange) https://github.com/grap/pos/blob/e5b36985fddf3621b8282ec1b6270fd500a0a38b/pos_margin/models/pos_order_line.py#L19

Indeed this field do an historisation of the purchase price. Having a computed field will return a different value depending of the moment of computation. Which is dangerous because we can loss the data if the field is recomputed for some unknow reason later.

So basically the idea is to set purchase_price as a normal field and fill the historic with an SQL request.

[ADD] margin and margin_percent on pos_order tree view ;
[IMP] make faster installation on database with many pos_orders, using pre_init_hook
[FIX] remove compute method for pos_order_line.purchase_price, cortesy @sebastienbeau
@legalsylvain
Copy link
Contributor Author

Hi @sebastienbeau,

thanks a lot for your answer. I so changed purchase_price type from computed / store True to no computed, with onchange feature. It fixes the problem you mention about the different value, depending of the moment of the computation.
In that way the SQL script to compute purchase_price for anteriority is now not a duplicate of an ORM function.

I propose to let the trivial SQL script that compute margin and margin_percent fields, because :

  • they improve really installation time on huge databases
  • they have trivial algorithm and are stable (should not have to change)

I hope it will be acceptable.

kind regards.

def pre_init_hook(cr):
_logger.info("Compute pos_order_line.purchase_price for existing lines")
_create_column(cr, 'pos_order_line', 'purchase_price', 'numeric')
cr.execute("""
Copy link
Member

Choose a reason for hiding this comment

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

This can be performed without subquery (the same as in OpenUpgrade) and without the performance penalty it means. Do you figure out how to do it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not really, could you help me. I'm really not very good for update request.
Regards.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @pedrobaeza. Could we consider to merge this PR as it, and search some optimization. The subquery is not generating a big performance penalty. Otherwise, could you point me how to do ?
regards.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants