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] cooperator: Refactor cooperative.membership preparation code #101

Merged
merged 3 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 2 additions & 70 deletions cooperator/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,46 +31,6 @@ def _get_starting_sequence(self):
starting_sequence = "R" + starting_sequence
return starting_sequence

def create_user(self, partner):
user_obj = self.env["res.users"]
email = partner.email

user = user_obj.search([("login", "=", email)])
if user:
if self.company_id not in user.company_ids:
# add the company to the user's companies
user.company_ids = [(4, self.company_id.id, 0)]
else:
# set the company as the only company of the user
company_ids = [(6, 0, [self.company_id.id])]
user = user_obj.search([("login", "=", email), ("active", "=", False)])
if user:
user.sudo().write(
{
"active": True,
"company_id": self.company_id.id,
"company_ids": company_ids,
}
)
else:
user_values = {
"partner_id": partner.id,
"login": email,
}
user = user_obj.sudo()._signup_create_user(user_values)
# passing these values in _signup_create_user() does not work
# if the website module is loaded, because it overrides the
# method and overwrites them.
user.sudo().write(
{
"company_id": self.company_id.id,
"company_ids": company_ids,
}
)
user.sudo().with_context(create_user=True).action_reset_password()

return user

def get_mail_template_certificate(self):
if self.partner_id.member:
return self.company_id.get_cooperator_certificate_increase_mail_template()
Expand All @@ -97,31 +57,6 @@ def get_subscription_register_vals(self, line, effective_date):
"company_id": self.company_id.id,
}

def get_membership_vals(self):
# flag the partner as an effective member
# if not yet cooperator we generate a cooperator number
vals = {}
cooperative_membership = self.partner_id.get_cooperative_membership(
self.company_id.id
)
if not cooperative_membership.member and not cooperative_membership.old_member:
sub_reg_num = self.company_id.get_next_cooperator_number()
vals = {
"member": True,
"old_member": False,
"cooperator_register_number": int(sub_reg_num),
}
elif cooperative_membership.old_member:
vals = {"member": True, "old_member": False}

return vals

def set_membership(self):
vals = self.get_membership_vals()
self.partner_id.get_cooperative_membership(self.company_id.id).write(vals)

return True

def _send_certificate_mail(self, certificate_email_template, sub_reg_line):
if self.company_id.send_certificate_email:
# we send the email with the certificate in attachment
Expand All @@ -135,7 +70,7 @@ def set_cooperator_effective(self, effective_date):

certificate_email_template = self.get_mail_template_certificate()

self.set_membership()
self.partner_id.get_cooperative_membership(self.company_id).set_effective()

sub_reg_operation = self.company_id.get_next_register_operation_number()

Expand All @@ -154,9 +89,6 @@ def set_cooperator_effective(self, effective_date):

self._send_certificate_mail(certificate_email_template, sub_reg_line)
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'm a bit confused by this. Does this assume that the for-loop has one item?


if self.company_id.create_user:
self.create_user(self.partner_id)

return True

