Skip to content

Commit be87d2b

Browse files
[16.0] [IMP] product_variant_default_code : add sequence to complete or replace patterns
1 parent 4c280b1 commit be87d2b

10 files changed

Lines changed: 314 additions & 43 deletions

File tree

product_variant_default_code/README.rst

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
.. image:: https://odoo-community.org/readme-banner-image
2-
:target: https://odoo-community.org/get-involved?utm_source=readme
3-
:alt: Odoo Community Association
4-
51
============================
62
Product Variant Default Code
73
============================
@@ -17,7 +13,7 @@ Product Variant Default Code
1713
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
1814
:target: https://odoo-community.org/page/development-status
1915
:alt: Beta
20-
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
2117
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
2218
:alt: License: AGPL-3
2319
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproduct--variant-lightgray.png?logo=github
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
from .hooks import pre_init_hook
12
from . import models

product_variant_default_code/__manifest__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@
2626
],
2727
"demo": ["demo/attribute_demo.xml"],
2828
"installable": True,
29+
"pre_init_hook": "pre_init_hook",
2930
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright (c) 2025 Groupe Voltaire
2+
# @author Emilie SOUTIRAS <emilie.soutiras@groupevoltaire.com>
3+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
4+
5+
6+
def pre_init_hook(cr):
7+
# Preserve default_code already set on product
8+
cr.execute(
9+
"""
10+
DO $$
11+
BEGIN
12+
IF NOT EXISTS (
13+
SELECT 1
14+
FROM information_schema.columns
15+
WHERE table_name = 'product_product'
16+
AND column_name = 'manual_code'
17+
) THEN
18+
ALTER TABLE product_product ADD COLUMN manual_code BOOLEAN;
19+
END IF;
20+
END $$;
21+
"""
22+
)
23+
cr.execute(
24+
"""
25+
UPDATE product_product
26+
SET manual_code = true
27+
WHERE default_code is not NULL
28+
"""
29+
)

product_variant_default_code/models/config_settings.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,15 @@ class BaseConfiguration(models.TransientModel):
2323
default=False,
2424
config_parameter="product_variant_default_code.prefix_as_default_code",
2525
)
26+
27+
sequence_as_default_code = fields.Many2one(
28+
string="Default sequence as default Reference",
29+
comodel_name="ir.sequence",
30+
config_parameter="product_variant_default_code.sequence_as_default_code",
31+
)
32+
33+
use_sequence_per_product_tmp_as_default_code = fields.Boolean(
34+
string="Use specific sequence par Product in Reference",
35+
config_parameter="product_variant_default_code."
36+
"use_sequence_per_product_tmp_as_default_code",
37+
)

product_variant_default_code/models/product.py

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
from odoo import _, api, fields, models
1515
from odoo.exceptions import UserError
1616

17+
SEQUENCE_PATTERN = "[SEQUENCE]"
18+
1719

