-
Notifications
You must be signed in to change notification settings - Fork 4
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
Added Multi company support #16
Added Multi company support #16
Conversation
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.
Thanks for this contrib!
mis_builder/models/aep.py
Outdated
def __init__(self, company): | ||
self.company = company | ||
self.dp = company.currency_id.decimal_places | ||
def __init__(self, company_ids=None, currency_id=None): |
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 you name that companies
instead of company_ids
.
mis_builder/models/aep.py
Outdated
else: | ||
aml_model = self.company.env[aml_model] | ||
aml_model = self.company_ids[0].env[aml_model] |
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.
self.companies.env[aml_model]
: [0]
is not needed
mis_builder/models/aep.py
Outdated
[self.env.user.company_id] | ||
self.currency_id = currency_id and currency_id or \ | ||
self.env.user.company_id.currency_id | ||
self.dp = self.currency_id.decimal_places |
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.
Could you keep the currency stuff in separate commits? So we different commit(s) for multi company and multi currency and a clean commit history.
mis_builder/models/aep.py
Outdated
@@ -238,7 +241,7 @@ def get_aml_domain_for_dates(self, date_from, date_to, | |||
elif mode == self.MODE_UNALLOCATED: | |||
date_from_date = fields.Date.from_string(date_from) | |||
fy_date_from = \ | |||
self.company.\ | |||
self.company_ids[0].\ |
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.
Hm. Here it's a special treatment for the first company. This could lead to surprises.
Could you extract the fy_date_from
computation in a separate method and add a check (raise UserError) that all companies have the same fy_date_from
? Later we can add logic to handle companies with different fiscal years.
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 can see some border effects when company is located in Australia with GMT +12, but this can be fixed.
However don't you think that for this particular case (at least) the main company (or user.company_id) is useful?
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 could be useful to have a main company but not in AEP. Perhaps in mis_report_instance. But even that I'm not sure and I certainly have not studied the impact of having different fiscal years on the computation of consolidated initial balances... Until that is clarified I prefer to raise an error if the various companies have different fiscal year dates.
help='Select companies for which data will be searched. \ | ||
User\'s company if empty.', | ||
default=_default_company_ids, | ||
required=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.
Could you use this style for new/modified fields?
company_ids = fields.Many2many(
comodel_name='res.company',
string='Company',
help='Select companies for which data will be searched. '
'User\'s company if empty.',
default=_default_company_ids,
required=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.
A migration script is needed.
default=_default_company_ids, | ||
required=False) | ||
currency_id = fields.Many2one('res.currency', 'Currency', | ||
required=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.
Could you please do multi currency in another PR?
_company_default_get('mis.report.instance') | ||
def _default_company_ids(self): | ||
return [(6,0,[self.env['res.company'].\ | ||
_company_default_get('mis.report.instance').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.
flake8 will complain here
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'm wondering if return _company_default_get('mis.report.instance')
would work too?
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'm wondering if return _company_default_get('mis.report.instance') would work too?
That's what I was using first, but there were a json complaint about res.company not serialisable.
Why flake8 will complain?
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.
flake8 requires a space after commas
Can you add a new test for multi-company AEP? |
mis_builder/tests/test_aep.py
Outdated
time.strftime('%Y') + '-03-31', | ||
'posted') | ||
self.assertEquals(end, { | ||
self.account_ar.id: (900, 0), | ||
self.account_in.id: (0, 800), | ||
}) | ||
unallocated = AEP.get_unallocated_pl( | ||
self.company, | ||
self.company_ids, |
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.
test_aep.py
should be unchanged: existing tests in this file should continue to work without change.
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.
So you the the AEP init method shoud accept company and companies as first argument and I shoud add check whether theare are one or many companies passed?
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 I mean is that for Odoo, a recordset of 1 is still a recordset, and create
returns a recordset of 1. So these tests can remain unmodified and work normally even if AEP.__init__
accept companies as argument.
Even if currency support is in a separate request, we still need to choose a main currency for total amounts calculation as account.move.lines might be in different currencies. EDITED : This PR |
Regarding this PR, a few things remain todo before merging;
Regarding multi-currency I would not worry too much with the display issue: we currently do it with a suffix/prefix in the styles, it does the job. Doing the currency conversion in an efficient manner is the key problem to resolve. |
Please please do the currency conversion in another pull request so this one remains reasonably small and easy to review. |
I've added a basic currency conversion of amounts to the main currency. |
mis_builder/models/aep.py
Outdated
# in initial mode, ignore accounts with 0 balance | ||
continue | ||
self._data[key][acc['account_id'][0]] = (debit, credit) | ||
if company.currency_id != self.currency_id: | ||
rate = self.currency_id.rate / company.currency_id.rate |
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.
The basic implementation is quite simple.
Get the account for the line, get its company. If account company currency is not the same as APE currency, do the conversion (using current rate for now)
mis_builder/models/aep.py
Outdated
@@ -281,14 +284,20 @@ def do_queries(self, date_from, date_to, | |||
['debit', 'credit', 'account_id'], | |||
['account_id']) | |||
for acc in accs: | |||
company = account_model.browse(acc['account_id'][0]).company_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 browse inside the loop is bad for performance.
I suggest:
- fetching and computing currency rates by company at the beginning of the method, outside of the loops, store that in a dictionary
- adding company_id in the read_group
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.
Yes good idea!
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 do you think about the precision rounding in float_is_zero method ? should it be company currency rounding or AEP currency rounding?
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.dp, which should come from the target currency.
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.
But if target currency is CHF which is 0.5 rounding and we're getting amounts in EUR which rounding is 0.1, won't we miss some amounts? That could be problematic especially if there are many amounts with 0.1 or 0.2 ?
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.
Hm. Indeed this float_compare occurs before currency conversion, so you are probably right, yes.
mis_builder/models/aep.py
Outdated
def __init__(self, companies, currency_id=None): | ||
self.companies = companies | ||
self.currency_id = currency_id and currency_id or \ | ||
self.companies.env.user.company_id.currency_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.
here, raise UserError if currency_id is not set and companies don't have all the same currency
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.
Ok, but we might also consider that user wants to see the amounts in his own currency by default. But then we would need the Monetary cell as if not set, the traget currency depends on user
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.
In that case the user will specify the currency explicitly in mis_report_instance.
AEP is a low level API, and I want it to have as little implicit behaviour as possible.
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.
Ok, that's a good reason.
TODO: Migration
There is missing some functionalities to have this 100% usable, at least:
|
I think we are ready to add the currency_id field to mis report instance? |
Yes, now that all the multi-currency logic in AEP is in this branch, it's a small change to add curency_id in mis_report_instance in this PR. |
SELECT id as mis_report_instance_id, | ||
company_id as res_company_id | ||
FROM mis_report_instance; | ||
""") |
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.
Hm that's a lot of code.
Better use openupgradelib for this: https://github.com/OCA/openupgradelib/blob/master/openupgradelib/openupgrade.py#L789
Also bump version to 10.0.3.1.0 and make a different migration directory for that.
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.
So much simpler, thank you for remind me the openupgrade
I think we should add company_ids to mis.report.instance.period and if not null, add the company filter to We might better add company_ids filter field to sub kpi filter |
Thanks a lot for your work! I've too little time to finalize the review and merge now, but I keep an eye on this and will do as soon as I can. |
Please check also this PR |
2803bb3
to
14b7f5e
Compare
@Martronic-SA Thanks for your contributions and patience. I'm now back working on this and I'm planning to do a release with as many new features as possible before end of september. I'll now flesh out the tests a little bit and merge at least some parts of this multi company PR. Could you rebase it on OCA#275 ? |
@sbidoul I'm back from holidays. |
0ea81c3
to
6fa52b5
Compare
Here is a rough rebasing procedure:
|
@Martronic-SA will you be at the OCA code sprint in Louvain-la-Neuve? |
b77bcb5
to
d38052e
Compare
Small flake8 corrections
Added multi company test (still missing multi currency test)
Fix Tests complain about absolute import
Added specific method for rates computation
ad33d5d
to
cdf6cfc
Compare
Thank you very much for the procedure. |
@Martronic-SA could you review OCA#275 ? We'll merge that first then move on with your other PRs. |
I think everything is fine with OCA#275. ok for me! |
Can write your approval there? |
I'm currently moving this PR to OCA/mis-builder. |
Moved to OCA/mis-builder#23 |
Could you check this?
I've added company_ids and currency_id in MIS report instance.
For the moment, the rate calcuation is not implemented (will be soon).