-
-
Notifications
You must be signed in to change notification settings - Fork 239
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ADD] stock_negative_alert_by_email: manage negative in stock via ema…
…il alert
- Loading branch information
Showing
15 changed files
with
810 additions
and
0 deletions.
There are no files selected for viewing
1 change: 1 addition & 0 deletions
1
setup/alert_email_negative_stock/odoo/addons/alert_email_negative_stock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../alert_email_negative_stock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import setuptools | ||
|
||
setuptools.setup( | ||
setup_requires=['setuptools-odoo'], | ||
odoo_addon=True, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
============================= | ||
Stock Negative Alert by Email | ||
============================= | ||
|
||
.. | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! This file is generated by oca-gen-addon-readme !! | ||
!! changes will be overwritten. !! | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! source digest: sha256:e332df0f9658b9291684a651820c53442974e320557806f51d7507b31b6d4be4 | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png | ||
:target: https://odoo-community.org/page/development-status | ||
:alt: Beta | ||
.. |badge2| image:: https://img.shields.io/badge/licence-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%2Fstock--logistics--reporting-lightgray.png?logo=github | ||
:target: https://github.com/OCA/stock-logistics-reporting/tree/14.0/stock_negative_alert_by_email | ||
:alt: OCA/stock-logistics-reporting | ||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png | ||
:target: https://translation.odoo-community.org/projects/stock-logistics-reporting-14-0/stock-logistics-reporting-14-0-stock_negative_alert_by_email | ||
: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/stock-logistics-reporting&target_branch=14.0 | ||
:alt: Try me on Runboat | ||
|
||
|badge1| |badge2| |badge3| |badge4| |badge5| | ||
|
||
This module adds possibility to manage negative in stock via email alert. | ||
|
||
On `Inventory` configuration, you can set a email alerts, alert intervals, and stock quantity type to check. | ||
|
||
This helps ensure proper stock management by notifying relevant parties when stock levels fall below zero. | ||
|
||
**Table of contents** | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-reporting/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/stock-logistics-reporting/issues/new?body=module:%20stock_negative_alert_by_email%0Aversion:%2014.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 | ||
~~~~~~~ | ||
|
||
* Giuseppe Borruso - Dinamiche Aziendali srl | ||
|
||
Contributors | ||
~~~~~~~~~~~~ | ||
|
||
* Giuseppe Borruso - Dinamiche Aziendali srl <[email protected]> | ||
|
||
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. | ||
|
||
This module is part of the `OCA/stock-logistics-reporting <https://github.com/OCA/stock-logistics-reporting/tree/14.0/stock_negative_alert_by_email>`_ project on GitHub. | ||
|
||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Copyright (C) 2025-Today: | ||
# Dinamiche Aziendali Srl (<http://www.dinamicheaziendali.it/>) | ||
# @author: Giuseppe Borruso <[email protected]> | ||
# License GPL-3.0 or later (http://www.gnu.org/licenses/gpl.html). | ||
|
||
{ | ||
"name": "Stock Negative Alert by Email", | ||
"version": "14.0.1.0.0", | ||
"summary": "Manage negative in stock via email alert", | ||
"author": "Giuseppe Borruso - Dinamiche Aziendali srl, Odoo Community Association (OCA)", | ||
"website": "https://github.com/OCA/stock-logistics-reporting", | ||
"category": "Warehouse Management", | ||
"license": "AGPL-3", | ||
"depends": [ | ||
"base", | ||
"stock", | ||
], | ||
"data": [ | ||
"data/ir_cron_data.xml", | ||
"views/res_config_setting_view.xml", | ||
], | ||
"installable": True, | ||
"images": ["static/description/icon.png"], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<odoo> | ||
<data noupdate="1"> | ||
|
||
<record id="ir_cron_action_negative_stock" model="ir.cron"> | ||
<field name="name">Action Negative Stock</field> | ||
<field name="user_id" ref="base.user_admin" /> | ||
<field name="interval_type">hours</field> | ||
<field name="interval_number">24</field> | ||
<field name="numbercall">-1</field> | ||
<field name="model_id" ref="stock.model_stock_move" /> | ||
<field name="code">model.action_negative_stock()</field> | ||
</record> | ||
|
||
</data> | ||
</odoo> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from . import res_company | ||
from . import res_config_settings | ||
from . import stock_move |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Copyright (C) 2025-Today: | ||
# Dinamiche Aziendali Srl (<http://www.dinamicheaziendali.it/>) | ||
# @author: Giuseppe Borruso <[email protected]> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import fields, models | ||
|
||
|
||
class ResCompanyInherit(models.Model): | ||
_inherit = "res.company" | ||
|
||
negative_stock_mail_from = fields.Char() | ||
negative_stock_mail_to = fields.Char() | ||
negative_stock_interval_number = fields.Integer() | ||
negative_stock_interval_type = fields.Selection( | ||
[ | ||
("minutes", "Minutes"), | ||
("hours", "Hours"), | ||
("days", "Days"), | ||
("weeks", "Weeks"), | ||
], | ||
) | ||
negative_stock_quantity_type = fields.Selection( | ||
[ | ||
("qty_available", "Quantity On Hand"), | ||
("virtual_available", "Forecast Quantity"), | ||
], | ||
default="qty_available", | ||
) |
31 changes: 31 additions & 0 deletions
31
stock_negative_alert_by_email/models/res_config_settings.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Copyright (C) 2025-Today: | ||
# Dinamiche Aziendali Srl (<http://www.dinamicheaziendali.it/>) | ||
# @author: Giuseppe Borruso <[email protected]> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import fields, models | ||
|
||
|
||
class ResConfigSettingInherit(models.TransientModel): | ||
_inherit = "res.config.settings" | ||
|
||
negative_stock_mail_from = fields.Char( | ||
related="company_id.negative_stock_mail_from", | ||
readonly=False, | ||
) | ||
negative_stock_mail_to = fields.Char( | ||
related="company_id.negative_stock_mail_to", | ||
readonly=False, | ||
) | ||
negative_stock_interval_number = fields.Integer( | ||
related="company_id.negative_stock_interval_number", | ||
readonly=False, | ||
) | ||
negative_stock_interval_type = fields.Selection( | ||
related="company_id.negative_stock_interval_type", | ||
readonly=False, | ||
) | ||
negative_stock_quantity_type = fields.Selection( | ||
related="company_id.negative_stock_quantity_type", | ||
readonly=False, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Copyright (C) 2025-Today: | ||
# Dinamiche Aziendali Srl (<http://www.dinamicheaziendali.it/>) | ||
# @author: Giuseppe Borruso <[email protected]> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from datetime import timedelta | ||
|
||
from odoo import _, api, fields, models | ||
|
||
|
||
class StockMoveInherit(models.Model): | ||
_inherit = "stock.move" | ||
|
||
@api.model | ||
def _compute_domain_negative_stock(self, company): | ||
interval_number = company.negative_stock_interval_number | ||
interval_type = company.negative_stock_interval_type | ||
if not (interval_number or interval_type): | ||
return False | ||
|
||
date_end = fields.Datetime.now() | ||
if interval_type == "minutes": | ||
date_start = fields.Datetime.now() - timedelta(minutes=interval_number) | ||
elif interval_type == "hours": | ||
date_start = fields.Datetime.now() - timedelta(hours=interval_number) | ||
elif interval_type == "days": | ||
date_start = fields.Datetime.now() - timedelta(days=interval_number) | ||
else: | ||
date_start = fields.Datetime.now() - timedelta(weeks=interval_number) | ||
return [ | ||
("write_date", ">", date_start), | ||
("write_date", "<", date_end), | ||
("company_id", "=", company.id), | ||
] | ||
|
||
@api.model | ||
def _compute_table_products_negative_stock(self, products, company): | ||
quantity_type = company.negative_stock_quantity_type | ||
table_products = _( | ||
""" | ||
<table class="table table-sm"> | ||
<thead> | ||
<tr> | ||
<th name="th_product">Product</th> | ||
<th name="th_%(quantity_type)s">%(quantity_type_name)s</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
""" | ||
% { | ||
"quantity_type": quantity_type, | ||
"quantity_type_name": ( | ||
"Quantity On Hand" | ||
if quantity_type == "qty_available" | ||
else "Forecast Quantity" | ||
), | ||
} | ||
) | ||
for product in products: | ||
if quantity_type == "qty_available": | ||
product_quantity = product.with_company(company.id).qty_available | ||
else: | ||
product_quantity = product.with_company(company.id).virtual_available | ||
if product_quantity >= 0: | ||
continue | ||
table_products += f""" | ||
<tr> | ||
<td name="product">{product.display_name}</td> | ||
<td name="{quantity_type}">{product_quantity}</td> | ||
</tr> | ||
""" | ||
table_products += """ | ||
</tbody> | ||
</table> | ||
""" | ||
return table_products | ||
|
||
@api.model | ||
def _compute_body_htm_negative_stock(self, products, company): | ||
return _( | ||
""" | ||
<p>Dear</p> | ||
<br /> | ||
<p> | ||
We would like to inform you that negative quantities have been | ||
detected in the warehouse for the following items: | ||
</p> | ||
<br /> | ||
%(table_products)s | ||
<p> | ||
We kindly ask you to take immediate action to rectify this situation | ||
in order to ensure proper stock management and avoid any | ||
inconveniences. | ||
</p> | ||
<br /><br /> | ||
<p>Kind regards,</p> | ||
<p>%(company)s</p> | ||
""" | ||
% { | ||
"table_products": self._compute_table_products_negative_stock( | ||
products, company | ||
), | ||
"company": company.display_name, | ||
} | ||
) | ||
|
||
def action_negative_stock(self): | ||
for company in self.env["res.company"].search([]): | ||
record = self.sudo().with_company(company.id) | ||
domain = record._compute_domain_negative_stock(company) | ||
if isinstance(domain, bool): | ||
continue | ||
products = record.search(domain).mapped("product_id") | ||
mail_from = company.negative_stock_mail_from or self.env.user.email | ||
mail_to = company.negative_stock_mail_to | ||
if products and mail_from and mail_to: | ||
mail = self.env["mail.mail"].create( | ||
{ | ||
"subject": "Negative Stock Alert", | ||
"email_from": mail_from, | ||
"email_to": mail_to, | ||
"body_html": record._compute_body_htm_negative_stock( | ||
products, company | ||
), | ||
} | ||
) | ||
mail.send() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* Giuseppe Borruso - Dinamiche Aziendali srl <[email protected]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
This module adds possibility to manage negative in stock via email alert. | ||
|
||
On `Inventory` configuration, you can set a email alerts, alert intervals, and stock quantity type to check. | ||
|
||
This helps ensure proper stock management by notifying relevant parties when stock levels fall below zero. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.