def post_process_confirm_paid(self, effective_date):
Expand All @@ -181,7 +113,7 @@ def _invoice_paid_hook(self):
result = super()._invoice_paid_hook()
for invoice in self:
cooperative_membership = invoice.partner_id.get_cooperative_membership(
invoice.company_id.id
invoice.company_id
)
if not (
invoice.move_type == "out_invoice"
Expand Down
80 changes: 80 additions & 0 deletions cooperator/models/cooperative_membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,83 @@ def get_share_quantities(self):
total_shares[line.share_product_id.id] += line.share_number

return total_shares

def set_effective(self):
"""Make sure the following things are in order for all memberships in
the recordset:

- ``member`` is set to True and ``old_member`` is set to False.
- A cooperator register number is assigned if one did not yet exist.
- A user is created if one did not yet exist.

This should all be idempotent.
"""
self.write({"member": True, "old_member": False})
self.assign_cooperator_register_number()
for membership in self:
if membership.company_id.create_user:
membership.create_user()

def assign_cooperator_register_number(self):
"""Set a new cooperator register number on the memberships if one is not
already assigned.
"""
for membership in self:
# Already exists; nothing to do.
if membership.cooperator_register_number:
continue
membership.cooperator_register_number = (
self.company_id.get_next_cooperator_number()
)

def create_user(self):
"""Create a new user for the memberships if one does not already exist.

If a user exists, but its 'active' field is False, then the user is
reactivated and the membership's company_id becomes the user's only
company_id.

If a new partner is created, an e-mail is sent to them with instructions
on how to set their passport.
"""
user_obj = self.env["res.users"].sudo()

for membership in self:
partner = membership.partner_id
email = partner.email

users = user_obj.with_context(active_test=False).search(
[("partner_id", "=", partner.id)]
)
if users:
inactive = users.filtered(lambda user: not user.active)
active = users - inactive
inactive.write(
{
"active": True,
# set the company as the only company of the user for
# returning users
"company_id": membership.company_id.id,
"company_ids": [fields.Command.set([membership.company_id.id])],
}
)
active.write(
# add the company to the users' companies
{"company_ids": [fields.Command.link(membership.company_id.id)]}
)
else:
user_values = {
"partner_id": partner.id,
"login": email,
}
user = user_obj._signup_create_user(user_values)
# passing these values in _signup_create_user() does not work
# if the website module is loaded, because it overrides the
# method and overwrites them.
user.write(
{
"company_id": membership.company_id.id,
"company_ids": [fields.Command.set([membership.company_id.id])],
}
)
user.with_context(create_user=True).action_reset_password()
33 changes: 9 additions & 24 deletions cooperator/models/operation_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,34 +367,19 @@ def execute_operation(self):
_("Converting just part of the shares is not yet implemented")
)
elif self.operation_type == "transfer":
partner_vals = {"member": True}
if self.receiver_not_member:
partner = self.subscription_request.setup_partner()
self.subscription_request.state = "done"
cooperator_number = self.company_id.get_next_cooperator_number()
# fixme: get_eater_vals() is really specific and should not be
# called from here.
partner_vals.update(
sub_request.get_eater_vals(partner, self.share_product_id)
)
partner_vals["cooperator_register_number"] = cooperator_number
partner.write(partner_vals)
self.partner_id_to = partner
else:
# means an old member or cooperator candidate
if not self.partner_id_to.member:
if self.partner_id_to.cooperator_register_number == 0:
cooperator_number = self.company_id.get_next_cooperator_number()
partner_vals["cooperator_register_number"] = cooperator_number
# fixme: get_eater_vals() is really specific and should
# not be called from here.
partner_vals.update(
sub_request.get_eater_vals(
self.partner_id_to, self.share_product_id
)
)
partner_vals["old_member"] = False
self.partner_id_to.write(partner_vals)
to_membership = self.partner_id_to.get_cooperative_membership(
self.company_id
)
to_membership.set_effective()
self.partner_id_to.write(
# FIXME: get_eater_vals() is really specific and should not be
# called from here.
sub_request.get_eater_vals(self.partner_id_to, self.share_product_id)
)
# remove the parts to the giver
self.hand_share_over(self.partner_id, self.share_product_id, self.quantity)
# give the share to the receiver
Expand Down
15 changes: 11 additions & 4 deletions cooperator/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def _get_share_type(self):

@api.depends_context("company")
def _compute_cooperative_membership_id(self):
company_id = self.env.company.id
company_id = self.env.company
for record in self:
record.cooperative_membership_id = record.get_cooperative_membership(
company_id
Expand Down Expand Up @@ -268,7 +268,7 @@ def get_cooperative_membership(self, company_id):
self.ensure_one()
return self.env["cooperative.membership"].search(
[
("company_id", "=", company_id),
("company_id", "=", company_id.id),
("partner_id", "=", self.id),
]
)
Expand All @@ -279,13 +279,20 @@ def create_cooperative_membership(self, company_id):
for record in self:
result |= cooperative_membership_model.create(
{
"company_id": company_id,
"company_id": company_id.id,
"partner_id": record.id,
"cooperator": True,
}
)
return result

def get_create_cooperative_membership(self, company_id):
self.ensure_one()
membership = self.get_cooperative_membership(company_id)
if not membership:
membership = self.create_cooperative_membership(company_id)
return membership

def get_share_quantities(self, company_id=None):
"""Return a defaultdict(int) with the amount of shares per product id,
for the partner's cooperative_membership_id.
Expand All @@ -298,7 +305,7 @@ def get_share_quantities(self, company_id=None):
if company_id is None:
company_id = self.env.company

coop_membership = self.get_cooperative_membership(company_id.id)
coop_membership = self.get_cooperative_membership(company_id)
if coop_membership:
return coop_membership.get_share_quantities()
else:
Expand Down
13 changes: 6 additions & 7 deletions cooperator/models/subscription_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,11 @@ def _adapt_create_vals_and_membership_from_partner(self, vals, partner):
update it if needed and set vals accordingly.
"""
company_id = vals.get("company_id", self.env.company.id)
company_id = self.env["res.company"].browse(company_id)
cooperative_membership = partner.get_cooperative_membership(company_id)
member = cooperative_membership and cooperative_membership.member
pending_requests_domain = [
("company_id", "=", company_id),
("company_id", "=", company_id.id),
("partner_id", "=", partner.id),
("state", "in", ("draft", "waiting", "done")),
]
Expand Down Expand Up @@ -819,12 +820,10 @@ def setup_partner(self):

partner = self._find_or_create_partner()

cooperative_membership = partner.get_cooperative_membership(self.company_id.id)
if not cooperative_membership:
cooperative_membership = partner.create_cooperative_membership(
self.company_id.id
)
elif not cooperative_membership.cooperator:
cooperative_membership = partner.get_create_cooperative_membership(
self.company_id
)
if not cooperative_membership.cooperator:
cooperative_membership.cooperator = True

if self.is_company and not partner.has_representative():
Expand Down
Loading
Loading