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

[16.0][MIG] cooperator: migration to 16.0 #86

Merged
merged 735 commits into from
Nov 29, 2023

Conversation

huguesdk
Copy link
Member

No description provided.

robinkeunen and others added 30 commits August 14, 2023 17:31
- remove coop_candidates from cooperators kanban view
- keep only coop_candidates in coop_candidates view
- remove legal reprentative in both
Signed-off-by: Carmen Bianca Bakker <[email protected]>
Signed-off-by: Carmen Bianca Bakker <[email protected]>
- refactor the form using templates
- simplify the design:
    - replace tables by bootstrap columns
    - use columns for the overall form rather than for individual fields
- use HTML5 widgets for the Part Numbers
- use adequate bootstrap classes
- use HTML5 date widget
fix incorrect call to ._get_share_transfer_mail_template() that was
forgotten during the recent correction of "transfert" to "transfer".
* make subscription.request.name a stored computed field to allow to
  search by any part of the full name.
* fix subscription request views: use only firstname and lastname.
Previously, if either firstname or lastname was (unexpectedly) empty, an
error would be thrown.

This commit uses approximately the same code approach as
partner-contact/partner_firstname to compute the full name.

Signed-off-by: Carmen Bianca Bakker <[email protected]>
fix error that happens when creating a company contact with a
sub-contact.
fix creation of subscription request from partner by adding missing
fields: firstname, lastname and lang.
Don't use value from self when looping over a list

Signed-off-by: Carmen Bianca Bakker <[email protected]>
@huguesdk
Copy link
Member Author

@polchampion: my answers below:

  • Can be used with multi-company configuration --> NOK

