Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7420b7f
[FIX] price_security_sale_margin: hide margin and margin_percent for …
matiasperalta1 Oct 13, 2025
0724eb6
[ADD] Copilot instructions
adhoc-cicd-bot Oct 22, 2025
02e256f
[UPD] Copilot instructions
adhoc-cicd-bot Oct 22, 2025
8017db3
[FIX] prodcut_catalog_tree: add context validation in product catalog…
lav-adhoc Oct 23, 2025
e5ec0b4
[UPD] Copilot instructions
adhoc-cicd-bot Oct 24, 2025
0f7fbb6
[FIX] product_catalog_tree: filters fixed
matiasperalta1 Oct 27, 2025
093f762
[IMP]product_catalog_tree:recompute line in PO
jcadhoc Oct 24, 2025
7dd5b63
[FIX]product_catalog_tree:Revert of commit
jcadhoc Nov 6, 2025
b40ee64
[FIX] product_catalog_tree: fix in product catalog fields
lav-adhoc Nov 12, 2025
55d48fc
[UPD] Copilot instructions
adhoc-cicd-bot Nov 18, 2025
923ade2
[IMP]product_replenishment_cost:no more force_company
jcadhoc Nov 18, 2025
b3ddff5
[I18N] Update translation terms from Transifex adhoc-odoo-18-0
adhoc-transbot Nov 21, 2025
a1cfadb
[IMP] *: Add macOS specific files to ignore list
lef-adhoc Nov 20, 2025
0f36826
[FIX] product_replenishment_cost_mrp: adapt module to subcontracting
ced-adhoc Nov 19, 2025
cddeac9
Update project.toml from template
vib-adhoc Dec 17, 2025
3a67ba9
[UPD] Copilot instructions
adhoc-cicd-bot Dec 19, 2025
f12fe06
[FIX] product_catalog_tree: clear context when updating order line info
cav-adhoc Dec 16, 2025
3f07911
[FIX] prodct_catalog_tree: clear all context before update order
cav-adhoc Dec 19, 2025
bb23eba
[IMP] backport from https://github.com/odoo/odoo/commit/41d8fa352a7ba…
maq-adhoc Oct 16, 2025
97a66c3
[FIX] product_catalog_tree: add warehouse location filter for sale or…
lef-adhoc Dec 24, 2025
c85dc7f
[FIX] _cost_sale_margin:: do not recompute on rep cost change
jjscarafia Dec 15, 2025
eec1598
[UPD] Copilot instructions
adhoc-cicd-bot Jan 14, 2026
8632232
Update project.toml from template
vib-adhoc Jan 29, 2026
b0b047d
[ADD] product_catalog_tree_custom: New module
gal-adhoc Feb 18, 2026
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
2 changes: 1 addition & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Do NOT update manually; changes here will be overwritten by Copier
_commit: d46567f
_commit: a740779
_src_path: https://github.com/ingadhoc/addons-repo-template.git
description: ''
is_private: false
Expand Down
325 changes: 325 additions & 0 deletions .github/copilot-instructions.md

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ name: pre-commit

on:
push:
branches: "[0-9][0-9].0"
branches:
- "1[8-9].0"
- "[2-9][0-9].0"
pull_request_target:
branches:
- "1[8-9].0*"
- "[2-9][0-9].0*"

jobs:
pre-commit:
Expand Down
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,36 @@ coverage.xml

