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
15 changes: 2 additions & 13 deletions .github/workflows/auto-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,16 @@ jobs:
TARGET_BRANCH: "18.0"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Obține primul commit al branch-ului relativ la 18.0
FIRST_COMMIT=$(git rev-list "$TARGET_BRANCH"..HEAD --reverse | head -n1)

# Titlul PR = prima linie a commit-ului
PR_TITLE=$(git log -1 --format=%s "$FIRST_COMMIT")

# Body PR = mesajul complet al commit-ului
PR_BODY=$(git log -1 --format=%b "$FIRST_COMMIT")
PR_BODY="PR creat automat pentru branch-ul $NEW_BRANCH\n\n$PR_BODY"

# Creează PR și obține numărul
PR_NUM=$(gh pr create \
--base "$TARGET_BRANCH" \
--head "$NEW_BRANCH" \
--title "[$TARGET_BRANCH] $PR_TITLE" \
--body "$PR_BODY" | awk '{print $2}' | tr -d '#')
--title "[$TARGET_BRANCH] $NEW_BRANCH " \
--body "PR creat automat pentru branch-ul $NEW_BRANCH" | awk '{print $2}' | tr -d '#')

echo "PR_NUM=$PR_NUM" >> $GITHUB_OUTPUT
echo "Created PR #$PR_NUM"


- name: Comment on PR
env:
CHECK_PR_NUM: ${{ steps.check_pr.outputs.PR_NUM }}
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
push:
branches:
- "18.0"
workflow_run:
workflows: ["Auto PR for 18.0 Branches"]
types:
- completed


jobs:
Expand Down
53 changes: 53 additions & 0 deletions deltatech_procurement_team/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
================
Sale Team Access
================

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

.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
:target: https://odoo-community.org/page/development-status
:alt: Production/Stable
.. |badge2| image:: https://img.shields.io/badge/github-dhongu%2Fdeltatech-lightgray.png?logo=github
:target: https://github.com/dhongu/deltatech/tree/18.0/deltatech_sale_team
:alt: dhongu/deltatech

|badge1| |badge2|

- Features:

- Restricting access to sales team

**Table of contents**

.. contents::
:local:

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

Bugs are tracked on `Terrabit Issues <https://www.terrabit.ro/helpdesk>`_.
In case of trouble, please check there if your issue has already been reported.

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

Credits
=======

Authors
-------

* Terrabit
* Dorin Hongu

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

This module is part of the `dhongu/deltatech <https://github.com/dhongu/deltatech/tree/18.0/deltatech_sale_team>`_ project on GitHub.

You are welcome to contribute.
5 changes: 5 additions & 0 deletions deltatech_procurement_team/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# © 2025 Deltatech
# Dorin Hongu <dhongu(@)gmail(.)com
# See README.rst file on addons root folder for license details

from . import models
18 changes: 18 additions & 0 deletions deltatech_procurement_team/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# © 2025 Deltatech
# Dorin Hongu <dhongu(@)gmail(.)com
# See README.rst file on addons root folder for license details

{
"name": "Deltatech Procurement Team",
"version": "18.0.1.0.0",
"category": "Inventory",
"summary": "Generate Purchase Orders per Sales Team using procurement groups",
"author": "Terrabit, Dorin Hongu",
"website": "https://www.terrabit.ro",
"depends": ["sales_team", "account", "stock", "sale_stock", "purchase", "purchase_stock"],
"license": "OPL-1",
"data": [],
"development_status": "Production/Stable",
"images": ["static/description/main_screenshot.png"],
"installable": True,
}
8 changes: 8 additions & 0 deletions deltatech_procurement_team/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# © 2025 Deltatech
# Dorin Hongu <dhongu(@)gmail(.)com
# See README.rst file on addons root folder for license details

from . import sale_order
from . import procurement_group
from . import stock_rule
from . import purchase_order
11 changes: 11 additions & 0 deletions deltatech_procurement_team/models/procurement_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# © 2025 Deltatech
# Dorin Hongu <dhongu(@)gmail(.)com
# See README.rst file on addons root folder for license details

from odoo import fields, models


class ProcurementGroup(models.Model):
_inherit = "procurement.group"

team_id = fields.Many2one("crm.team", string="Sales Team")
11 changes: 11 additions & 0 deletions deltatech_procurement_team/models/purchase_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# © 2025 Deltatech
# Dorin Hongu <dhongu(@)gmail(.)com
# See README.rst file on addons root folder for license details