error : can't validate multicompany share request
I added a company ("deuxième structure"), an cooperative accounting account on company two, a subscription journal (though shouldn't it be created automatically for company two?), a share product for company two. I then tried to validate this draft subscription request.

The operation cannot be completed:

  • Create/update: a mandatory field is not set.
  • Delete: another model requires the record being deleted. If possible, archive it instead.

Model: Journal Entry (account.move)
Field: Journal (journal_id)

this is because the company has no subscription journal. it is created automatically when a chart of account is configured on the company (settings > invoicing > fiscale localization > package).

  • Generate Cooperator Certificate and several reports about cooperators --> button missing to print cooperators register
    error : no way to print cooperators register - button missing in 'print' menu

screenshot-odoo16 main test srv coopiteasy be-2023 11 20-16_48_46

this has moved: it is now available from the cooperator register (registers > cooperator register).

  • Click "create subscription request" button on partner --> Still NOK, same error as below

error on this partner, though worked on another

RPC_ERROR
Odoo Server Error
Traceback (most recent call last):
  File "/home/odoo16/src/odoo/odoo/http.py", line 1584, in _serve_db
    return service_model.retrying(self._serve_ir_http, self.env)
  File "/home/odoo16/src/odoo/odoo/service/model.py", line 133, in retrying
    result = func()
  File "/home/odoo16/src/odoo/odoo/http.py", line 1611, in _serve_ir_http
    response = self.dispatcher.dispatch(rule.endpoint, args)
  File "/home/odoo16/src/odoo/odoo/http.py", line 1815, in dispatch
    result = self.request.registry['ir.http']._dispatch(endpoint)
  File "/home/odoo16/src/odoo/odoo/addons/base/models/ir_http.py", line 154, in _dispatch
    result = endpoint(**request.params)
  File "/home/odoo16/src/odoo/odoo/http.py", line 697, in route_wrapper
    result = endpoint(self, *args, **params_ok)
  File "/home/odoo16/src/odoo/addons/web/controllers/dataset.py", line 42, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "/home/odoo16/src/odoo/addons/web/controllers/dataset.py", line 33, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/home/odoo16/src/odoo/odoo/api.py", line 461, in call_kw
    result = _call_kw_multi(method, model, args, kwargs)
  File "/home/odoo16/src/odoo/odoo/api.py", line 448, in _call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/home/odoo16/src/odoo/odoo/models.py", line 6401, in onchange
    defaults = self.default_get(missing_names)
  File "/home/odoo16/src/odoo/odoo/models.py", line 1392, in default_get
    defaults[name] = field.default(self)
  File "/home/odoo16/src/oca/cooperative/cooperator/wizard/partner_create_subscription.py", line 33, in _default_product_id
    return self.env["product.product"].search(domain)[0]
  File "/home/odoo16/src/odoo/odoo/models.py", line 5895, in __getitem__
    return self.browse((self._ids[key],))
IndexError: tuple index out of range

The above server error caused the following client error:
null

this is because there are no configured share products available for companies. i added an error message in this case.

@huguesdk
Copy link
Member Author

huguesdk commented Nov 22, 2023

@polchampion: my answers below:

  • Can be used with multi-company configuration --> NOK

error : can't validate multicompany share request
I added a company ("deuxième structure"), an cooperative accounting account on company two, a subscription journal (though shouldn't it be created automatically for company two?), a share product for company two. I then tried to validate this draft subscription request.

The operation cannot be completed:

  • Create/update: a mandatory field is not set.
  • Delete: another model requires the record being deleted. If possible, archive it instead.

Model: Journal Entry (account.move)
Field: Journal (journal_id)

this is because the company has no subscription journal. it is created automatically when a chart of account is configured on the company (settings > invoicing > fiscal localization > package).

  • Generate Cooperator Certificate and several reports about cooperators --> button missing to print cooperators register
    error : no way to print cooperators register - button missing in 'print' menu

screenshot-odoo16 main test srv coopiteasy be-2023 11 20-16_48_46

this has moved: it is now available from the cooperator register (registers > cooperator register).

  • Click "create subscription request" button on partner --> Still NOK, same error as below

error on this partner, though worked on another

RPC_ERROR
Odoo Server Error
Traceback (most recent call last):
  File "/home/odoo16/src/odoo/odoo/http.py", line 1584, in _serve_db
    return service_model.retrying(self._serve_ir_http, self.env)
  File "/home/odoo16/src/odoo/odoo/service/model.py", line 133, in retrying
    result = func()
  File "/home/odoo16/src/odoo/odoo/http.py", line 1611, in _serve_ir_http
    response = self.dispatcher.dispatch(rule.endpoint, args)
  File "/home/odoo16/src/odoo/odoo/http.py", line 1815, in dispatch
    result = self.request.registry['ir.http']._dispatch(endpoint)
  File "/home/odoo16/src/odoo/odoo/addons/base/models/ir_http.py", line 154, in _dispatch
    result = endpoint(**request.params)
  File "/home/odoo16/src/odoo/odoo/http.py", line 697, in route_wrapper
    result = endpoint(self, *args, **params_ok)
  File "/home/odoo16/src/odoo/addons/web/controllers/dataset.py", line 42, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "/home/odoo16/src/odoo/addons/web/controllers/dataset.py", line 33, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/home/odoo16/src/odoo/odoo/api.py", line 461, in call_kw
    result = _call_kw_multi(method, model, args, kwargs)
  File "/home/odoo16/src/odoo/odoo/api.py", line 448, in _call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/home/odoo16/src/odoo/odoo/models.py", line 6401, in onchange
    defaults = self.default_get(missing_names)
  File "/home/odoo16/src/odoo/odoo/models.py", line 1392, in default_get
    defaults[name] = field.default(self)
  File "/home/odoo16/src/oca/cooperative/cooperator/wizard/partner_create_subscription.py", line 33, in _default_product_id
    return self.env["product.product"].search(domain)[0]
  File "/home/odoo16/src/odoo/odoo/models.py", line 5895, in __getitem__
    return self.browse((self._ids[key],))
IndexError: tuple index out of range

The above server error caused the following client error:
null

this is because there are no configured share products available for this type of partner (a company in this case). there should be at least one product marked as “is share?” and “can be subscribed by companies?”. i added an error message in this case. (coopiteasy#4)

@huguesdk huguesdk marked this pull request as ready for review November 22, 2023 13:52
@huguesdk
Copy link
Member Author

i’ve split changes into separate commits for clarity. this branch is almost ready (still waiting for reviews or fixes on coopiteasy#3 and coopiteasy#4). the module version is currently set at version 16.0.0.1.0 instead of 16.0.1.0.0 to indicate that it is still being developed. before merging, the migration folder should be renamed to 16.0.1.0.0 (although it would still work with its current name). this branch should be merged as a major change. this will update the version to 16.0.1.0.0.

Copy link
Member

@carmenbianca carmenbianca left a comment

Choose a reason for hiding this comment

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

Some commentary. This looks like a huge undertaking otherwise. Well done @huguesdk !

Comment on lines 131 to 134
<t t-out="object.subscription_request_ids[0].firstname" />,
<t
t-if="object.is_company"
t-out="object.child_ids.filtered(lambda c: c.representative).firstname"
/>
<t t-else="" t-out="object.firstname" />,
Copy link
Member

Choose a reason for hiding this comment

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

This entire if-else section seems like it should be its own computed convenience field. Especially because it's repeated in this file.

Comment on lines 44 to 40
operation_type = fields.Selection(
[
("subscription", "Subscription"),
("transfer", "Transfer"),
("sell_back", "Sell Back"),
("convert", "Conversion"),
Copy link
Member

Choose a reason for hiding this comment

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

Does the removal of this selection option require a migration script?

Copy link
Member Author

Choose a reason for hiding this comment

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

i don’t think so, because it has never been implemented.

Comment on lines 100 to 104
# fixme: this field should be removed. it is only used for transfer
# operations just to hold the values to create a new partner from. using a
# subscription request for this causes several problems: it appears in the
# list of subscription requests while it is not a real one and it sends an
# email message to the receiver when it is created. instead, a partner
# should be created. the problem with using a partner, though, (besides
# creating a partner that might never be used if the the operation is
# never executed) is that it cannot hold the extra values coming from the
# subscription request and not stored on the partner or on the
# cooperative.membership, like the iban (is it the only one?). should we
# use a separate model that would be used here and in subscription.request
# (possibly as a mixin)?
subscription_request = fields.One2many(
Copy link
Member

Choose a reason for hiding this comment

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

imo subscription.request is an overused object throughout the cooperator codebase. It should just be an object that contains enough data to create a partner, an invoice, and share.lines, and is subsequently never referenced again. But it's used a lot in heaps of places.

I'm not sure what a good solution here is, though.

Copy link
Member Author

Choose a reason for hiding this comment

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

i totally agree with you.

Comment on lines 133 to 134
<t
t-if="object.is_company"
t-out="object.child_ids.filtered(lambda c: c.representative).firstname"
/>
<t t-if="object.is_company" t-out="object.get_representative().firstname" />
<t t-else="" t-out="object.firstname" />,
Copy link
Member

Choose a reason for hiding this comment

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

You almost read my mind! I still think this can be simplified into a single convenience field (or method) to get rid of the if-else :)

Copy link
Member Author

Choose a reason for hiding this comment

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

this is specific to mail templates related to the res.partner model. (for subscription requests, for instance, the firstname field can be used directly.) do you have a suggestion? what kind of field would you add? main_person_firstname? physical_person_firstname? or would you change the way the firstname field works for companies?

Comment on lines +131 to +144
if not record.subscription_request.is_operation:
raise ValidationError(
_(
"The is_operation field of the subscription "
"request must be true"
)
)
if record.subscription_request.source != "operation":
raise ValidationError(
_(
"The source field of the subscription request "
"must be set to operation"
)
)
Copy link
Member

Choose a reason for hiding this comment

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

Is this not testing the same thing twice? Is the second test really necessary?

Copy link
Member Author

Choose a reason for hiding this comment

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

good point. i’ve found that the fields is_operation, source (and state for transfer operations) were related to operations, and instead of changing the way subscription requests work, i added this here to make sure the ones used by operations are uniform. i think it would be a good idea to rethink these fields at some point.

Comment on lines +69 to +74
@api.constrains("email", "company_email")
def _check_company_and_representative_email_different(self):
for record in self:
if record.email == record.company_email:
raise ValidationError(_("Email and Company Email must be different."))

Copy link
Member

Choose a reason for hiding this comment

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

I'm not certain I like this constraint. I'm sure it solves a bug, but this seems like an incredibly silly restriction from the user's POV.

Copy link
Member Author

Choose a reason for hiding this comment

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

agreed, but that limitation exists already. this only makes the error message understandable. (see the internal task)

Copy link
Member Author

@huguesdk huguesdk 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 your re-review, @carmenbianca! here are my answers.

Comment on lines 44 to 40
operation_type = fields.Selection(
[
("subscription", "Subscription"),
("transfer", "Transfer"),
("sell_back", "Sell Back"),
("convert", "Conversion"),
Copy link
Member Author

Choose a reason for hiding this comment

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

i don’t think so, because it has never been implemented.

Comment on lines 100 to 104
# fixme: this field should be removed. it is only used for transfer
# operations just to hold the values to create a new partner from. using a
# subscription request for this causes several problems: it appears in the
# list of subscription requests while it is not a real one and it sends an
# email message to the receiver when it is created. instead, a partner
# should be created. the problem with using a partner, though, (besides
# creating a partner that might never be used if the the operation is
# never executed) is that it cannot hold the extra values coming from the
# subscription request and not stored on the partner or on the
# cooperative.membership, like the iban (is it the only one?). should we
# use a separate model that would be used here and in subscription.request
# (possibly as a mixin)?
subscription_request = fields.One2many(
Copy link
Member Author

Choose a reason for hiding this comment

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

i totally agree with you.

Comment on lines +131 to +144
if not record.subscription_request.is_operation:
raise ValidationError(
_(
"The is_operation field of the subscription "
"request must be true"
)
)
if record.subscription_request.source != "operation":
raise ValidationError(
_(
"The source field of the subscription request "
"must be set to operation"
)
)
Copy link
Member Author

Choose a reason for hiding this comment

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

good point. i’ve found that the fields is_operation, source (and state for transfer operations) were related to operations, and instead of changing the way subscription requests work, i added this here to make sure the ones used by operations are uniform. i think it would be a good idea to rethink these fields at some point.

Comment on lines +69 to +74
@api.constrains("email", "company_email")
def _check_company_and_representative_email_different(self):
for record in self:
if record.email == record.company_email:
raise ValidationError(_("Email and Company Email must be different."))

Copy link
Member Author

Choose a reason for hiding this comment

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

agreed, but that limitation exists already. this only makes the error message understandable. (see the internal task)

Comment on lines 133 to 134
<t
t-if="object.is_company"
t-out="object.child_ids.filtered(lambda c: c.representative).firstname"
/>
<t t-if="object.is_company" t-out="object.get_representative().firstname" />
<t t-else="" t-out="object.firstname" />,
Copy link
Member Author

Choose a reason for hiding this comment

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

this is specific to mail templates related to the res.partner model. (for subscription requests, for instance, the firstname field can be used directly.) do you have a suggestion? what kind of field would you add? main_person_firstname? physical_person_firstname? or would you change the way the firstname field works for companies?

@polchampion
Copy link

polchampion commented Nov 27, 2023

Functional test 4 - tested 27/11/2023 on 16-test-cooperator

Setup

  • Install the cooperator module
  • Create shares for individuals only, organisations only, and both
  • Define the cooperator accounting account (property_cooperator_account ) in the Company settings

Basic flow

  • Create subscription request for a person (moral or physical)
  • Validate subscription request, a capital release request (an invoice: account.move).
    This invoice is sent to the future cooperator.
  • Payment of the cooperator is registered and the capital Release
    request is marked as paid.
  • A new cooperator (a special partner) is created, and the right type
    and amount of share is linked to this new cooperator.
  • The new cooperator appears in the Cooperator Registry.

Features:

  • Manage several share types
  • Manage share subscription request
  • Cooperators can be individuals or companies
  • Get an up to date Cooperator Registry
  • See shares of a cooperator on the partner view
  • Manage departure of cooperators
  • Manage conversion between different share type
  • Send automatic mail to the future cooperator during the procedure
  • Can be used with multi-company configuration
  • Generate Cooperator Certificate and several reports about cooperators

Added features during test

  • Waiting list: add subscription request to waiting list which triggers an automatic email
  • Click "create subscription request" button on partner

Configurations:

  • on the company, set a default payment term for the capital release requests.
  • on the company, set the cooperator account.

@polchampion
Copy link

  • Click "create subscription request" button on partner --> Still NOK, same error as below

error on this partner, though worked on another

RPC_ERROR
Odoo Server Error
Traceback (most recent call last):
  File "/home/odoo16/src/odoo/odoo/http.py", line 1584, in _serve_db
    return service_model.retrying(self._serve_ir_http, self.env)
  File "/home/odoo16/src/odoo/odoo/service/model.py", line 133, in retrying
    result = func()
  File "/home/odoo16/src/odoo/odoo/http.py", line 1611, in _serve_ir_http
    response = self.dispatcher.dispatch(rule.endpoint, args)
  File "/home/odoo16/src/odoo/odoo/http.py", line 1815, in dispatch
    result = self.request.registry['ir.http']._dispatch(endpoint)
  File "/home/odoo16/src/odoo/odoo/addons/base/models/ir_http.py", line 154, in _dispatch
    result = endpoint(**request.params)
  File "/home/odoo16/src/odoo/odoo/http.py", line 697, in route_wrapper
    result = endpoint(self, *args, **params_ok)
  File "/home/odoo16/src/odoo/addons/web/controllers/dataset.py", line 42, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "/home/odoo16/src/odoo/addons/web/controllers/dataset.py", line 33, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/home/odoo16/src/odoo/odoo/api.py", line 461, in call_kw
    result = _call_kw_multi(method, model, args, kwargs)
  File "/home/odoo16/src/odoo/odoo/api.py", line 448, in _call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/home/odoo16/src/odoo/odoo/models.py", line 6401, in onchange
    defaults = self.default_get(missing_names)
  File "/home/odoo16/src/odoo/odoo/models.py", line 1392, in default_get
    defaults[name] = field.default(self)
  File "/home/odoo16/src/oca/cooperative/cooperator/wizard/partner_create_subscription.py", line 33, in _default_product_id
    return self.env["product.product"].search(domain)[0]
  File "/home/odoo16/src/odoo/odoo/models.py", line 5895, in __getitem__
    return self.browse((self._ids[key],))
IndexError: tuple index out of range

The above server error caused the following client error:
null

this is because there are no configured share products available for this type of partner (a company in this case). there should be at least one product marked as “is share?” and “can be subscribed by companies?”. i added an error message in this case. (coopiteasy#4)

@huguesdk There are two share product for My Company available for companies, plus this partner is already cooperator with one of the type of shares.

all other tests are ok !

@polchampion
Copy link

@huguesdk and one minor thing : the "subscription register" should be renamed "operation register", although that should be checked and followed with Cath, not here

@huguesdk
Copy link
Member Author

@polchampion

  • Click "create subscription request" button on partner --> Still NOK, same error as below

this is because there are no configured share products available for this type of partner (a company in this case). there should be at least one product marked as “is share?” and “can be subscribed by companies?”. i added an error message in this case. (coopiteasy#4)

@huguesdk There are two share product for My Company available for companies, plus this partner is already cooperator with one of the type of shares.

sorry, i forgot one condition: the default_share_product field of the share must also be true. with this, it works.

@huguesdk huguesdk force-pushed the 16.0-mig-cooperator branch 2 times, most recently from 98286eb to 772320b Compare November 28, 2023 12:26
@polchampion
Copy link

@polchampion

  • Click "create subscription request" button on partner --> Still NOK, same error as below

this is because there are no configured share products available for this type of partner (a company in this case). there should be at least one product marked as “is share?” and “can be subscribed by companies?”. i added an error message in this case. (coopiteasy#4)

@huguesdk There are two share product for My Company available for companies, plus this partner is already cooperator with one of the type of shares.

sorry, i forgot one condition: the default_share_product field of the share must also be true. with this, it works.

@huguesdk ok, I updated yesterday's test report, all good.
I added two items not in the original description though, it could be included in the module functionality list:

Waiting list: add subscription request to waiting list which triggers an automatic email
Click "create subscription request" button on partner

carmenbianca and others added 5 commits November 29, 2023 14:55
display an error message instead of failing when trying to create a
subscription request from a partner and no default share product is
found.
@huguesdk huguesdk force-pushed the 16.0-mig-cooperator branch 2 times, most recently from 3b56711 to 93ad7f6 Compare November 29, 2023 14:05
* update roadmap (contents and format).
* remove obsolete install fragment.
* fix link format in usage fragment.
@huguesdk
Copy link
Member Author

/ocabot merge major

@OCA-git-bot
Copy link
Contributor

Hey, thanks for contributing! Proceeding to merge this for you.
Prepared branch 16.0-ocabot-merge-pr-86-by-huguesdk-bump-major, awaiting test results.

@OCA-git-bot OCA-git-bot merged commit 27f2a66 into OCA:16.0 Nov 29, 2023
7 checks passed
@OCA-git-bot
Copy link
Contributor

Congratulations, your PR was merged at da48e0b. Thanks a lot for contributing to OCA. ❤️

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.