Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
191 changes: 191 additions & 0 deletions stock_picking_partner_brand/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

================================
Stock Picking Partner Brand Sync
================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:21d109d64c9a3f8ac534b11caa8c03e70210a7617ec997d55d51c69b7b024887
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fbrand-lightgray.png?logo=github
:target: https://github.com/OCA/brand/tree/19.0/stock_picking_partner_brand
:alt: OCA/brand
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/brand-19-0/brand-19-0-stock_picking_partner_brand
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/brand&target_branch=19.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module is a glue module between ``sale_brand`` and
``partner_brand``.

If the customer has a brand assigned, it will set that brand on the
Sales Order. If the customer has no brand, or if the customer is cleared
from the SO, the brand on the SO will also be cleared.

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
:local:

Use Cases / Context
===================

This module was developed because it is a common use case for
(sub)contractors and other types of businesses to sell products under
different brands.

Installation
============

To install this module, you need to:

1. Place the ``sale_brand`` module in your Odoo addons path.
2. Install the ``partner_brand`` module in Odoo.

It will auto install if all the dependencies are available.

Configuration
=============

1. Configure Brands on Partners: Navigate to Contacts. Open the customer
records for which you want to assign a brand.

2. On the customer form, locate the "Brand" field (provided by
partner_brand) and select the appropriate brand.

3. Save the changes.

Usage
=====

Automatic Brand Setting
-----------------------

When you are on a Stock Picking form:

Selecting a Customer with a Brand:

If you select a customer in the "Customer" (partner_id) field, and that
customer has a brand assigned to them (via the brand_id field on their
contact record), the "Brand" field on the Stock picking will
automatically be populated with the customer's brand.

Selecting a Customer without a Brand:

If you select a customer who does not have a brand assigned to them, the
"Brand" field on the Stock Picking will be automatically cleared (set to
empty/None).

*Changing Customer*:

If you change the customer on an existing picking, the brand on the
picking will update according to the newly selected customer's brand (or
be cleared if the new customer has no brand).

Clearing Customer:

If you clear the "Customer" field on the stock picking (remove the
selected customer), the "Brand" field on the stock picking will also be
automatically cleared.

This behavior is triggered by an onchange mechanism on the partner_id
field of the stock.picking model.

*Manual Override* The automatic setting of the brand based on the
customer is a default behavior. After the brand is automatically
populated (or cleared), you can still manually change or set the brand
on the Stock Picking directly if needed. The onchange mechanism only
triggers when the partner_id field itself is modified.

Known issues / Roadmap
======================



Changelog
=========

18.0.1.0.0 (2025-05-20)
-----------------------

- [ADD] First Release of module.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/brand/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/brand/issues/new?body=module:%20stock_picking_partner_brand%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* O.B.S. Solutions

Contributors
------------

- bosd <c5e2fd43-d292-4c90-9d1f-74ff3436329a@anonaddy.me>
- `Heliconia Solutions Pvt. Ltd. <https://www.heliconia.io>`__

- Bhavesh Heliconia

Other credits
-------------

The development of this module has been financially supported by:

- OBS Solutions B.V.

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-bosd| image:: https://github.com/bosd.png?size=40px
:target: https://github.com/bosd
:alt: bosd

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-bosd|