from odoo import fields, models


class PurchaseOrder(models.Model):
_inherit = "purchase.order"

team_id = fields.Many2one("crm.team", string="Sales Team", index=True, copy=False)
15 changes: 15 additions & 0 deletions deltatech_procurement_team/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# © 2025 Deltatech
# Dorin Hongu <dhongu(@)gmail(.)com
# See README.rst file on addons root folder for license details


from odoo import models


class SaleOrderLine(models.Model):
_inherit = "sale.order.line"

def _prepare_procurement_group_vals(self):
vals = super()._prepare_procurement_group_vals()
vals["team_id"] = self.order_id.team_id.id
return vals
42 changes: 42 additions & 0 deletions deltatech_procurement_team/models/stock_rule.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from odoo import models


class StockRule(models.Model):
_inherit = "stock.rule"

def _get_team_from_values(self, values):
group = values.get("group_id")
if group:
return group.team_id.id

return False

def _make_po_get_domain(self, company_id, values, partner):
# Extend the standard domain so that POs are split per Sales Team when provided
domain = super()._make_po_get_domain(company_id, values, partner)
team_id = self._get_team_from_values(values)
if team_id:
domain += (("team_id", "=", team_id),)
return domain

def _prepare_purchase_order(self, company_id, origins, values_list):
# values_list is a list of values (one per procurement) for the same PO domain
vals = super()._prepare_purchase_order(company_id, origins, values_list)
# Try to get team_id from the first values dict
team_id = False
if values_list:
team_id = self._get_team_from_values(values_list[0])
if team_id:
vals["team_id"] = team_id
return vals

# def _make_po(self, product_id, procurement_values, po_company_id, origin=None, values=None):
# # Call standard logic to get/create the PO
# po = super()._make_po(product_id, procurement_values, po_company_id, origin, values)
#
# # Assign Sales Team on PO if provided or derivable from procurement
# team_id = self._get_team_from_values(procurement_values)
# if team_id and po.team_id.id != team_id:
# po.team_id = team_id
#
# return po
3 changes: 3 additions & 0 deletions deltatech_procurement_team/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
40 changes: 40 additions & 0 deletions deltatech_procurement_team/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Deltatech Procurement Team

Purpose
- This module ensures that Purchase Orders (RFQs) generated from Sales Orders are split per Sales Team when they target the same vendor. It enables reporting, filtering, and approval flows per team while keeping the standard procurement flow intact.

Features
- Propagates `team_id` from Sales Order to procurement and then to Purchase Orders.
- Extends PO grouping domain so procurements from different Sales Teams never merge into a single PO.
- Stores `team_id` on `purchase.order` for visibility and analysis.
- Works with Buy + MTO and MTS else MTO flows; compatible with orderpoints (reordering rules).
- No impact on replenishments not originating from Sales Orders (those typically have no team and keep default grouping).

How it works
- `sale.order.line._prepare_procurement_values` injects the order's `team_id` into procurement values.
- `procurement.group` keeps team as a grouping key so similar procurements are aggregated within the same team.
- `stock.rule` customizations:
- `_make_po_get_domain` adds `('team_id', '=', team_id)` when available to split PO per team.
- `_prepare_purchase_order` sets `team_id` on PO creation values.
- `purchase.order` gains a `team_id` field.

Configuration
- Ensure your sellable products have a vendor and appropriate routes (e.g., Buy + MTO or MTS else MTO).
- Optional: create reordering rules if you also want planning via orderpoints.
- Install the module and (optionally) add `team_id` to PO list/form views using Studio or a custom view for filtering/reporting.

Usage
- Create Sales Orders assigned to different Sales Teams using products from the same vendor.
- Confirm the orders and run the scheduler; the system will create one draft RFQ per team for that vendor.

Compatibility
- Odoo 18. Depends on `sales_team`, `stock`, `sale_stock`, `purchase`, `purchase_stock`.
- Multi-company aware; POs are always created in the correct company.

Testing
- Includes a test that creates 4 SOs (2 per team) for the same vendor and verifies that exactly 2 RFQs are created (one per team), with aggregated quantities.

Maintainer
- Deltatech / Terrabit — Dorin Hongu


Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading