Move all OCA POS modules from oca-technical to dedicated oca-pos submodule

Reorganized 74 POS-related modules for better structure:
- Moved all odoo-bringout-oca-pos-* packages from packages/oca-technical/
- Now organized in dedicated packages/oca-pos/ submodule
- Includes payment, receipt, loyalty, order, product, and partner modules
- Maintains all module functionality while improving project organization

This creates a cleaner separation between general technical modules
and Point of Sale specific functionality.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ernad Husremovic 2025-08-30 17:15:35 +02:00
parent 3791451dc1
commit 377f346a99
2675 changed files with 93308 additions and 0 deletions

View file

@ -0,0 +1,48 @@
# Point of Sale Stock Available Online
Odoo addon: pos_stock_available_online
## Installation
```bash
pip install odoo-bringout-oca-pos-pos_stock_available_online
```
## Dependencies
This addon depends on:
- point_of_sale
- stock_available
- base_automation
## Manifest Information
- **Name**: Point of Sale Stock Available Online
- **Version**: 16.0.2.0.3
- **Category**: Sales/Point of Sale
- **License**: AGPL-3
- **Installable**: True
## Source
Based on [OCA/pos](https://github.com/OCA/pos) branch 16.0, addon `pos_stock_available_online`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Reports: doc/REPORTS.md
- Security: doc/SECURITY.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Pos_stock_available_online Module - pos_stock_available_online
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for pos_stock_available_online. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,7 @@
# Dependencies
This addon depends on:
- [point_of_sale](https://github.com/bringout/oca-ocb-sale/tree/681dc8d5fff638cb0862a34e48091a2098d091f8/odoo-bringout-oca-ocb-point_of_sale)
- [stock_available](https://github.com/bringout/oca-technical)
- [base_automation](https://github.com/bringout/oca-ocb-core/tree/b3e6fb998e53b9eb1bc9669d992017616c2bd7b3/odoo-bringout-oca-ocb-base_automation)

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon pos_stock_available_online or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-pos-pos_stock_available_online"
# or
uv pip install odoo-bringout-oca-pos-pos_stock_available_online"
```

View file

@ -0,0 +1,18 @@
# Models
Detected core models and extensions in pos_stock_available_online.
```mermaid
classDiagram
class stock_move
class stock_notifier_pos_mixin
class stock_quant
class pos_config
class pos_session
class res_config_settings
class stock_warehouse
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: pos_stock_available_online. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon pos_stock_available_online
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,8 @@
# Security
This module does not define custom security rules or access controls beyond Odoo defaults.
Default Odoo security applies:
- Base user access through standard groups
- Model access inherited from dependencies
- No custom row-level security rules

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon pos_stock_available_online
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,107 @@
====================================
Point of Sale Stock Available Online
====================================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:d544301c362e728a3cab17fa70bc08796bb02c4435dd0edf4ed2df4a4376d1c1
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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%2Fpos-lightgray.png?logo=github
:target: https://github.com/OCA/pos/tree/16.0/pos_stock_available_online
:alt: OCA/pos
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/pos-16-0/pos-16-0-pos_stock_available_online
: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/pos&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module allows to display product quantities in selected locations in real time. Quantities are displayed directly on product tiles:
.. image:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_stock_available_online/static/img/pos_quantity.png
Once a product quantity is changed it will be simultaneously updated in all active POS.
This module depends on stock_available module which is available in https://github.com/OCA/stock-logistics-availability repo.
**Table of contents**
.. contents::
:local:
Configuration
=============
In "Point of Sale" configuration "Product Quantity" section activate "Display Product Quantity" feature:
.. image:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_stock_available_online/static/img/pos_config.png
By default quantity is displayed for the warehouse that is used in the POS stock operation type.
You can add additional warehouses to show quantity in by adding them into "Additional Warehouses" field.
In this case the following information will be displayed on product tiles:
- Total quantity = quantity in the default warehouse + quantity in the additional warehouses
- Quantity in the default warehouse
- Quantity in the additional warehouses.
Known issues / Roadmap
======================
This module requires connection to update quantities and doesn't support offline mode.
Warehouses must belong to the same company as POS.
Offline mode support (probably additional module).
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/pos/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/pos/issues/new?body=module:%20pos_stock_available_online%0Aversion:%2016.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
~~~~~~~
* Cetmix
Contributors
~~~~~~~~~~~~
* Cetmix <https://cetmix.com/>
* Dinar Gabbasov
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/pos <https://github.com/OCA/pos/tree/16.0/pos_stock_available_online>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -0,0 +1 @@
from . import models

View file

@ -0,0 +1,20 @@
{
"name": "Point of Sale Stock Available Online",
"version": "16.0.2.0.3",
"category": "Sales/Point of Sale",
"summary": "Show the available quantity of products in the Point of Sale ",
"depends": ["point_of_sale", "stock_available", "base_automation"],
"website": "https://github.com/OCA/pos",
"author": "Cetmix, Odoo Community Association (OCA)",
"images": ["static/description/banner.png"],
"installable": True,
"data": ["views/res_config_settings_view.xml"],
"assets": {
"point_of_sale.assets": [
"pos_stock_available_online/static/src/css/**/*.css",
"pos_stock_available_online/static/src/js/**/*.js",
"pos_stock_available_online/static/src/xml/**/*.xml",
],
},
"license": "AGPL-3",
}

View file

@ -0,0 +1,121 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_stock_available_online
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.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: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__additional_warehouse_ids
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_additional_warehouse_ids
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Additional Warehouses"
msgstr "Dodatno Skladišta"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_res_config_settings
msgid "Config Settings"
msgstr "Postavke"
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__display_product_quantity
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_display_product_quantity
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Display Product Quantity"
msgstr "Prikaži Proizvod Količina"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Display the quantity of available products in the POS for"
msgstr "Prikaži količinu dostupnih proizvoda u POS sistemu za"
#. module: pos_stock_available_online
#: model:ir.model.fields,help:pos_stock_available_online.field_pos_config__additional_warehouse_ids
#: model:ir.model.fields,help:pos_stock_available_online.field_res_config_settings__pos_additional_warehouse_ids
msgid ""
"For the selected warehouses will be displayed quantity of available products"
" in the POS"
msgstr ""
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__main_warehouse_id
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_main_warehouse_id
msgid "Main Warehouse"
msgstr "Main Skladište"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Mark quantity red if below or equal this value."
msgstr "Označi količinu crvenom bojom ako je ispod ili jednaka ovoj vrijednosti."
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__minimum_product_quantity_alert
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_minimum_product_quantity_alert
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Minimum Product Quantity Alert"
msgstr "Minimum Proizvod Količina Alert"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_pos_config
msgid "Point of Sale Configuration"
msgstr "Postavke prodajnog mjesta"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_pos_session
msgid "Point of Sale Session"
msgstr "Sesija POS-a"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Product Quantity"
msgstr "Količina proizvoda"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_quant
msgid "Quants"
msgstr "Količine"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Show quantity in the following warehouses in additional to"
msgstr "Prikaži količinu u sljedećim skladištima dodatno na"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_move
msgid "Stock Move"
msgstr "Skladišno kretanje"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_notifier_pos_mixin
msgid "Stock Notifier POS Mixin"
msgstr "Mješavina POS obavještavača zaliha"
#. module: pos_stock_available_online
#. odoo-javascript
#: code:addons/pos_stock_available_online/static/src/xml/Screens/ProductScreen/ProductItem.xml:0
#, python-format
msgid "Total"
msgstr "Ukupno"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_warehouse
msgid "Warehouse"
msgstr "Skladište"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Warehouses must belong to the same company as POS."
msgstr "Skladišta moraju pripadati istoj kompaniji kao POS."
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "warehouse"
msgstr "Skladište"

View file

@ -0,0 +1,126 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_stock_available_online
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-10-24 11:06+0000\n"
"Last-Translator: Daniel Duque <danieldqmrt@gmail.com>\n"
"Language-Team: none\n"
"Language: es\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.6.2\n"
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__additional_warehouse_ids
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_additional_warehouse_ids
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Additional Warehouses"
msgstr "Almacenes Adicionales"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_res_config_settings
msgid "Config Settings"
msgstr "Ajustes de Configuración"
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__display_product_quantity
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_display_product_quantity
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Display Product Quantity"
msgstr "Mostrar Cantidad de Productos"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Display the quantity of available products in the POS for"
msgstr "Mostrar la cantidad de productos disponibles en el TPV para"
#. module: pos_stock_available_online
#: model:ir.model.fields,help:pos_stock_available_online.field_pos_config__additional_warehouse_ids
#: model:ir.model.fields,help:pos_stock_available_online.field_res_config_settings__pos_additional_warehouse_ids
msgid ""
"For the selected warehouses will be displayed quantity of available products "
"in the POS"
msgstr ""
"Para los almacenes seleccionados se mostrará la cantidad de productos "
"disponibles en el TPV"
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__main_warehouse_id
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_main_warehouse_id
msgid "Main Warehouse"
msgstr ""
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Mark quantity red if below or equal this value."
msgstr "Marque la cantidad en rojo si es inferior o igual a este valor."
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__minimum_product_quantity_alert
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_minimum_product_quantity_alert
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Minimum Product Quantity Alert"
msgstr "Alerta de Cantidad Mínima de Producto"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_pos_config
msgid "Point of Sale Configuration"
msgstr "Configuración del Punto de Venta"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_pos_session
msgid "Point of Sale Session"
msgstr "Sesiones del Punto de Venta"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Product Quantity"
msgstr "Cantidad de Productos"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_quant
msgid "Quants"
msgstr "Quants"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Show quantity in the following warehouses in additional to"
msgstr "Indicar la cantidad en los siguientes almacenes además de"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_move
msgid "Stock Move"
msgstr ""
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_notifier_pos_mixin
msgid "Stock Notifier POS Mixin"
msgstr ""
#. module: pos_stock_available_online
#. odoo-javascript
#: code:addons/pos_stock_available_online/static/src/xml/Screens/ProductScreen/ProductItem.xml:0
#, python-format
msgid "Total"
msgstr "Total"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_warehouse
msgid "Warehouse"
msgstr "Almacén"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Warehouses must belong to the same company as POS."
msgstr "Los almacenes deben pertenecer a la misma compañía que el TPV."
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "warehouse"
msgstr "almacén"

View file

@ -0,0 +1,126 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_stock_available_online
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-02-21 18:06+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.6.2\n"
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__additional_warehouse_ids
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_additional_warehouse_ids
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Additional Warehouses"
msgstr "Magazzini aggiuntivi"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_res_config_settings
msgid "Config Settings"
msgstr "Impostazioni configurazione"
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__display_product_quantity
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_display_product_quantity
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Display Product Quantity"
msgstr "Visualizza quantità prdotto"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Display the quantity of available products in the POS for"
msgstr "Visualizza la quantità dei prodotti disponibili nel POS per"
#. module: pos_stock_available_online
#: model:ir.model.fields,help:pos_stock_available_online.field_pos_config__additional_warehouse_ids
#: model:ir.model.fields,help:pos_stock_available_online.field_res_config_settings__pos_additional_warehouse_ids
msgid ""
"For the selected warehouses will be displayed quantity of available products "
"in the POS"
msgstr ""
"Per il magazzino selezionato verrà visualizzata nel POS la quantità "
"disponibile del prodotto"
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__main_warehouse_id
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_main_warehouse_id
msgid "Main Warehouse"
msgstr "Magazzino principale"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Mark quantity red if below or equal this value."
msgstr "Evidenzia in rosso la quantità se inferiore o uguale a questo valore."
#. module: pos_stock_available_online
#: model:ir.model.fields,field_description:pos_stock_available_online.field_pos_config__minimum_product_quantity_alert
#: model:ir.model.fields,field_description:pos_stock_available_online.field_res_config_settings__pos_minimum_product_quantity_alert
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Minimum Product Quantity Alert"
msgstr "Allerta quantità minima prodotto"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_pos_config
msgid "Point of Sale Configuration"
msgstr "Configurazione punto vendita"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_pos_session
msgid "Point of Sale Session"
msgstr "Sessione punto vendita"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Product Quantity"
msgstr "Quantità prodotto"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_quant
msgid "Quants"
msgstr "Quanti"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Show quantity in the following warehouses in additional to"
msgstr "Mostra le quantità nei magazzini seguenti in aggiunta a"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_move
msgid "Stock Move"
msgstr "Movimento di magazzino"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_notifier_pos_mixin
msgid "Stock Notifier POS Mixin"
msgstr "Mixin POS avvisatore giacenza"
#. module: pos_stock_available_online
#. odoo-javascript
#: code:addons/pos_stock_available_online/static/src/xml/Screens/ProductScreen/ProductItem.xml:0
#, python-format
msgid "Total"
msgstr "Totale"
#. module: pos_stock_available_online
#: model:ir.model,name:pos_stock_available_online.model_stock_warehouse
msgid "Warehouse"
msgstr "Magazzino"
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "Warehouses must belong to the same company as POS."
msgstr "Il magazzino deve appartenere alla stessa azienda del POS."
#. module: pos_stock_available_online
#: model_terms:ir.ui.view,arch_db:pos_stock_available_online.res_config_settings_view_form
msgid "warehouse"
msgstr "magazzino"

View file

@ -0,0 +1,7 @@
from . import pos_config
from . import pos_session
from . import res_config_settings
from . import stock_notifier_pos_mixin
from . import stock_quant
from . import stock_warehouse
from . import stock_move

View file

@ -0,0 +1,54 @@
import logging
from odoo import fields, models
_logger = logging.getLogger(__name__)
class PosConfig(models.Model):
_inherit = "pos.config"
display_product_quantity = fields.Boolean(
default=True,
)
main_warehouse_id = fields.Many2one(
"stock.warehouse",
string="Main Warehouse",
related="picking_type_id.warehouse_id",
store=True,
)
additional_warehouse_ids = fields.Many2many(
"stock.warehouse",
"pos_config_stock_warehouse_rel",
"pos_config_id",
"warehouse_id",
string="Additional Warehouses",
domain="[('company_id', '=', company_id)]",
help="For the selected warehouses will be displayed "
"quantity of available products in the POS",
)
minimum_product_quantity_alert = fields.Float(
default=0.0,
)
def _get_channel_name(self):
"""
Return full channel name as combination, POS Config ID and const CHANNEL
"""
self.ensure_one()
return '["{}","{}"]'.format("pos_stock_available_online", self.id)
def _notify_available_quantity(self, message):
"""
Notify POSes about product updates
"""
if not isinstance(message, list):
message = [message]
notifications = []
for config in self:
notifications.append(
[config._get_channel_name(), "pos.config/product_update", message]
)
if notifications:
self.env["bus.bus"]._sendmany(notifications)
_logger.debug("POS notifications for %s: %s", self.ids, notifications)

View file

@ -0,0 +1,22 @@
from odoo import models
class PosSession(models.Model):
_inherit = "pos.session"
def _process_pos_ui_product_product(self, products):
config = self.config_id
if config.display_product_quantity:
product_obj = self.env["product.product"]
for product_info in products:
product = product_obj.browse(product_info["id"])
# prepared first main warehouse info
warehouse_info = [
config.main_warehouse_id._prepare_vals_for_pos(product)
]
# prepared additional warehouses info
for warehouse in config.additional_warehouse_ids:
warehouse_info.append(warehouse._prepare_vals_for_pos(product))
product_info["warehouse_info"] = warehouse_info
return super()._process_pos_ui_product_product(products)

View file

@ -0,0 +1,23 @@
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
pos_display_product_quantity = fields.Boolean(
related="pos_config_id.display_product_quantity",
readonly=False,
)
pos_main_warehouse_id = fields.Many2one(
"stock.warehouse",
related="pos_config_id.main_warehouse_id",
)
pos_additional_warehouse_ids = fields.Many2many(
"stock.warehouse",
related="pos_config_id.additional_warehouse_ids",
readonly=False,
)
pos_minimum_product_quantity_alert = fields.Float(
related="pos_config_id.minimum_product_quantity_alert",
readonly=False,
)

View file

@ -0,0 +1,30 @@
from odoo import models
class StockMove(models.Model):
_name = "stock.move"
_inherit = ["stock.move", "stock.notifier.pos.mixin"]
def write(self, vals):
states_dict = {line.id: line.state for line in self} if "state" in vals else {}
res = super().write(vals)
if not states_dict:
return res
for line in self:
if states_dict.get(line.id) != line.state:
line._notify_pos()
return res
def _action_done(self, cancel_backorder=False):
# As stock will be updated once move has updated its state, skip
# notification from quant
return super(
StockMove, self.with_context(skip_quant_notify_pos=True)
)._action_done(cancel_backorder=cancel_backorder)
def _get_warehouses_to_notify(self):
warehouses = super()._get_warehouses_to_notify()
warehouses |= self.warehouse_id
warehouses |= self.location_id.warehouse_id
warehouses |= self.location_dest_id.warehouse_id
return warehouses

View file

@ -0,0 +1,46 @@
from odoo import models
class StockNotifierPosMixin(models.AbstractModel):
_name = "stock.notifier.pos.mixin"
_description = "Stock Notifier POS Mixin"
def _skip_notify_pos(self):
"""
Skip notification to POS
"""
return False
def _get_warehouses_to_notify(self):
self.ensure_one()
return self.env["stock.warehouse"]
def _notify_pos(self):
"""
Send notification to POS
"""
pos_session_obj = self.env["pos.session"]
for record in self:
if record._skip_notify_pos():
continue
for warehouse in record._get_warehouses_to_notify():
configs = pos_session_obj.search(
[
("state", "=", "opened"),
("config_id.display_product_quantity", "=", True),
"|",
("config_id.additional_warehouse_ids", "in", [warehouse.id]),
("config_id.main_warehouse_id", "=", warehouse.id),
"|",
("config_id.iface_available_categ_ids", "=", False),
(
"config_id.iface_available_categ_ids",
"in",
[record.product_id.pos_categ_id.id],
),
],
).mapped("config_id")
if configs:
configs._notify_available_quantity(
warehouse._prepare_vals_for_pos(record.product_id)
)

View file

@ -0,0 +1,23 @@
from odoo import models
class StockQuant(models.Model):
_name = "stock.quant"
_inherit = ["stock.quant", "stock.notifier.pos.mixin"]
def write(self, vals):
res = super().write(vals)
self._notify_pos()
return res
def _skip_notify_pos(self):
self.ensure_one()
return (
self.env.context.get("skip_quant_notify_pos", False)
or super()._skip_notify_pos()
)
def _get_warehouses_to_notify(self):
warehouses = super()._get_warehouses_to_notify()
warehouses |= self.warehouse_id
return warehouses

View file

@ -0,0 +1,18 @@
from odoo import models
class StockWarehouse(models.Model):
_inherit = "stock.warehouse"
def _prepare_vals_for_pos(self, product):
"""
Prepare warehouse info data to send a POS
"""
self.ensure_one()
return {
"id": self.id,
"name": self.name,
"code": self.code,
"quantity": product.with_context(warehouse=self.id).immediately_usable_qty,
"product_id": product.id,
}

View file

@ -0,0 +1,14 @@
In "Point of Sale" configuration "Product Quantity" section activate "Display Product Quantity" feature:
.. image:: ../static/img/pos_config.png
By default quantity is displayed for the warehouse that is used in the POS stock operation type.
You can add additional warehouses to show quantity in by adding them into "Additional Warehouses" field.
In this case the following information will be displayed on product tiles:
- Total quantity = quantity in the default warehouse + quantity in the additional warehouses
- Quantity in the default warehouse
- Quantity in the additional warehouses.

View file

@ -0,0 +1,2 @@
* Cetmix <https://cetmix.com/>
* Dinar Gabbasov

View file

@ -0,0 +1,6 @@
This module allows to display product quantities in selected locations in real time. Quantities are displayed directly on product tiles:
.. image:: ../static/img/pos_quantity.png
Once a product quantity is changed it will be simultaneously updated in all active POS.
This module depends on stock_available module which is available in https://github.com/OCA/stock-logistics-availability repo.

View file

@ -0,0 +1,3 @@
This module requires connection to update quantities and doesn't support offline mode.
Warehouses must belong to the same company as POS.
Offline mode support (probably additional module).

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View file

@ -0,0 +1,454 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Point of Sale Stock Available Online</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="point-of-sale-stock-available-online">
<h1 class="title">Point of Sale Stock Available Online</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:d544301c362e728a3cab17fa70bc08796bb02c4435dd0edf4ed2df4a4376d1c1
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/pos/tree/16.0/pos_stock_available_online"><img alt="OCA/pos" src="https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/pos-16-0/pos-16-0-pos_stock_available_online"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/pos&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<dl class="docutils">
<dt>This module allows to display product quantities in selected locations in real time. Quantities are displayed directly on product tiles:</dt>
<dd><img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_stock_available_online/static/img/pos_quantity.png" class="first last" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_stock_available_online/static/img/pos_quantity.png" />
</dd>
</dl>
<p>Once a product quantity is changed it will be simultaneously updated in all active POS.</p>
<p>This module depends on stock_available module which is available in <a class="reference external" href="https://github.com/OCA/stock-logistics-availability">https://github.com/OCA/stock-logistics-availability</a> repo.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-2">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<dl class="docutils">
<dt>In “Point of Sale” configuration “Product Quantity” section activate “Display Product Quantity” feature:</dt>
<dd><img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_stock_available_online/static/img/pos_config.png" class="first last" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_stock_available_online/static/img/pos_config.png" />
</dd>
</dl>
<p>By default quantity is displayed for the warehouse that is used in the POS stock operation type.</p>
<p>You can add additional warehouses to show quantity in by adding them into “Additional Warehouses” field.</p>
<p>In this case the following information will be displayed on product tiles:</p>
<ul class="simple">
<li>Total quantity = quantity in the default warehouse + quantity in the additional warehouses</li>
<li>Quantity in the default warehouse</li>
<li>Quantity in the additional warehouses.</li>
</ul>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h1>
<p>This module requires connection to update quantities and doesnt support offline mode.
Warehouses must belong to the same company as POS.
Offline mode support (probably additional module).</p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/pos/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/pos/issues/new?body=module:%20pos_stock_available_online%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-4">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-5">Authors</a></h2>
<ul class="simple">
<li>Cetmix</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
<ul class="simple">
<li>Cetmix &lt;<a class="reference external" href="https://cetmix.com/">https://cetmix.com/</a>&gt;</li>
<li>Dinar Gabbasov</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>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.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/pos/tree/16.0/pos_stock_available_online">OCA/pos</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View file

@ -0,0 +1,32 @@
.pos .product-list .warehouse-info {
padding: 0.5rem;
font-weight: bold;
display: flex;
border-top: 1px solid #efefef;
justify-content: space-between;
}
.pos .product-list .warehouse-info .warehouse {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.pos .product-list .warehouse-info .warehouse .quantity {
color: black;
padding: 1px 2px;
font-size: 11px;
}
.pos .product-list .warehouse-info .warehouse .warehouse-name {
display: block;
color: #696969;
font-size: 10px;
}
.pos .product-list .warehouse-info .warehouse.total .warehouse-name {
font-weight: bold;
}
.pos .product-list .warehouse-info .warehouse .quantity.available {
color: #32a868;
}
.pos .product-list .warehouse-info .warehouse .quantity.not-available {
color: #ef5350;
}

View file

@ -0,0 +1,39 @@
/** @odoo-module **/
import ProductItem from "point_of_sale.ProductItem";
import Registries from "point_of_sale.Registries";
import {format} from "web.field_utils";
import utils from "web.utils";
const StockProductItem = (OriginalProductItem) =>
class extends OriginalProductItem {
format_quantity(quantity) {
const unit = this.env.pos.units_by_id[this.props.product.uom_id[0]];
var formattedQuantity = `${quantity}`;
if (unit) {
if (unit.rounding) {
var decimals = this.env.pos.dp["Product Unit of Measure"];
formattedQuantity = format.float(quantity, {
digits: [69, decimals],
});
} else {
formattedQuantity = utils.round_precision(quantity, 1).toFixed(0);
}
}
return `${formattedQuantity}`;
}
get display_total_quantity() {
return this.format_quantity(this.total_quantity);
}
get total_quantity() {
return this.warehouses.reduce(
(partialSum, warehouse) => partialSum + warehouse.quantity,
0
);
}
get warehouses() {
return this.props.product.warehouse_info;
}
};
Registries.Component.extend(ProductItem, StockProductItem);

View file

@ -0,0 +1,63 @@
/** @odoo-module **/
import ProductsWidget from "point_of_sale.ProductsWidget";
import Registries from "point_of_sale.Registries";
const StockProductsWidget = (OriginalProductsWidget) =>
class extends OriginalProductsWidget {
setup() {
super.setup();
this.env.services.bus_service.addChannel(this._getChannelName());
this.env.services.bus_service.addEventListener(
"notification",
this._onNotification.bind(this)
);
}
_getChannelName() {
return JSON.stringify([
"pos_stock_available_online",
String(this.env.pos.config.id),
]);
}
_onNotification({detail: notifications}) {
var payloads = [];
for (const {payload, type} of notifications) {
if (type === "pos.config/product_update") {
payloads.push(payload);
}
}
this._handleNotification(payloads);
}
async _handleNotification(payloads) {
if (this.env.isDebug()) {
console.log("Payloads:", payloads);
}
const db = this.env.pos.db;
const ProductIds = [];
for (const payload of payloads) {
for (const message of payload) {
var product = db.get_product_by_id(message.product_id);
if (product) {
// Update warehouse info of the product
var warehouse = product.warehouse_info.find(
(wh) => wh.id === message.id
);
if (warehouse) {
warehouse.quantity = message.quantity;
} else {
product.warehouse_info.push(message);
}
} else {
ProductIds.push(message.id);
}
}
}
if (ProductIds.length) {
await this.env.pos._addProducts([...new Set(ProductIds)], false);
}
// Re-render product list without category switching
this.render(true);
}
};
Registries.Component.extend(ProductsWidget, StockProductsWidget);

View file

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
<t
t-name="ProductItem"
t-inherit="point_of_sale.ProductItem"
t-inherit-mode="extension"
owl="1"
>
<xpath expr="//div[hasclass('product-content')]" position="inside">
<div t-if="env.pos.config.display_product_quantity" class="warehouse-info">
<div class="flex">
<div
t-if="warehouses.length > 1"
class="warehouse total"
title="Total"
>
<i class="fa fa-dropbox" />
<span
t-attf-class="quantity {{total_quantity > env.pos.config.minimum_product_quantity_alert ? 'available' : 'not-available'}}"
>
<t t-esc="display_total_quantity" />
</span>
</div>
</div>
<div class="flex">
<t t-foreach="warehouses" t-as="warehouse" t-key="warehouse.id">
<div class="warehouse" t-att-title="warehouse.name">
<span class="warehouse-name">
<t t-esc="warehouse.code" />
</span>
<span
t-attf-class="quantity {{warehouse.quantity > env.pos.config.minimum_product_quantity_alert ? 'available' : 'not-available'}}"
>
<t t-esc="format_quantity(warehouse.quantity)" />
</span>
</div>
</t>
</div>
</div>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="point_of_sale.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[@id='pos_inventory_section']" position="after">
<h2>Product Quantity</h2>
<div class="row mt16 o_settings_container" id="pos_product_quantity">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="pos_display_product_quantity" />
</div>
<div class="o_setting_right_pane">
<label
for="pos_display_product_quantity"
string="Display Product Quantity"
/>
<div class="text-muted">
Display the quantity of available products in the POS for <bold
><field
name="pos_main_warehouse_id"
class="oe_inline"
nolabel="1"
/> warehouse</bold>.
</div>
</div>
</div>
<div
class="col-12 col-lg-6 o_setting_box"
attrs="{'invisible': [('pos_display_product_quantity', '=', False)]}"
>
<div class="o_setting_right_pane">
<label
for="pos_additional_warehouse_ids"
string="Additional Warehouses"
/>
<div class="text-muted">
Show quantity in the following warehouses in additional to <bold
><field
name="pos_main_warehouse_id"
class="oe_inline"
nolabel="1"
/> warehouse</bold>.
</div>
<div class="alert alert-warning" role="alert">
Warehouses must belong to the same company as POS.
</div>
<div class="content-group mt16">
<field
name="pos_additional_warehouse_ids"
domain="[('id', '!=', pos_main_warehouse_id)]"
widget="many2many_tags"
/>
</div>
</div>
</div>
<div
class="col-12 col-lg-6 o_setting_box"
attrs="{'invisible': [('pos_display_product_quantity', '=', False)]}"
>
<div class="o_setting_right_pane">
<label
for="pos_minimum_product_quantity_alert"
string="Minimum Product Quantity Alert"
/>
<div class="text-muted">
Mark quantity red if below or equal this value.
</div>
<div class="content-group mt16">
<field name="pos_minimum_product_quantity_alert" />
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

View file

@ -0,0 +1,44 @@
[project]
name = "odoo-bringout-oca-pos-pos_stock_available_online"
version = "16.0.0"
description = "Point of Sale Stock Available Online - Show the available quantity of products in the Point of Sale "
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-ocb-point_of_sale>=16.0.0",
"odoo-bringout-oca-pos-stock_available>=16.0.0",
"odoo-bringout-oca-pos-base_automation>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["pos_stock_available_online"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]