1820
class ReferenceMask(Template):
1921
pattern = r"""\[(?:
@@ -33,11 +35,13 @@ def sanitize_reference_mask(product, mask):
3335
main_lang = product._guess_main_lang()
3436
tokens = extract_token(mask)
3537
attribute_names = set()
38+
attribute_names.add(SEQUENCE_PATTERN[1:-1])
39+
attribute_names.add("ID")
3640
for line in product.attribute_line_ids:
3741
attribute_names.add(line.attribute_id.with_context(lang=main_lang).name)
3842
if not tokens.issubset(attribute_names):
3943
raise UserError(
40-
_('Found unrecognized attribute name in "Variant ' 'Reference Mask"')
44+
_('Found unrecognized attribute name in "Variant Reference Mask"')
4145
)
4246

4347

@@ -73,13 +77,22 @@ class ProductTemplate(models.Model):
7377
' `fancyA/l~r~l` (for variant with Color "Red" and Size "L") '
7478
' `fancyA/x~y~x` (for variant with Color "Yellow" and Size "XL")'
7579
'\nNote: make sure characters "[,]" do not appear in your '
76-
"attribute name",
80+
"attribute name"
81+
"Specific : set `%s` to add séquence number, [ID] for variant identifier"
82+
% SEQUENCE_PATTERN,
7783
)
7884

7985
variant_default_code_error = fields.Text(
8086
compute="_compute_variant_default_code_error"
8187
)
8288

89+
code_sequence_id = fields.Many2one(
90+
string="Default sequence as Reference",
91+
comodel_name="ir.sequence",
92+
default=False,
93+
copy=False,
94+
)
95+
8396
def is_automask(self):
8497
return bool(
8598
not self.user_has_groups(
@@ -196,6 +209,54 @@ def _compute_default_code(self):
196209
template.default_code = template.code_prefix
197210
return True
198211

212+
def _create_default_code_sequence(self):
213+
current_pdt = self if len(self.ids) == 1 else False
214+
params = self.env["ir.config_parameter"].sudo()
215+
seq_model = self.env["ir.sequence"]
216+
for_global = not bool(
217+
params.get_param(
218+
"product_variant_default_code.use_sequence_per_product_tmp_as_default_code"
219+
)
220+
)
221+
seq = (
222+
False
223+
if not for_global
224+
else seq_model.browse(
225+
int(
226+
params.get_param(
227+
"product_variant_default_code.sequence_as_default_code"
228+
)
229+
)
230+
)
231+
)
232+
if for_global:
233+
seq_name = _("Global Product Sequence")
234+
else:
235+
assert current_pdt
236+
seq = self.code_sequence_id
237+
seq_name = _("Product Sequence of %(name)s - %(identifier)s") % {
238+
"name": current_pdt.name,
239+
"identifier": current_pdt.id,
240+
}
241+
if not seq:
242+
vals = {
243+
"name": seq_name,
244+
"code": "product_sequence_%s"
245+
% (current_pdt.id if not for_global else 0),
246+
"implementation": "no_gap",
247+
"prefix": "",
248+
"suffix": "",
249+
"padding": 3,
250+
}
251+
seq = seq_model.create(vals)
252+
if not for_global:
253+
self.code_sequence_id = seq.id
254+
else:
255+
params.set_param(
256+
"product_variant_default_code.sequence_as_default_code", seq.id
257+
)
258+
return seq
259+
199260

200261
class ProductProduct(models.Model):
201262
_inherit = "product.product"
@@ -231,6 +292,10 @@ def _generate_default_code(self):
231292
return None
232293
else:
233294
product_attrs = defaultdict(str)
295+
product_attrs["ID"] = str(self.id)
296+
if SEQUENCE_PATTERN in self.product_tmpl_id.reference_mask:
297+
seq = self.product_tmpl_id._create_default_code_sequence()
298+
product_attrs[SEQUENCE_PATTERN[1:-1]] = seq.next_by_id()
234299
reference_mask = ReferenceMask(self.product_tmpl_id.reference_mask)
235300
main_lang = self.product_tmpl_id._guess_main_lang()
236301
for attr in self.product_template_attribute_value_ids:

product_variant_default_code/static/description/index.html

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
55
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
6-
<title>README.rst</title>
6+
<title>Product Variant Default Code</title>
77
<style type="text/css">
88

99
/*
@@ -360,21 +360,16 @@
360360
</style>
361361
</head>
362362
<body>
363-
<div class="document">
363+
<div class="document" id="product-variant-default-code">
364+
<h1 class="title">Product Variant Default Code</h1>
364365

365-
366-
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
367-
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
368-
</a>
369-
<div class="section" id="product-variant-default-code">
370-
<h1>Product Variant Default Code</h1>
371366
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
372367
!! This file is generated by oca-gen-addon-readme !!
373368
!! changes will be overwritten. !!
374369
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375370
!! source digest: sha256:23782e83708e18c5e26008b1e49622f50b2f53d317111279dd3fe33def16dacd
376371
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377-
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/product-variant/tree/16.0/product_variant_default_code"><img alt="OCA/product-variant" src="https://img.shields.io/badge/github-OCA%2Fproduct--variant-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/product-variant-16-0/product-variant-16-0-product_variant_default_code"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/product-variant&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
372+
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/product-variant/tree/16.0/product_variant_default_code"><img alt="OCA/product-variant" src="https://img.shields.io/badge/github-OCA%2Fproduct--variant-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/product-variant-16-0/product-variant-16-0-product_variant_default_code"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/product-variant&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378373
<p>This module automatically generate Product Reference (default_code)
379374
according to attributes data with a configurable behavior.</p>
380375
<p>It defines a reference mask on the product templates so the
@@ -411,7 +406,7 @@ <h1>Product Variant Default Code</h1>
411406
</ul>
412407
</div>
413408
<div class="section" id="usage">
414-
<h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
409+
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
415410
<p>To set the reference mask up on any product template ‘Variant reference mask’
416411
new field.</p>
417412
<p>When creating a new product template without specifying the <em>Variant reference
@@ -444,7 +439,7 @@ <h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
444439
would give <cite>default_code</cite> like this: <cite>COBl-L</cite>, <cite>COWh-L</cite>, <cite>COBl-XL</cite> and
445440
<cite>COWh-XL</cite>.</p>
446441
<div class="section" id="avoiding-mask-in-variants">
447-
<h3><a class="toc-backref" href="#toc-entry-2">Avoiding mask in variants</a></h3>
442+
<h2><a class="toc-backref" href="#toc-entry-2">Avoiding mask in variants</a></h2>
448443
<p>You can avoid this behavior or force a manual default_code on variant. To do
449444
so, go to <em>Product Variants &gt; [any variant you want to set up]</em> and set
450445
manually its reference code. The field <cite>manual code</cite> will be set to on and the
@@ -453,23 +448,23 @@ <h3><a class="toc-backref" href="#toc-entry-2">Avoiding mask in variants</a></h3
453448
</div>
454449
</div>
455450
<div class="section" id="known-issues-roadmap">
456-
<h2><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h2>
451+
<h1><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h1>
457452
<ul class="simple">
458453
<li>In case of attribute name update, related mask are not updated.</li>
459454
</ul>
460455
</div>
461456
<div class="section" id="bug-tracker">
462-
<h2><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h2>
457+
<h1><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h1>
463458
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/product-variant/issues">GitHub Issues</a>.
464459
In case of trouble, please check there if your issue has already been reported.
465460
If you spotted it first, help us to smash it by providing a detailed and welcomed
466461
<a class="reference external" href="https://github.com/OCA/product-variant/issues/new?body=module:%20product_variant_default_code%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
467462
<p>Do not contact contributors directly about support or help with technical issues.</p>
468463
</div>
469464
<div class="section" id="credits">
470-
<h2><a class="toc-backref" href="#toc-entry-5">Credits</a></h2>
465+
<h1><a class="toc-backref" href="#toc-entry-5">Credits</a></h1>
471466
<div class="section" id="authors">
472-
<h3><a class="toc-backref" href="#toc-entry-6">Authors</a></h3>
467+
<h2><a class="toc-backref" href="#toc-entry-6">Authors</a></h2>
473468
<ul class="simple">
474469
<li>AvancOSC</li>
475470
<li>Shine IT</li>
@@ -478,7 +473,7 @@ <h3><a class="toc-backref" href="#toc-entry-6">Authors</a></h3>
478473
</ul>
479474
</div>
480475
<div class="section" id="contributors">
481-
<h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
476+
<h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
482477
<ul class="simple">
483478
<li>Alfredo de la Fuente &lt;<a class="reference external" href="mailto:alfredodelafuente&#64;avanzosc.es">alfredodelafuente&#64;avanzosc.es</a>&gt;</li>
484479
<li>Tony Gu &lt;<a class="reference external" href="mailto:tony&#64;openerp.cn">tony&#64;openerp.cn</a>&gt;</li>
@@ -492,7 +487,7 @@ <h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
492487
</ul>
493488
</div>
494489
<div class="section" id="maintainers">
495-
<h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
490+
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
496491
<p>This module is maintained by the OCA.</p>
497492
<a class="reference external image-reference" href="https://odoo-community.org">
498493
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
@@ -507,6 +502,5 @@ <h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
507502
</div>
508503
</div>
509504
</div>
510-
</div>
511505
</body>
512506
</html>

0 commit comments

Comments
 (0)