<commit_before># Copyright 2014 AvancOSC - <NAME>
# Copyright 2014 Tecnativa - <NAME>
# Copyright 2014 Shine IT - <NAME>
# Copyright 2017 Tecnativa - <NAME>
# Copyright 2018 Avanzosc S.L. - <NAME>
# Copyright 2020 Tecnativa - <NAME>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import re
from collections import defaultdict
from string import Template

from odoo import _, api, fields, models
from odoo.exceptions import UserError


class ReferenceMask(Template):
    pattern = r"""\[(?:
                    (?P<escaped>\[) |
                    (?P<named>[^\]]+?)\] |
                    (?P<braced>[^\]]+?)\] |
                    (?P<invalid>)
                    )"""


def extract_token(s):
    pattern = re.compile(r"\[([^\]]+?)\]")
    return set(pattern.findall(s))


def sanitize_reference_mask(product, mask):
    main_lang = product._guess_main_lang()
    tokens = extract_token(mask)
    attribute_names = set()
    for line in product.attribute_line_ids:
        attribute_names.add(line.attribute_id.with_context(lang=main_lang).name)
    if not tokens.issubset(attribute_names):
        raise UserError(
            _('Found unrecognized attribute name in "Variant ' 'Reference Mask"')
        )


def get_rendered_default_code(product, mask):
    product_attrs = defaultdict(str)
    reference_mask = ReferenceMask(mask)
    main_lang = product.product_tmpl_id._guess_main_lang()
    for attr in product.product_template_attribute_value_ids:
        value = attr.product_attribute_value_id
        attr_name = value.attribute_id.with_context(lang=main_lang).name
        if value.attribute_id.code:
            product_attrs[attr_name] += value.attribute_id.code
        if value.code:
            product_attrs[attr_name] += value.code
    all_attrs = extract_token(mask)
    missing_attrs = all_attrs - set(product_attrs.keys())
    missing = dict.fromkeys(
        missing_attrs,
        product.env["ir.config_parameter"]
        .sudo()
        .get_param("default_reference_missing_placeholder"),
    )
    product_attrs.update(missing)
    default_code = reference_mask.safe_substitute(product_attrs)
    return default_code


def render_default_code(product, mask):
    product.default_code = get_rendered_default_code(product, mask)


class ProductTemplate(models.Model):
    _inherit = "product.template"

    code_prefix = fields.Char(
        string="Reference Prefix",
        help="Add prefix to product variant reference (default code)",
    )
    reference_mask = fields.Char(
        string="Variant reference mask",
        copy=False,
        help="Reference mask for building internal references of a "
        "variant generated from this template.\n"
        "Example:\n"
        "A product named ABC with 2 attributes: Size and Color:\n"
        "Product: ABC\n"
        "Color: Red(r), Yellow(y), Black(b)  #Red, Yellow, Black are "
        "the attribute value, `r`, `y`, `b` are the corresponding code\n"
        "Size: L (l), XL(x)\n"
        "When setting Variant reference mask to `[Color]-[Size]`, the "
        "default code on the variants will be something like `r-l` "
        "`b-l` `r-x` ...\n"
        "If you like, You can even have the attribute name appear more"
        " than once in the mask. Such as,"
        "`fancyA/[Size]~[Color]~[Size]`\n"
        " When saved, the default code on variants will be "
        "something like \n"
        ' `fancyA/l~r~l` (for variant with Color "Red" and Size "L") '
        ' `fancyA/x~y~x` (for variant with Color "Yellow" and Size "XL")'
        '\nNote: make sure characters "[,]" do not appear in your '
        "attribute name",
    )

    def _get_default_mask(self):
        attribute_names = []
        default_reference_separator = (
            self.env["ir.config_parameter"]
            .sudo()
            .get_param("default_reference_separator")
        )
        for line in self.attribute_line_ids:
            attribute_names.append(u"[{}]".format(line.attribute_id.name))
        default_mask = (self.code_prefix or "") + default_reference_separator.join(
            attribute_names
        )
        return default_mask

    @api.model
    def create(self, vals):
        product = self.new(vals)
        if (
            not vals.get("reference_mask")
            and product.attribute_line_ids
            or not self.user_has_groups(
                "product_variant_default_code.group_product_default_code_manual_mask"
            )
        ):
            vals["reference_mask"] = product._get_default_mask()
        elif vals.get("reference_mask"):
            sanitize_reference_mask(product, vals["reference_mask"])
        return super(ProductTemplate, self).create(vals)

    def write(self, vals):<commit_msg>[FIX] product_variant_default_code: don't translate mask<commit_after># Copyright 2014 AvancOSC - <NAME>
