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

[15.0][ADD] subscription_oca #971

Merged
merged 1 commit into from
Sep 22, 2023

Conversation

carlos-domatix
Copy link
Contributor

This module allows creating subscriptions that generate recurring invoices or orders. It also enables the sale of products that generate subscriptions.

Copy link

@elvise elvise left a comment

Choose a reason for hiding this comment

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

LGTM!

@elvise
Copy link

elvise commented Jul 26, 2023

CC @francesco-ooops

@francesco-ooops
Copy link
Contributor

@OCA/project-service-maintainers this looks like a clean implementation as we're really struggling to handle customers' requests through the contract_ modules.

What do you think?


@api.model
def create(self, values):
return super().create(values)

Choose a reason for hiding this comment

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

I think you need to remove unused inheritance.

return super().create(values)

def write(self, values):
return super().write(values)

Choose a reason for hiding this comment

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

I think you need to remove unused inheritance.

def get_next_interval(self, type_interval, interval):
date_start = date.today()
if type_interval == "days":
date_start += relativedelta(days=+interval)

Choose a reason for hiding this comment

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

May be its better to write something like this for all cases:
date_start += relativedelta(**{ type_interval: interval })


@staticmethod
def string2datetime(string_date):
return datetime.strptime(string_date, ODOO_DATE_FORMAT)

Choose a reason for hiding this comment

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

For this operations you can use builtin to Date field methods
https://www.odoo.com/documentation/16.0/developer/reference/backend/orm.html#date-time-fields

)
elif self.template_id.recurring_rule_type == "years":
self.recurring_next_date = start_date + relativedelta(
years=+int(self.template_id.recurring_interval)

Choose a reason for hiding this comment

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

You can use previous example for such case

elif self.template_id.recurring_rule_type == "months":
date_string += relativedelta(months=+self.template_id.recurring_interval)
else:
date_string += relativedelta(years=+self.template_id.recurring_interval)

Choose a reason for hiding this comment

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

You can use previous example to make code shorter

else:
self.calculate_recurring_next_date(today)

def calculate_recurring_next_date(self, start_date):
Copy link
Contributor

Choose a reason for hiding this comment

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

@carlos-domatix For these kind of computations, have you looked at https://github.com/OCA/server-ux/tree/13.0/base_recurrence ?

That one could be useful to lower the amount of code here

Copy link
Contributor

Choose a reason for hiding this comment

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

@rousseldenis any chance to migrate it to 15? :)

Copy link
Contributor

Choose a reason for hiding this comment

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

@francesco-ooops Feel free to do it. It should be quite easy. But no time to do it now.

Copy link
Contributor

Choose a reason for hiding this comment

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

@carlos-domatix FYI we've migrated base_recurrence here, you can add a dependency to that PR to employ it here

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @carlos-domatix , just to say the migration is complete :)

@francesco-ooops
Copy link
Contributor

@carlos-domatix we'd like to get this merged soon so let us know if we can help in any way or pick up the task in case you don't have time to work on it ATM

Thank you!

@rafaelbn rafaelbn added this to the 15.0 milestone Jul 26, 2023
@rafaelbn
Copy link
Member

https://github.com/orgs/OCA/teams/project-service-maintainers this looks like a clean implementation as we're really struggling to handle customers' requests through the contract_ modules.

I agree. Quite 😢 in the change of contract in v12 that broke a simple ux module from Odoo 8 #207

👍🏼 Thank you!

@carlos-domatix
Copy link
Contributor Author

Thanks for the fixes and suggestions! I think I'll have some time next week to get all the changes done.

@elvise
Copy link

elvise commented Aug 2, 2023

Thanks for the fixes and suggestions! I think I'll have some time next week to get all the changes done.

@carlos-domatix any good news ? :)

@carlos-domatix carlos-domatix force-pushed the 15.0-add-subscription_oca branch 2 times, most recently from 68a14dd to 352b39d Compare August 6, 2023 10:35
@carlos-domatix
Copy link
Contributor Author

Changes made, except for the dependency on base_recurrence because using this module would result in losing functionality, such as the ability to bill every 15 days. You can make this change yourselves if you consider it necessary for the merge since I won't have much time available from now on.

@francesco-ooops
Copy link
Contributor

@rousseldenis good for you?

Copy link

@aayartsev aayartsev left a comment

Choose a reason for hiding this comment

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

Looks good

@francesco-ooops
Copy link
Contributor

@OCA/project-service-maintainers could this be merged?

it can be later improved to include dependency to base_recurrence if needed, but we'd like to start migration to v14 asap :)

@francesco-ooops
Copy link
Contributor

https://github.com/orgs/OCA/teams/project-service-maintainers this looks like a clean implementation as we're really struggling to handle customers' requests through the contract_ modules.