This module is part of the `OCA/brand <https://github.com/OCA/brand/tree/19.0/stock_picking_partner_brand>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions stock_picking_partner_brand/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
30 changes: 30 additions & 0 deletions stock_picking_partner_brand/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2025 OBS Solutions B.V.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)

{
"name": "Stock Picking Partner Brand Sync",
"summary": """
Automatically sets the brand on a Stock Picking based on the
selected partner's brand.
""",
"version": "19.0.1.0.0",
"development_status": "Alpha",
"category": "Inventory",
"website": "https://github.com/OCA/brand",
"author": "O.B.S. Solutions, Odoo Community Association (OCA)",
"maintainers": ["bosd"],
"license": "AGPL-3",
"application": False,
"installable": True,
"auto_install": True,
"external_dependencies": {
"python": [],
"bin": [],
},
"depends": [
"stock",
"partner_brand",
"stock_brand",
],
"data": [],
}
22 changes: 22 additions & 0 deletions stock_picking_partner_brand/i18n/it.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_picking_partner_brand
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-09-26 18:43+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"

#. module: stock_picking_partner_brand
#: model:ir.model,name:stock_picking_partner_brand.model_stock_picking
msgid "Transfer"
msgstr "Trasferimento"
19 changes: 19 additions & 0 deletions stock_picking_partner_brand/i18n/stock_picking_partner_brand.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_picking_partner_brand
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: stock_picking_partner_brand
#: model:ir.model,name:stock_picking_partner_brand.model_stock_picking
msgid "Transfer"
msgstr ""
1 change: 1 addition & 0 deletions stock_picking_partner_brand/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import stock_picking
117 changes: 117 additions & 0 deletions stock_picking_partner_brand/models/stock_picking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import logging

from odoo import api, models

_logger = logging.getLogger(__name__)


class StockPicking(models.Model):
_inherit = "stock.picking"

@api.onchange("partner_id")
def _onchange_partner_id_set_brand(self):
"""
Onchange method to set the brand_id on the Stock Picking
based on the selected partner's brand or its parent company's brand.
"""
brand_to_set = False

if self.partner_id:
# Determine the partner whose brand should be checked
# Prefer the commercial entity (parent company) if it exists
partner_for_brand_check = (
self.partner_id.commercial_partner_id or self.partner_id
) # noqa

if (
hasattr(partner_for_brand_check, "brand_id")
and partner_for_brand_check.brand_id
): # noqa
brand_to_set = partner_for_brand_check.brand_id
_logger.info(
f"Stock Picking (virtual ID "
"{self._origin.id if self._origin else 'New'}): "
f"Partner '{self.partner_id.name}' selected. "
f"Using brand from '{partner_for_brand_check.name}': "
"'{brand_to_set.name}' (ID: {brand_to_set.id})."
)
else:
_logger.info(
f"Stock Picking (virtual ID "
"{self._origin.id if self._origin else 'New'}): "
f"Partner '{self.partner_id.name}' selected. "
f"Neither partner nor its commercial entity "
"'{partner_for_brand_check.name}' has a brand. Clearing brand."
)
else:
_logger.info(
"Stock Picking (virtual ID "
"{self._origin.id if self._origin else 'New'}): "
"Partner cleared. Clearing brand."
)

# Set or clear the brand_id on the picking
if hasattr(self, "brand_id"):
self.brand_id = brand_to_set
else:
# This case should ideally not happen if stock_brand is correctly installed
if self.partner_id:
_logger.warning(
"Stock Picking model does not have a 'brand_id' field. "
"Is 'stock_brand' module installed and loaded correctly?"
)

@api.model_create_multi
def create(self, vals_list):
"""
Override create to ensure brand_id is set from partner_id
(or its commercial entity)
if provided during direct creation, and not already set in vals.
"""
for vals in vals_list:
# Only attempt to set brand_id if partner_id is provided and brand_id is not
# already in vals
if vals.get("partner_id") and "brand_id" not in vals:
partner = self.env["res.partner"].browse(vals.get("partner_id"))
if partner.exists():
# Determine the partner whose brand should be checked
partner_for_brand_check = partner.commercial_partner_id or partner

if (
hasattr(partner_for_brand_check, "brand_id")
and partner_for_brand_check.brand_id
): # noqa
# Check if the stock.picking model (self) has brand_id field
if "brand_id" in self._fields:
vals["brand_id"] = partner_for_brand_check.brand_id.id
_logger.info(
f"Create Stock Picking: Partner"
" '{partner.name}' provided. "
f"Using brand from '{partner_for_brand_check.name}': "
"'{partner_for_brand_check.brand_id.name}'. "
f"Setting brand_id in creation vals."
)
else:
_logger.warning(
"Stock Picking model does not have a 'brand_id' "
"field during create. "
"Is 'stock_brand' module installed?"
)
else:
_logger.info(
f"Create Stock Picking: Partner '{partner.name}' provided. "
f"Neither partner nor its commercial entity "
"'{partner_for_brand_check.name}' has a brand. "
f"brand_id not set from partner."
)

records = super().create(vals_list)

# The onchange logic might also be triggered after creation if
# partner_id is set,
# but explicitly handling it here ensures it's
# set during the initial create call
# if possible. Re-triggering onchange or a direct write post-create is generally
# less efficient if it can be handled in the initial vals.

return records
3 changes: 3 additions & 0 deletions stock_picking_partner_brand/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
7 changes: 7 additions & 0 deletions stock_picking_partner_brand/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1. Configure Brands on Partners:
Navigate to Contacts.
Open the customer records for which you want to assign a brand.

2. On the customer form, locate the "Brand" field (provided by partner_brand) and select the appropriate brand.

3. Save the changes.
Loading
Loading