# Sphinx documentation
docs/_build/

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### macOS Patch ###
# iCloud generated files
*.icloud
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ repos:
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-merge-conflict
args: ['--assume-in-merge']
exclude: '\.rst$'
- id: check-symlinks
- id: check-xml
- id: check-yaml
Expand Down
14 changes: 7 additions & 7 deletions price_security_sale_margin/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ def _get_view(self, view_id=None, view_type="form", **options):
modifiers["readonly"] = True
node.set("modifiers", json.dumps(modifiers))
if self.env.user.has_group("price_security.group_only_view_sale_price"):
invisible_fields = (
arch.xpath("//field[@name='purchase_price']")
+ arch.xpath("//field[@name='margin']")
+ arch.xpath("//field[@name='margin_percent']")
+ arch.xpath("//field[@name='margin_percent']/..")
invisible_fields = arch.xpath(
"//field[@name='purchase_price']"
"|//field[@name='order_line']//field[@name='margin']"
"|//field[@name='order_line']//field[@name='margin_percent']"
"|//div[@class='d-flex float-end']"
)
for node in invisible_fields:
node.set("column_invisible", "1")
node.set("invisible", "1")
modifiers = json.loads(node.get("modifiers") or "{}")
modifiers["column_invisible"] = True
modifiers["invisible"] = True
node.set("modifiers", json.dumps(modifiers))
return arch, view
2 changes: 1 addition & 1 deletion product_catalog_tree/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
##############################################################################
{
"name": "Product Catalog Tree",
"version": "18.0.1.2.0",
"version": "18.0.1.3.0",
"category": "Products",
"sequence": 14,
"summary": "",
Expand Down
7 changes: 7 additions & 0 deletions product_catalog_tree/models/product_catalog_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,12 @@ class ProductCatalogMixin(models.AbstractModel):
def action_add_from_catalog(self):
action = super().action_add_from_catalog()
tree_view_id = self.env.ref("product_catalog_tree.product_view_tree_catalog").id
search_view_id = self.env.ref("product.product_search_form_view").id
action["views"] = [(tree_view_id, "list")] + action["views"]
action["search_view_id"] = (search_view_id, "search")
# add warehouse location filter if order has warehouse
context = action.get("context", {})
if "order_id" in context and self._name == "sale.order":
if self._fields.get("warehouse_id") and self.warehouse_id:
action["context"]["search_default_location_id"] = self.warehouse_id.lot_stock_id.id
return action
14 changes: 13 additions & 1 deletion product_catalog_tree/models/product_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ def write(self, vals):
def _compute_catalog_values(self):
res_model = self._context.get("product_catalog_order_model")
order_id = self._context.get("order_id")

if not res_model or not order_id:
self.product_catalog_qty = 0
self.product_catalog_price = 0
return

order = self.env[res_model].browse(order_id)
order_line_info = order.with_company(order.company_id)._get_product_catalog_order_line_info(
product_ids=self.ids
Expand All @@ -46,9 +52,15 @@ def _compute_catalog_values(self):
def _inverse_catalog_values(self, product_catalog_qty):
res_model = self._context.get("product_catalog_order_model")
order_id = self._context.get("order_id")

if not res_model or not order_id:
return

order = self.env[res_model].browse(order_id)
for rec in self:
order.with_company(order.company_id)._update_order_line_info(rec.id, product_catalog_qty)
# Actualizar la información de la línea de orden
# Call the order method with a cleared context to avoid errors on creating move line
order.with_company(order.company_id).with_context(**{})._update_order_line_info(rec.id, product_catalog_qty)

def increase_quantity(self):
for rec in self:
Expand Down
12 changes: 12 additions & 0 deletions product_catalog_tree/views/product_product_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,16 @@
</field>
</record>

<record id="product_search_form_view_supplier" model="ir.ui.view">
<field name="name">product.product.search.form.supplier</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_search_form_view"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="seller_ids" string="Supplier"
filter_domain="[('seller_ids.partner_id', 'ilike', self)]"/>
</field>
</field>
</record>

</odoo>
Empty file.
19 changes: 19 additions & 0 deletions product_catalog_tree_custom/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "Product Catalog Tree Custom",
"version": "18.0.1.0.0",
"category": "Product",
"summary": "Customizations for product catalog tree view",
"author": "ADHOC SA",
"license": "LGPL-3",
"depends": [
"product_catalog_tree",
"website_sale",
"product_price_taxes_included",
"product_brand",
],
"data": [
"views/product_catalog_list_views.xml",
],
"installable": True,
"application": False,
}
46 changes: 46 additions & 0 deletions product_catalog_tree_custom/views/product_catalog_list_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>

<record id="gg_product_view_list_catalog_ext" model="ir.ui.view">
<field name="name">gg.product.view.list.catalog.ext</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product_catalog_tree.product_view_tree_catalog"/>
<field name="mode">extension</field>
<field name="priority">50</field>
<field name="arch" type="xml">

<!-- Sitio web: oculto por defecto -->
<xpath expr="//field[@name='website_id']" position="attributes">
<attribute name="optional">hide</attribute>
</xpath>

<!-- Tipo de producto: oculto por defecto-->
<xpath expr="//field[@name='type']" position="attributes">
<attribute name="optional">hide</attribute>
</xpath>

<!-- Valores de variantes SIEMPRE visibles -->
<xpath expr="//field[@name='product_template_variant_value_ids']" position="attributes">
<attribute name="optional">show</attribute>
</xpath>

<!-- Campos de precios: opcionales -->
<xpath expr="//field[@name='lst_price']" position="attributes">
<attribute name="optional">show</attribute>
</xpath>

<xpath expr="//field[@name='taxed_lst_price']" position="attributes">
<attribute name="optional">show</attribute>
</xpath>

<xpath expr="//field[@name='standard_price']" position="attributes">
<attribute name="optional">show</attribute>
</xpath>

<xpath expr="//field[@name='product_catalog_price']" position="attributes">
<attribute name="optional">show</attribute>
</xpath>

</field>
</record>
</odoo>
17 changes: 1 addition & 16 deletions product_replenishment_cost/i18n/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-03 05:15+0000\n"
"POT-Creation-Date: 2025-11-21 10:29+0000\n"
"PO-Revision-Date: 2024-11-08 12:54+0000\n"
"Last-Translator: ced_adhoc, 2025\n"
"Language-Team: Spanish (https://app.transifex.com/adhoc/teams/46451/es/)\n"
Expand Down Expand Up @@ -287,11 +287,6 @@ msgstr "Productos sin regla de reposición"
msgid "Purchase Order Line"
msgstr "Línea de pedido de compra"

#. module: product_replenishment_cost
#: model:ir.model.fields,field_description:product_replenishment_cost.field_product_replenishment_cost_rule__rating_ids
msgid "Ratings"
msgstr ""

#. module: product_replenishment_cost
#: model:ir.model.fields,help:product_replenishment_cost.field_product_product__replenishment_base_cost
#: model:ir.model.fields,help:product_replenishment_cost.field_product_template__replenishment_base_cost
Expand Down Expand Up @@ -434,16 +429,6 @@ msgstr "Lista de precios de proveedor"
msgid "Supplierinfo"
msgstr "Información del Proveedor"

#. module: product_replenishment_cost
#. odoo-python
#: code:addons/product_replenishment_cost/models/product_template.py:0
msgid ""
"The argument 'company_ids' and the key 'force_company' on the context can't "
"be used together"
msgstr ""
"El argumento 'company_ids' y la clave 'force_company'  en el contexto no "
"pueden usarse juntos"

#. module: product_replenishment_cost
#: model_terms:ir.ui.view,arch_db:product_replenishment_cost.view_update_from_replenishment_cost_wizard_form
msgid ""
Expand Down
15 changes: 3 additions & 12 deletions product_replenishment_cost/models/product_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import logging

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import float_compare

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -44,7 +43,7 @@ class ProductTemplate(models.Model):
replenishment_base_cost = fields.Float(
digits="Product Price",
tracking=True,
help="Replanishment Cost expressed in 'Replenishment Base Cost " "Currency'.",
help="Replanishment Cost expressed in 'Replenishment Base Cost Currency'.",
)
replenishment_base_cost_currency_id = fields.Many2one(
"res.currency",
Expand Down Expand Up @@ -111,12 +110,6 @@ def cron_update_cost_from_replenishment_cost(self, limit=None, company_ids=None,
tampoco podemos usar get_param porque justamente no se va a refrescar el valor
"""

# allow force_company for backward compatibility
force_company = self._context.get("force_company", False)
if force_company and company_ids:
raise ValidationError(
_("The argument 'company_ids' and the key 'force_company' on the context can't be used together")
)
# buscamos cual fue el ultimo registro actualziado
parameter_name = "product_replenishment_cost.last_updated_record_id"
last_updated_param = self.env["ir.config_parameter"].sudo().search([("key", "=", parameter_name)], limit=1)
Expand All @@ -126,10 +119,8 @@ def cron_update_cost_from_replenishment_cost(self, limit=None, company_ids=None,
domain = [("id", ">", int(last_updated_param.value))]
records = self.with_context(prefetch_fields=False).search(domain, order="id asc")

# use company_ids or force_company or search for all companies
if force_company:
company_ids = [force_company]
elif not company_ids:
# use company_ids or search for all companies
if not company_ids:
company_ids = self.env["res.company"].search([]).ids

for company_id in company_ids:
Expand Down
5 changes: 3 additions & 2 deletions product_replenishment_cost_mrp/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
Integration between Replenishment Cost and Manufacture
======================================================

#. Agregado de método para cálculo de costo de reposición utilizando el costo de reposición de la LdM.
#. Modifica el reporte de "Estructura de Lista de Materiales" para que utilice el costo de reposición.
#. Add a method to compute the replenishment cost using the BoM's replenishment cost.
#. Modify the "Bill of Materials Structure" report to use the replenishment cost
#. Support for replenishment cost calculation in subcontracted BOMs, adding the supplier/subcontractor cost to the components' cost

Installation
============
Expand Down
6 changes: 5 additions & 1 deletion product_replenishment_cost_mrp/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
"product_replenishment_cost",
"mrp",
],
"data": ["views/mrp_bom_views.xml", "views/product_template_views.xml", "report/mrp_report_bom_structure.xml"],
"data": [
"views/mrp_bom_views.xml",
"views/product_template_views.xml",
"report/mrp_report_bom_structure.xml",
],
"installable": True,
}
36 changes: 35 additions & 1 deletion product_replenishment_cost_mrp/models/product_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ def _compute_replenishment_cost(self):
rec.update({"replenishment_base_cost_on_currency": 0.0, "replenishment_cost": 0.0})
continue
# el explode es para product.product, tomamos la primer variante
result, result2 = bom.explode(rec.with_context(active_test=rec.active).product_variant_ids[0], 1)
product_variant = rec.with_context(active_test=rec.active).product_variant_ids[:1]
if not product_variant:
rec.update({"replenishment_base_cost_on_currency": 0.0, "replenishment_cost": 0.0})
continue
result, result2 = bom.explode(product_variant, 1)
for sbom, sbom_data in result2:
sbom_rep_cost = (
sbom.product_id.uom_id._compute_price(
Expand All @@ -57,6 +61,36 @@ def _compute_replenishment_cost(self):
price += sbom.product_id.product_tmpl_id.currency_id._convert(
sbom_rep_cost, product_currency, company, date, round=False
)

# Add subcontracting cost if bom type is 'subcontract'
if bom.type == "subcontract":
# Look for the seller/subcontractor set in the BOM
product = rec.product_variant_ids[:1]
if product:
seller = product._select_seller(
quantity=1, uom_id=bom.product_uom_id, params={"subcontractor_ids": bom.subcontractor_ids}
)
else:
# If no product variant, look for sellers in the template
seller = rec.seller_ids.filtered(lambda s: s.partner_id in bom.subcontractor_ids)[:1]

if seller:
if bom.product_uom_id.ratio == 0:
raise ValueError(
_(
"El ratio de la unidad de medida del producto '%s' en el BOM es cero. "
"Esto provocaría una división por cero. Verifique la configuración de la UoM."
)
% bom.display_name
)
# Calculate the subcontracting cost
ratio_uom_seller = seller.product_uom.ratio / bom.product_uom_id.ratio
subcontract_price = seller.currency_id._convert(
seller.price, product_currency, company, date, round=False
)
# Add the subcontract price to the total price
price += subcontract_price / ratio_uom_seller

# NO implementamos total va a ser borrado. Ver si implementamos mas adelante (tener en cuenta convertir
# moneda)
# if bom.routing_id:
Expand Down
Loading