I agree. Quite 😢 in the change of contract in v12 that broke a simple ux module from Odoo 8 #207

👍🏼 Thank you!

@rafaelbn good for you?

Copy link

@simahawk simahawk 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 this big work 😄
Some remarks here and there.

One more: TBH I'm quite surprised to see a lot of code but no tests.
Sounds a bit scary to maintain, no?

date_start += relativedelta(**{type_interval: interval})
return date_start

def create_subscription(self, lines, template_id):

Choose a reason for hiding this comment

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

Suggested change
def create_subscription(self, lines, template_id):
def create_subscription(self, lines, subscription_tmpl):

subscription_lines.append((0, 0, line.get_subscription_line_values()))

if template_id:
sub_id = self.env["sale.subscription"].create(

Choose a reason for hiding this comment

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

Suggested change
sub_id = self.env["sale.subscription"].create(
rec [or sub] = self.env["sale.subscription"].create(

subscription_oca/models/sale_order.py Outdated Show resolved Hide resolved
subscription_oca/models/sale_order.py Outdated Show resolved Hide resolved
subscription_oca/models/sale_order.py Outdated Show resolved Hide resolved
subscription_oca/models/sale_subscription.py Outdated Show resolved Hide resolved
subscription_oca/models/sale_subscription.py Outdated Show resolved Hide resolved
subscription_oca/models/sale_subscription.py Outdated Show resolved Hide resolved
subscription_oca/models/sale_subscription_template.py Outdated Show resolved Hide resolved
subscription_oca/models/sale_subscription_template.py Outdated Show resolved Hide resolved
@francesco-ooops
Copy link
Contributor

@carlos-domatix if you don't have time to work on this, would you like for us to pick it up and bring it to merge? of course you'll remain the author of the module

@rafaelbn
Copy link
Member

I agree with @simahawk about test, It's not mandatory but bery recommended to maintain and prevent errors in the whole repository

🔴 Failing after 1s — 41.92% of diff hit (target 97.46%)

@rafaelbn
Copy link
Member

@francesco-ooops , august, so please wait a little bit more time to see if @carlos-domatix answer. Thank you!

compute="_compute_account_invoice_ids_count", string="Invoice Count"
)

limit_rule_count = fields.Integer(default=0, string="Subscription limit count")
Copy link
Contributor

Choose a reason for hiding this comment

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

AFAICS this is not used anyhwere...

@francesco-ooops
Copy link
Contributor

@carlos-domatix if you don't have time to work on this, would you like for us to pick it up and bring it to merge? of course you'll remain the author of the module

@carlos-domatix hi, waiting for your feedback in order to merge ASAP :)

@carlos-domatix
Copy link
Contributor Author

@carlos-domatix if you don't have time to work on this, would you like for us to pick it up and bring it to merge? of course you'll remain the author of the module

@carlos-domatix hi, waiting for your feedback in order to merge ASAP :)

I will try to find a place this week, although I doubt that I will be able to do the tests.

@francesco-ooops
Copy link
Contributor

@rafaelbn @simahawk ok for you if we add tests after merging the updated version with requested changes?

@rafaelbn
Copy link
Member

If @carlos-domatix don't know how to make test, and you @francesco-ooops know, let's go! But @simahawk comments should be attended please @carlos-domatix

This module remember me to the classic account_analytic_analysis_recurring backported by @YannickB long time ago... a really nice simple way to make recurring.

😄

@francesco-ooops
Copy link
Contributor

@carlos-domatix any good news?

@carlos-domatix
Copy link
Contributor Author

I would say that I have already made all the suggested changes. Sorry but there were many and right now we are quite busy with other matters.

On the other hand, we just received some direct comments with concerns about the license.
Right now, the subscribe application is managed on Odoo EE, however, we never used that code in order to create this module.
We started working on this on Odoo 11.0 several years ago and we decided to open the code now.

@francesco-ooops
Copy link
Contributor

@simahawk could you please review?

<field name="sequence">0</field>
<field name="type">pre</field>
<field name="description">
DEFAULT STAGE

Choose a reason for hiding this comment

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

is this "DEFAULT STAGE" wanted?
Also, wouldn't be better to flag them as noupdate?

Copy link
Contributor Author

@carlos-domatix carlos-domatix Sep 20, 2023

Choose a reason for hiding this comment

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

Yes, it is the first stage, why should it not exist?

It's inside <data noupdate="1">, I don't know what you mean.

Choose a reason for hiding this comment

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

ahh sorry, I've looked only at the top 😓

is this "DEFAULT STAGE" wanted?

I mean: why do you need this sentence in the description?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I delete it

