Skip to content

Commit 413c43d

Browse files
committed
[FEAT] subscription_oca: enable markers to print invoice names
(like in _contract_)
1 parent eb2a4c6 commit 413c43d

File tree

5 files changed

+124
-9
lines changed

5 files changed

+124
-9
lines changed

Diff for: subscription_oca/models/sale_subscription.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -277,15 +277,18 @@ def _prepare_account_move(self, line_ids):
277277
return values
278278

279279
def create_invoice(self):
280+
self.ensure_one()
280281
if not self.env["account.move"].check_access_rights("create", False):
281282
try:
282283
self.check_access_rights("write")
283284
self.check_access_rule("write")
284285
except AccessError:
285286
return self.env["account.move"]
286287
line_ids = []
288+
start_date = self.recurring_next_date or self.date_start
289+
end_date = self._get_next_period_date_end(start_date, self.date)
287290
for line in self.sale_subscription_line_ids:
288-
line_values = line._prepare_account_move_line()
291+
line_values = line._prepare_account_move_line(start_date, end_date)
289292
line_ids.append((0, 0, line_values))
290293
invoice_values = self._prepare_account_move(line_ids)
291294
invoice_id = (
@@ -305,8 +308,10 @@ def create_sale_order(self):
305308
except AccessError:
306309
return self.env["sale.order"]
307310
line_ids = []
311+
start_date = self.recurring_next_date or self.date_start
312+
end_date = self._get_next_period_date_end(start_date, self.date)
308313
for line in self.sale_subscription_line_ids:
309-
line_values = line._prepare_sale_order_line()
314+
line_values = line._prepare_sale_order_line(start_date, end_date)
310315
line_ids.append((0, 0, line_values))
311316
values = self._prepare_sale_order(line_ids)
312317
order_id = self.env["sale.order"].sudo().create(values)
@@ -431,6 +436,27 @@ def _check_dates(self, start, next_invoice):
431436
return True
432437
return False
433438

439+
def _get_next_period_date_end(
440+
self,
441+
next_period_date_start,
442+
max_date_end,
443+
):
444+
self.ensure_one()
445+
if not next_period_date_start:
446+
return False
447+
if max_date_end and next_period_date_start > max_date_end:
448+
return False
449+
next_period_date_end = (
450+
next_period_date_start
451+
+ self.template_id.get_relative_delta()
452+
- relativedelta(days=1)
453+
)
454+
if not max_date_end:
455+
return next_period_date_end
456+
if next_period_date_end > max_date_end:
457+
return max_date_end
458+
return next_period_date_end
459+
434460
def write(self, values):
435461
res = super().write(values)
436462
if "stage_id" in values:

Diff for: subscription_oca/models/sale_subscription_line.py

+45-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Copyright 2023 Domatix - Carlos Martínez
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3-
from odoo import api, fields, models
3+
from odoo import _, api, fields, models
44
from odoo.tools.misc import get_lang
55

66

@@ -290,11 +290,11 @@ def _get_display_price(self, product):
290290
)
291291
return max(base_price, final_price)
292292

293-
def _prepare_sale_order_line(self):
293+
def _prepare_sale_order_line(self, start_date, end_date):
294294
self.ensure_one()
295295
return {
296296
"product_id": self.product_id.id,
297-
"name": self.name,
297+
"name": self._generate_name(start_date, end_date),
298298
"product_uom_qty": self.product_uom_qty,
299299
"price_unit": self.price_unit,
300300
"discount": self.discount,
@@ -303,15 +303,15 @@ def _prepare_sale_order_line(self):
303303
"product_uom": self.product_id.uom_id.id,
304304
}
305305