# Copyright 2014 Tecnativa - <NAME>
# Copyright 2014 Sh<NAME> - <NAME>
# Copyright 2017 Tecnativa - <NAME>
# Copyright 2018 Avanzosc S.L. - <NAME>
# Copyright 2020 Tecnativa - <NAME>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import re
from collections import defaultdict
from string import Template

from odoo import _, api, fields, models
from odoo.exceptions import UserError


class ReferenceMask(Template):
    pattern = r"""\[(?:
                    (?P<escaped>\[) |
                    (?P<named>[^\]]+?)\] |
                    (?P<braced>[^\]]+?)\] |
                    (?P<invalid>)
                    )"""


def extract_token(s):
    pattern = re.compile(r"\[([^\]]+?)\]")
    return set(pattern.findall(s))


def sanitize_reference_mask(product, mask):
    main_lang = product._guess_main_lang()
    tokens = extract_token(mask)
    attribute_names = set()
    for line in product.attribute_line_ids:
        attribute_names.add(line.attribute_id.with_context(lang=main_lang).name)
    if not tokens.issubset(attribute_names):
        raise UserError(
            _('Found unrecognized attribute name in "Variant ' 'Reference Mask"')
        )


def get_rendered_default_code(product, mask):
    product_attrs = defaultdict(str)
    reference_mask = ReferenceMask(mask)
    main_lang = product.product_tmpl_id._guess_main_lang()
    for attr in product.product_template_attribute_value_ids:
        value = attr.product_attribute_value_id
        attr_name = value.attribute_id.with_context(lang=main_lang).name
        if value.attribute_id.code:
            product_attrs[attr_name] += value.attribute_id.code
        if value.code:
            product_attrs[attr_name] += value.code
    all_attrs = extract_token(mask)
    missing_attrs = all_attrs - set(product_attrs.keys())
    missing = dict.fromkeys(
        missing_attrs,
        product.env["ir.config_parameter"]
        .sudo()
        .get_param("default_reference_missing_placeholder"),
    )
    product_attrs.update(missing)
    default_code = reference_mask.safe_substitute(product_attrs)
    return default_code


def render_default_code(product, mask):
    product.default_code = get_rendered_default_code(product, mask)


class ProductTemplate(models.Model):
    _inherit = "product.template"

    code_prefix = fields.Char(
        string="Reference Prefix",
        help="Add prefix to product variant reference (default code)",
    )
    reference_mask = fields.Char(
        string="Variant reference mask",
        copy=False,
        help="Reference mask for building internal references of a "
        "variant generated from this template.\n"
        "Example:\n"
        "A product named ABC with 2 attributes: Size and Color:\n"
        "Product: ABC\n"
        "Color: Red(r), Yellow(y), Black(b)  #Red, Yellow, Black are "
        "the attribute value, `r`, `y`, `b` are the corresponding code\n"
        "Size: L (l), XL(x)\n"
        "When setting Variant reference mask to `[Color]-[Size]`, the "
        "default code on the variants will be something like `r-l` "
        "`b-l` `r-x` ...\n"
        "If you like, You can even have the attribute name appear more"
        " than once in the mask. Such as,"
        "`fancyA/[Size]~[Color]~[Size]`\n"
        " When saved, the default code on variants will be "
        "something like \n"
        ' `fancyA/l~r~l` (for variant with Color "Red" and Size "L") '
        ' `fancyA/x~y~x` (for variant with Color "Yellow" and Size "XL")'
        '\nNote: make sure characters "[,]" do not appear in your '
        "attribute name",
    )

    def _get_default_mask(self):
        attribute_names = []
        default_reference_separator = (
            self.env["ir.config_parameter"]
            .sudo()
            .get_param("default_reference_separator")
        )
        # Get the attribute name in the main lang format, otherwise we could not
        # match mask with the proper values
        main_lang = self._guess_main_lang()
        for line in self.attribute_line_ids:
            attribute_names.append(
                u"[{}]".format(line.attribute_id.with_context(lang=main_lang).name)
            )
        default_mask = (self.code_prefix or "") + default_reference_separator.join(
            attribute_names
        )
        return default_mask

    @api.model
    def create(self, vals):
        product = self.new(vals)
        if (
            not vals.get("reference_mask")
            and product.attribute_line_ids
            or not self.user_has_groups(
                "product_variant_default_code.group_product_default_code_manual_mask"
            )
        ):
            vals["reference_mask"] = product._get_default_mask()
        elif vals.get("reference_mask"):
            sanitize_reference_mask(product, vals["reference_mask"])
        return super(ProductTemplate, self).create(vals)

    def write(self, vals):
{'fraction_non_alphanumeric': 0.11267749514761467, 'fraction_numerical': 0.0055163959546429666, 'mean_word_length': 2.6313056379821957, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5518174', 'n_tokens_mistral': 3008, 'n_tokens_neox': 2864, 'n_words': 700}