<field name="name">The subscription is too expensive</field>
</record>

<record id="close_reason_expecs" model="sale.subscription.close.reason">

Choose a reason for hiding this comment

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

Suggested change
<record id="close_reason_expecs" model="sale.subscription.close.reason">
<record id="close_reason_requirement" model="sale.subscription.close.reason">

inverse_name="partner_id",
string="Subscriptions",
)
subscription_ids_count = fields.Integer(

Choose a reason for hiding this comment

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

Suggested change
subscription_ids_count = fields.Integer(
subscription_count = fields.Integer(

subscription_oca/models/sale_order.py Show resolved Hide resolved
try:
subscription.generate_invoice()
except Exception:
logger.exception("Error during Subscriptions Management cron")

Choose a reason for hiding this comment

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

Suggested change
logger.exception("Error during Subscriptions Management cron")
logger.exception("Error on subscription invoice generate")

if self.template_id.invoicing_mode == "invoice_send":
mail_template_id = self.template_id.invoice_mail_template_id
invoice_id.with_context(force_send=True).message_post_with_template(
mail_template_id.id,

Choose a reason for hiding this comment

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

Suggested change
mail_template_id.id,
mail_template.id,

Choose a reason for hiding this comment

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

well, apply to all the vars that are not ids but... records 😉

def write(self, values):
res = super().write(values)
if "stage_id" in values:
if self.stage_id:

Choose a reason for hiding this comment

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

this is broken if you have multiple records, no? 🔥

_description = "Subscription stage"
_order = "sequence, name, id"

@api.constrains("type")

Choose a reason for hiding this comment

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

methods go below fields

<notebook>
<page string="Invoicing">
<group>
<group>

Choose a reason for hiding this comment

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

please name at least inner groups

Comment on lines 15 to 17
sale_subscription_id = self.env["sale.subscription"].search(
[("id", "=", self.env.context["active_id"])]
)

Choose a reason for hiding this comment

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

why searching when you have it?

Suggested change
sale_subscription_id = self.env["sale.subscription"].search(
[("id", "=", self.env.context["active_id"])]
)
sale_subscription = self.env["sale.subscription"].browse(self.env.context["active_id"])

@francesco-ooops
Copy link
Contributor

@simahawk appreciate it!

@carlos-domatix
Copy link
Contributor Author

@simahawk Thanks for the suggestions, I'll do it as soon as possible.

@carlos-domatix
Copy link
Contributor Author

Changes made, I hope everything is there.

@simahawk
Copy link

@elvise @francesco-ooops good for you from functional perspective after all these changes? I have no time to test on my side 😉

@simahawk simahawk self-requested a review September 21, 2023 05:16
Copy link

@simahawk simahawk left a comment

Choose a reason for hiding this comment

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

LG, just code review

@elvise
Copy link

elvise commented Sep 21, 2023

@elvise @francesco-ooops good for you from functional perspective after all these changes? I have no time to test on my side 😉

@simahawk LGTM 🫡

Copy link

@elvise elvise left a comment

Choose a reason for hiding this comment

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

LGTM

@francesco-ooops
Copy link
Contributor

@simahawk

image

Copy link

@simahawk simahawk left a comment

Choose a reason for hiding this comment

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

reminder for 2 things to change on your next iteration ;)

Comment on lines +454 to +456
template_id = self.env["sale.subscription.template"].search(
[("id", "=", values["template_id"])]
)

Choose a reason for hiding this comment

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

Suggested change
template_id = self.env["sale.subscription.template"].search(
[("id", "=", values["template_id"])]
)
template_id = self.env["sale.subscription.template"].browse(values["template_id"])

Comment on lines +466 to +468
self.env["sale.subscription.stage"]
.search([("type", "=", "pre")], order="sequence desc")[-1]
.id

Choose a reason for hiding this comment

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

Suggested change
self.env["sale.subscription.stage"]
.search([("type", "=", "pre")], order="sequence desc")[-1]
.id
self.env["sale.subscription.stage"]
.search([("type", "=", "pre")], order="sequence desc", limit=1)
.id

@simahawk
Copy link

/ocabot merge nobump

@OCA-git-bot
Copy link
Contributor

This PR looks fantastic, let's merge it!
Prepared branch 15.0-ocabot-merge-pr-971-by-simahawk-bump-nobump, awaiting test results.

@OCA-git-bot OCA-git-bot merged commit 6d3f4bb into OCA:15.0 Sep 22, 2023
5 of 7 checks passed
@OCA-git-bot
Copy link
Contributor

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

@carlos-domatix
Copy link
Contributor Author

reminder for 2 things to change on your next iteration ;)

Thanks, I'll have it in mind.

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.

9 participants