-
Notifications
You must be signed in to change notification settings - Fork 266
[18.0][MIG] fieldservice_account_analytic #1226
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
base: 18.0
Are you sure you want to change the base?
[18.0][MIG] fieldservice_account_analytic #1226
Conversation
|
/ocabot migration fieldservice_account_analytic |
d3e562e to
d48f879
Compare
|
/ocabot migration fieldservice_account_analytic |
6a59d33 to
50d20bf
Compare
50d20bf to
4a17d52
Compare
|
@EdgarRetes We need to create 3 analytic plans:
and:
When creating the customer invoice, vendor bill line or timesheet entry, we need to set the corresponding analytic account in each plan. We also need to activate the following settings/groups:
|
f0ef587 to
062bb59
Compare
52ad51f to
40d4df5
Compare
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: field-service-17.0/field-service-17.0-fieldservice_account_analytic Translate-URL: https://translation.odoo-community.org/projects/field-service-17-0/field-service-17-0-fieldservice_account_analytic/
e7f8bb5 to
849fdc4
Compare
849fdc4 to
5c93b75
Compare
4181c76 to
b7ce772
Compare
|
I think all the features around route can be moved to All the analytic features can be moved to |
Do you have any example of a repository that does this? |
|
@max3903 since the changes you're proposing are, if I'm not mistaken, refactoring of the actual logic and this PR is stale for a long time, don't you think we can postpone the refactoring to a later PR and prioritize the pure migration of the logic as-is? Also, this module not migrated 'blocks' the migration of fieldservice_isp_account. Do you think this could be feasible? Thanks |
|
Let me discuss it with @santiagordz and give it higher priority. |
Sorry if I bother you: have you had a chance to discuss it? |
Nope. @SMaciasOSI Can you get this in the todo list of @dcamacho20? |
Thanks for looking into it! We'll probably start anyway to migrate fieldservice_isp_account internally to 18.0 using this open PR as a dependency. |
|
Hello 👋 @EdgarRetes would you mind rebasing this PR? I suspect the CI will fail too: some modules have been merged meanwhile. |
ivantodorovich
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello 👋🏻 !
I just did a review commit by commit.
Some of my comments may be outdated, as the code is overwritten by following commits. However, the content is still valid in most cases.
Can you clean up a bit the commits, please?
I believe the changes are not atomic and well organized. If not possible, then it's better to squash everything into the migration commit and write a nice message describing the main changes.
Some things are blocking for me, like the addition of the new dependency, and the new init_hook.
| vals["account_id"] = order.location_id.analytic_account_id.id | ||
| else: | ||
| raise ValidationError( | ||
| _("No analytic account set " "on the order's Location.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use self.env._
| return super().create(vals) | ||
| @api.model_create_multi | ||
| def create(self, vals_list): | ||
| for vals in vals_list: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it was like this before, but please lets only loop if vals.get("fsm_order_id"), as it makes no sense to get into this iteration otherwise
|
|
||
|
|
||
| class AnalyticAccount(models.Model): | ||
| _inherit = "account.analytic.account" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we split this into two files: account_analytic_line.py and account_analytic_account.py ?
| _inherit = "account.analytic.account" | ||
|
|
||
| fsm_order_id = fields.One2many("fsm.order", "analytic_account_id", copy=False) | ||
| # route_id = fields.One2many("tms.route", "analytic_account_id", copy=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's with this commented out line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: This line is overwriten in a following commit.
Still: clearly commits are not atomic and require some cleaning
| { | ||
| "name": vals.get("name"), | ||
| "plan_id": self.env.ref( | ||
| "fieldservice_account_analytic.fsm_order_analytic_plan" | ||
| ).id, | ||
| "fsm_order_id": record, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move the vals preparation to a separate method. This makes it possible to easily override in other modules if needed. e.g: _prepare_analytic_account_vals
| "plan_id": self.env.ref( | ||
| "fieldservice_account_analytic.fsm_order_analytic_plan" | ||
| ).id, | ||
| "fsm_order_id": record, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set also the company_id and partner_id
| @api.model | ||
| def create(self, vals): | ||
| record = super().create(vals) | ||
| analytic_account = self.env["account.analytic.account"].create( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comments than the fsm.order model:
- use model_create_multi
- separate method for vals preparation
- create only if not explicitly set in vals
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
|
||
| from odoo import api, fields, models | ||
| from odoo import _, api, fields, models |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use self.env._ instead, everywhere
| "analytic", | ||
| "product", | ||
| "fieldservice_route", | ||
| "account_usability", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's with this new dependency?
| users = env["res.users"].search([]) | ||
|
|
||
| for user in users: | ||
| user.write({"groups_id": [(4, group_analytic_accounting.id)]}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not correct.
You can't just give this group to every user in the db
| <field name="name">account.analytic.line.fsm.manager</field> | ||
| <field name="model_id" ref="model_account_analytic_line" /> | ||
| <field name="global" eval="False" /> | ||
| <field name="domain_force">[(1, '=', 1)]</field> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is coming from previous versions, but it's not correct.
It grants too much power.
It should only grant access to lines having a fsm_order_id, IMO:
| <field name="domain_force">[(1, '=', 1)]</field> | |
| <field name="domain_force">[('fsm_order_id', '!=', False)]</field> |
| <field name="domain_force">[(1, '=', 1)]</field> | ||
| <field name="groups" eval="[(4, ref('fieldservice.group_fsm_dispatcher'))]" /> | ||
| <field name="perm_read" eval="True" /> | ||
| <field name="perm_write" eval="True" /> | ||
| <field name="perm_create" eval="True" /> | ||
| <field name="perm_unlink" eval="True" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as before, but it's also giving too much power.
The dispatcher should probably only see them, but I'm not sure if it should modify them 🤔
TBD
| <field name="domain_force">[(1, '=', 1)]</field> | |
| <field name="groups" eval="[(4, ref('fieldservice.group_fsm_dispatcher'))]" /> | |
| <field name="perm_read" eval="True" /> | |
| <field name="perm_write" eval="True" /> | |
| <field name="perm_create" eval="True" /> | |
| <field name="perm_unlink" eval="True" /> | |
| <field name="domain_force">[('fsm_order_id', '!=', False)]</field> | |
| <field name="groups" eval="[(4, ref('fieldservice.group_fsm_dispatcher'))]" /> | |
| <field name="perm_read" eval="True" /> | |
| <field name="perm_write" eval="False" /> | |
| <field name="perm_create" eval="False" /> | |
| <field name="perm_unlink" eval="False" /> |
| <field name="perm_create" eval="True" /> | ||
| <field name="perm_unlink" eval="True" /> | ||
| </record> | ||
| </odoo> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moreover, the user should be able to see and record his own timesheets
| </odoo> | |
| <record id="analytic_account_fsm_user" model="ir.rule"> | |
| <field name="name">account.analytic.line.fsm.user</field> | |
| <field name="model_id" ref="model_account_analytic_line" /> | |
| <field name="domain_force">[('fsm_order_id', '!=', False), ('user_id', '=', user.id)]</field> | |
| <field name="groups" eval="[Command.link(ref('fieldservice.group_fsm_user'))]" /> | |
| </record> | |
| </odoo> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file should be moved to security/
| @api.model_create_multi | ||
| def create(self, vals_list): | ||
| for vals in vals_list: | ||
| if vals.get("fsm_order_ids") and len(vals.get("fsm_order_ids")[0]) > 2: | ||
| fsm_orders = vals.get("fsm_order_ids")[0][2] | ||
| for order in self.env["fsm.order"].browse(fsm_orders).exists(): | ||
| if order.location_id.analytic_account_id: | ||
| vals["analytic_distribution"] = { | ||
| order.location_id.analytic_account_id.id: 100 | ||
| } | ||
| else: | ||
| raise ValidationError( | ||
| _("No analytic account " "set on the order's Location.") | ||
| ) | ||
| return super().create(vals_list) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be done in an override of _compute_analytic_distribution, instead of a create override.
| @api.onchange("product_id") | ||
| def onchange_product_id(self): | ||
| self.name = self.product_id.name if self.product_id else False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too invasive for other modules adding their own analytic lines.
I'm not sure we want this, anyway.
My recommendation would be to remove it.
And if we really want it, it shuold be limited only on those analytic.lines that have a fsm_order_id
| @api.onchange("product_id") | |
| def onchange_product_id(self): | |
| self.name = self.product_id.name if self.product_id else False |
| @api.model_create_multi | ||
| def create(self, vals_list): | ||
| record = super().create(vals_list) | ||
| if self.env.user.has_group("analytic.group_analytic_accounting"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't matter if the user creating the FSM order has access to accounting or not.
The behavior should be the same.
Moreover, the account should be created only if it's not already provided in the vals. Otherwise we'd be overwriting it.
| for vals in vals_list: | ||
| analytic_account = self.env["account.analytic.account"].create( | ||
| { | ||
| "name": vals.get("name"), | ||
| "plan_id": self.env.ref( | ||
| "fieldservice_account_analytic.fsm_location_analytic_plan" | ||
| ).id, | ||
| "fsm_location_id": record, | ||
| } | ||
| ) | ||
| record.analytic_account_id = analytic_account |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This for..loop is totally wrong.
It's looping through all the vals in vals_list, but for each iteration it's assigning the created analytic account to record (which in fact should be spelled records [plural]).
So, all the created records will end up with the same analytic account --> the one created for the last of them
@max3903