306-
def _prepare_account_move_line(self):
306+
def _prepare_account_move_line(self, start_date, end_date):
307307
self.ensure_one()
308308
account = (
309309
self.product_id.property_account_income_id
310310
or self.product_id.categ_id.property_account_income_categ_id
311311
)
312312
return {
313313
"product_id": self.product_id.id,
314-
"name": self.name,
314+
"name": self._generate_name(start_date, end_date),
315315
"quantity": self.product_uom_qty,
316316
"price_unit": self.price_unit,
317317
"discount": self.discount,
@@ -320,3 +320,43 @@ def _prepare_account_move_line(self):
320320
"product_uom_id": self.product_id.uom_id.id,
321321
"account_id": account.id,
322322
}
323+
324+
def _generate_name(self, start_date, end_date):
325+
return self._insert_markers(start_date, end_date)
326+
327+
def _insert_markers(self, start_date, end_date):
328+
self.ensure_one()
329+
lang_obj = self.env["res.lang"]
330+
lang = lang_obj.search(
331+
[("code", "=", self.sale_subscription_id.partner_id.lang)]
332+
)
333+
date_format = lang.date_format or "%m/%d/%Y"
334+
name = self.name
335+
name = name.replace("#START#", start_date.strftime(date_format))
336+
name = name.replace("#END#", end_date.strftime(date_format)) if end_date else ""
337+
name = name.replace("#INVOICEMONTHNUMBER#", start_date.strftime("%m"))
338+
name = name.replace("#INVOICEYEAR#", start_date.strftime("%Y"))
339+
name = name.replace(
340+
"#INVOICEMONTHNAME#",
341+
self.with_context(lang=lang.code)._translate_marker_month_name(
342+
start_date.strftime("%m")
343+
),
344+
)
345+
return name
346+
347+
def _translate_marker_month_name(self, month_name):
348+
months = {
349+
"01": _("January"),
350+
"02": _("February"),
351+
"03": _("March"),
352+
"04": _("April"),
353+
"05": _("May"),
354+
"06": _("June"),
355+
"07": _("July"),
356+
"08": _("August"),
357+
"09": _("September"),
358+
"10": _("October"),
359+
"11": _("November"),
360+
"12": _("December"),
361+
}
362+
return months[month_name]

Diff for: subscription_oca/models/sale_subscription_template.py

+13
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,16 @@ def action_view_product_ids(self):
100100
"type": "ir.actions.act_window",
101101
"domain": [("id", "in", self.product_ids.ids)],
102102
}
103+
104+
def get_relative_delta(self):
105+
self.ensure_one()
106+
rule_type = self.recurring_rule_type
107+
interval = self.recurring_interval
108+
if rule_type == "days":
109+
return relativedelta(days=interval)
110+
elif rule_type == "weeks":
111+
return relativedelta(weeks=interval)
112+
elif rule_type == "months":
113+
return relativedelta(months=interval)
114+
else:
115+
return relativedelta(years=interval)

Diff for: subscription_oca/tests/test_subscription_oca.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,11 @@ def test_subscription_oca_sub_lines(self):
320320
self.assertEqual(self.sub_line.discount, 0)
321321
res = self.sub_line._get_display_price(self.product_2)
322322
self.assertEqual(res, 38.25)
323-
sol_res = self.sub_line._prepare_sale_order_line()
323+
date_start = self.sub_line.sale_subscription_id.date_start
324+
date_end = self.sub_line.sale_subscription_id.date
325+
sol_res = self.sub_line._prepare_sale_order_line(date_start, date_end)
324326
self.assertIsInstance(sol_res, dict)
325-
move_res = self.sub_line._prepare_account_move_line()
327+
move_res = self.sub_line._prepare_account_move_line(date_start, date_end)
326328
self.assertIsInstance(move_res, dict)
327329

328330
def test_subscription_oca_sub_cron(self):

Diff for: subscription_oca/views/sale_subscription_views.xml

+34
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,40 @@
192192
<field name="user_id" />
193193
</group>
194194
</group>
195+
<group
196+
string="Legend (for the markers inside invoice lines description)"
197+
name="group_legend"
198+
>
199+
<p colspan="2">
200+
<strong>#START#</strong>
201+
: Start
202+
date
203+
of the
204+
invoiced period
205+
</p>
206+
<p colspan="2">
207+
<strong>#END#</strong>
208+
: End date
209+
of
210+
the
211+
invoiced period
212+
</p>
213+
<p colspan="2">
214+
<strong>#INVOICEMONTHNAME#</strong>
215+
: Invoice month name
216+
of
217+
the
218+
invoiced period
219+
</p>
220+
<p colspan="2">
221+
<strong
222+
>#INVOICEMONTHNUMBER#</strong>: Invoice month number of the period
223+
</p>
224+
<p colspan="2">
225+
<strong
226+
>#INVOICEYEAR#</strong>: Invoice year of the period
227+
</p>
228+
</group>
195229
</page>
196230
</notebook>
197231

0 commit comments

Comments
 (0)